The DOM is not yet available in the #activate callback. You would need to access the DOM element in the #attached or #compositionComplete callback. You can read here about the signatures of those callbacks, along with their intended purposes.
//viewmodel
define (["jquery", "knockout", "videojs"], function ($, ko, videojs) {
var attached = function (view) { //route param
var $view = $(view);
var $videoTag = $view.find('#video'); //undefined
var playerInstance = new videojs.Player($videoTag); //error
playerInstance.src(videoSource); //loads video from route parameter
playerInstance.play(); //starts to play
};
return {
attached: attached
}
});
ANOTHER APPROACH
You could also write a custom Knockout binding and encapsulate the logic of accessing the DOM element there.
I would actually suggest this approach as I'm suspicious of the point where you pass in a DOM reference to videojs.Player()
. This screams for encapsulation in a custom binding.
[EDIT]
EXAMPLE OF USAGE OF CUSTOM BINDING
Consider this usage in the view:
<div id='video' data-bind=player: {instance: playerInstance, source: videoSource}></div>
With this, you can then move all of the logic in the #attached function above into the custom binding. If you need to dynamically control the playerInstance, you can create an object literal with observable properties in your viewmodel, something like this:
var playerOptions = {
action: ko.observable('play'),
player: new videojs.Player(),
source: ko.observable(videoSource)
};
and change the binding to this:
<div id='video' data-bind=player: {options: playerOptions}></div>
Your custom binding would look something like this:
ko.bindingHandlers.player = {
update: function (element, valueAccessor, allBindingsAccessor, viewModel) {
var options = ko.unwrap(valueAccessor),
$element = $(element);
var playerInstance = options.player;
playerInstance.source = options.source();
playerInstance.do(options.action());
}
};
I'm not sure how your Player is connected to the DOM. I can see only that you're passing in a DOM element. But inside this binding, you have access to the element itself.