Marionette document.querySelector('#test') returns null 但这样做。$('#test') 不会
Marionette document.querySelector('#test') returns null but doing this.$('#test') does not
我有一个简单的 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
}
})
与这样做相比,document.querySelector returns null 有什么原因吗?$,我需要做 document.querySelector 因为我正在使用的库在我通过时在内部使用它在 id/class
参考https://marionettejs.com/docs/v3.5.1/viewlifecycle.html#view-creation-lifecycle
在 onRender 中,模板将在内存中呈现(即 this.$el),但尚未附加到 DOM。
如果视图的 HTML 需要在 DOM 中,您可以使用 onAttached。
请注意,DOM 查找比针对视图的 el 进行的查找慢,因此除非需要针对 DOM 进行查找,否则通常最好将 onRender 与 this.$() 一起使用查找。
编辑:由于您使用的是 ItemView,因此必须使用 < v3,这是 onAttach 的 v2 文档:
https://marionettejs.com/docs/v2.4.7/marionette.view.html#view-attach--onattach-event
第二次编辑:添加片段(抱歉,花了一些时间才找到较旧的 marionette 依赖项)
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>
我有一个简单的 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
}
})
与这样做相比,document.querySelector returns null 有什么原因吗?$,我需要做 document.querySelector 因为我正在使用的库在我通过时在内部使用它在 id/class
参考https://marionettejs.com/docs/v3.5.1/viewlifecycle.html#view-creation-lifecycle
在 onRender 中,模板将在内存中呈现(即 this.$el),但尚未附加到 DOM。
如果视图的 HTML 需要在 DOM 中,您可以使用 onAttached。
请注意,DOM 查找比针对视图的 el 进行的查找慢,因此除非需要针对 DOM 进行查找,否则通常最好将 onRender 与 this.$() 一起使用查找。
编辑:由于您使用的是 ItemView,因此必须使用 < v3,这是 onAttach 的 v2 文档: https://marionettejs.com/docs/v2.4.7/marionette.view.html#view-attach--onattach-event
第二次编辑:添加片段(抱歉,花了一些时间才找到较旧的 marionette 依赖项)
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>