I have a simple marionette ItemView,
import Marionette from 'backbone.marionette';
import Tabs from '@component/tabs/src/js/views/Tabs';
import template from '../../../templates/partials/one/tabs.hbs'
export default Marionette.ItemView.extend({
template,
onRender() {
console.log(document.querySelector('#tabs-main')); //--> null
console.log(this.$('#tabs-main')[0]); // gets appropriate dom element
}
})
Is there a reason why document.querySelector returns null compared to doing this.$, i need to do document.querySelector because the library that I am using uses it internally when i pass in the id/class
Refer to https://marionettejs.com/docs/v3.5.1/viewlifecycle.html#view-creation-lifecycle
In onRender, the template will be rendered in memory (i.e. this.$el), but not yet attached to the DOM.
You can use onAttached if the view's HTML needs to be in the DOM.
Note that DOM lookups are slower than lookups done against the view's el, so unless a lookup needs to occur against the DOM, is generally better to use onRender with this.$() lookups.
Edit: since you're using ItemView, must be using < v3, here is v2 doc for onAttach: https://marionettejs.com/docs/v2.4.7/marionette.view.html#view-attach--onattach-event
2nd edit: adding snippet (sorry, took a while to find older marionette dependencies)
var MyView = Backbone.Marionette.ItemView.extend({
template: Handlebars.compile('<p id="hello-world">Hello World</p>'),
onRender: function() {
console.log('onRender');
console.log('querySelector', document.querySelector('#hello-world'));
console.log('querySelector equal null?', document.querySelector('#hello-world') === null);
console.log('this.$el', this.$('#hello-world')[0]);
},
onAttach: function() {
console.log('onAttach');
console.log('querySelector', document.querySelector('#hello-world'));
console.log('querySelector equal null?', document.querySelector('#hello-world') === null);
console.log('this.$el', this.$('#hello-world')[0]);
}
});
// ParentView to mock an application
var ParentView = Backbone.Marionette.LayoutView.extend({
el: '.test-container',
template: Handlebars.compile('<div class="my-region"></div>'),
regions: {
myRegion: '.my-region'
},
onRender: function() {
var myView = new MyView();
this.showChildView('myRegion', myView);
}
});
var parentView = new ParentView();
parentView.render();
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/backbone.js/1.3.3/backbone.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/handlebars.js/4.3.1/handlebars.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/backbone.marionette/2.4.7/backbone.marionette.js"></script>
<div class="test-container"></div>