Javascript 使用Ractive.extend()时如何引用DOM元素?
所以,如果我使用Ractive.extend()来实例化自定义类的对象,那么如何引用该类中的DOM元素呢?显然,我不能像往常一样使用document.getElementById(),因为DOM尚未呈现,将Ractive.findComponent()传递给构造函数会返回“Ractive.findComponent不是函数”。我要做的是这样:Javascript 使用Ractive.extend()时如何引用DOM元素?,javascript,dom,ractivejs,Javascript,Dom,Ractivejs,所以,如果我使用Ractive.extend()来实例化自定义类的对象,那么如何引用该类中的DOM元素呢?显然,我不能像往常一样使用document.getElementById(),因为DOM尚未呈现,将Ractive.findComponent()传递给构造函数会返回“Ractive.findComponent不是函数”。我要做的是这样: class myClass { constructor(id /*,...*/) { this.element = documen
class myClass {
constructor(id /*,...*/) {
this.element = document.getElementById(id); //how do I do this??
};
};
var Extended = Ractive.extend( {
oninit() {
var myObject = new myClass(id /*,...*/);
this.set({myObject});
}
});
var ractiveExtended = new Extended({
el: document.body,
template: '#template',
data: { id: myId}
});
埃塔:这也不行
class myClass {
constructor(id /*,...*/) {
this.element = document.getElementById(id);
};
};
var Extended = Ractive.extend( {
onrender() {
var myObject = new myClass(id /*,...*/);
this.set({myObject});
}
});
var ractiveExtended = new Extended({
el: document.body,
template: '#template',
data: { id: myId}
});
这也不是
class myClass {
constructor(id /*,...*/) {
this.element = id;
this.element.innerHTML = 'Hello world!';
};
};
var Extended = Ractive.extend( {
onrender() {
var myObject = new myClass(document.getElementById(id) /*,...*/);
this.set({myObject});
}
});
var ractiveExtended = new Extended({
el: document.body,
template: '#template',
data: { id: myId}
});
更新了评论中澄清的问题的答案 这里有一个小问题:
{{{#每个精灵}
{{/每个}}
意味着Ractive将为精灵中的每个项目创建
,并为其分配适当的ID。但是,精灵在初始渲染时未定义,因此不会创建
元素
然后,在onrender()
中创建类的实例,这些实例假定
元素已经存在。只有在这之后,您才能将实例添加到精灵中,告诉Ractive渲染元素:
this.set({sprites});
有几种可能的解决办法。(我认为)最好是在类中添加render()
方法,并将任何与DOM相关的内容移出构造函数。然后,您的代码将更改为以下内容:
class myClass {
constructor(id /*,...*/) {
this.element = document.getElementById(id); //how do I do this??
};
};
var Extended = Ractive.extend( {
oninit() {
var myObject = new myClass(id /*,...*/);
this.set({myObject});
}
});
var ractiveExtended = new Extended({
el: document.body,
template: '#template',
data: { id: myId}
});
onrender(){
var sprites=this.get('repeaters').map(函数(repeater){
返回新画布(repeater.id);
});
this.set({sprites});
sprite.forEach(函数(sprite){
sprite.render();
});
}
但是,如果您不想修改您的类,您可以简单地为{{each}
循环使用现有的中继器
数组。此处演示:
关键是,在使用document.getElementsById()
或类似方法之前,您需要一种方法告诉Ractive呈现
元素
原始答案
如果需要访问DOM,请将初始化代码从oninit
移动到onrender
。然后可以使用document.getElementById()
或ractive.find()
()来获取所需的元素
class myClass {
constructor(id) {
this.element = document.getElementById(id);
this.element.innerHTML = 'Hello world!';
};
};
var Extended = Ractive.extend( {
onrender() {
// use this.get('id') to get ID from Ractive's data
var myObject = new myClass(this.get('id'));
this.set({myObject});
}
});
var ractiveExtended = new Extended({
el: document.body,
template: '#template',
data: { id: 'content' },
});
演示:更新了评论中澄清的问题的答案
这里有一个小问题:
{{{#每个精灵}
{{/每个}}
意味着Ractive将为精灵中的每个项目创建
,并为其分配适当的ID。但是,精灵在初始渲染时未定义,因此不会创建
元素
然后,在onrender()
中创建类的实例,这些实例假定
元素已经存在。只有在这之后,您才能将实例添加到精灵中,告诉Ractive渲染元素:
this.set({sprites});
有几种可能的解决办法。(我认为)最好是在类中添加render()
方法,并将任何与DOM相关的内容移出构造函数。然后,您的代码将更改为以下内容:
class myClass {
constructor(id /*,...*/) {
this.element = document.getElementById(id); //how do I do this??
};
};
var Extended = Ractive.extend( {
oninit() {
var myObject = new myClass(id /*,...*/);
this.set({myObject});
}
});
var ractiveExtended = new Extended({
el: document.body,
template: '#template',
data: { id: myId}
});
onrender(){
var sprites=this.get('repeaters').map(函数(repeater){
返回新画布(repeater.id);
});
this.set({sprites});
sprite.forEach(函数(sprite){
sprite.render();
});
}
但是,如果您不想修改您的类,您可以简单地为{{each}
循环使用现有的中继器
数组。此处演示:
关键是,在使用document.getElementsById()
或类似方法之前,您需要一种方法告诉Ractive呈现
元素
原始答案
如果需要访问DOM,请将初始化代码从oninit
移动到onrender
。然后可以使用document.getElementById()
或ractive.find()
()来获取所需的元素
class myClass {
constructor(id) {
this.element = document.getElementById(id);
this.element.innerHTML = 'Hello world!';
};
};
var Extended = Ractive.extend( {
onrender() {
// use this.get('id') to get ID from Ractive's data
var myObject = new myClass(this.get('id'));
this.set({myObject});
}
});
var ractiveExtended = new Extended({
el: document.body,
template: '#template',
data: { id: 'content' },
});
演示:编辑:完整的跑步示例可从以下网址获得:
我会将每个CanvasSprite
封装在它自己的组件中:
const CanvasSpriteComponent = Ractive.extend({
template: '#sprite',
// Using onrender, not oninit, because we need DOM canvas node
onrender(){
const canvas = this.find('canvas');
const repeater = this.get('repeater');
var sprite = new CanvasSprite(canvas, repeater.width, repeater.height, repeater.spriteSheetURL, repeater.rows, repeater.columns, repeater.totalFrames);
sprite.left = repeater.left; //add variables *not* in the constructor
sprite.setFrame(0);
this.on('setFrame', function (event) {
var offsetY = event.original.clientY - event.node.getBoundingClientRect().top;
var relY = offsetY/sprite.height;
sprite.setFrame(relY);
});
}
});
然后在主实例中使用它:
var CanvasAnimation = Ractive.extend( {
template: '#animation',
components: {
'canvas-sprite': CanvasSpriteComponent
}
});
var canvasAnimation = new CanvasAnimation({
el: 'main',
data: { repeaters: repeater }
});
可以说,您的CanvasSprite
类采用画布节点更有意义,因为这样它就不再与该节点的位置(当前为document.getElementById
)相关联
如果您根本不愿意更改该类,那么只需要创建一个唯一的id(或者如果repeater集合不会发生变化,则使用索引)。在这种情况下,我将重用组件的唯一id:
const CanvasSpriteComponent = Ractive.extend({
// ...
onrender(){
const canvas = this.find('canvas');
canvas.id = `canvas-${this._guid}`
const repeater = this.get('repeater');
var sprite = new CanvasSprite(canvas.id, repeater.width, repeater.height, repeater.spriteSheetURL, repeater.rows, repeater.columns, repeater.totalFrames);
sprite.left = repeater.left; //add variables *not* in the constructor
sprint.setFrame(0);
this.on('setFrame', function (event) {
var offsetY = event.original.clientY - event.node.getBoundingClientRect().top;
var relY = offsetY/sprite.height;
sprite.setFrame(relY);
});
}
});
编辑:完整的跑步示例可从以下网址获得:
我会将每个CanvasSprite
封装在它自己的组件中:
const CanvasSpriteComponent = Ractive.extend({
template: '#sprite',
// Using onrender, not oninit, because we need DOM canvas node
onrender(){
const canvas = this.find('canvas');
const repeater = this.get('repeater');
var sprite = new CanvasSprite(canvas, repeater.width, repeater.height, repeater.spriteSheetURL, repeater.rows, repeater.columns, repeater.totalFrames);
sprite.left = repeater.left; //add variables *not* in the constructor
sprite.setFrame(0);
this.on('setFrame', function (event) {
var offsetY = event.original.clientY - event.node.getBoundingClientRect().top;
var relY = offsetY/sprite.height;
sprite.setFrame(relY);
});
}
});
然后在主实例中使用它:
var CanvasAnimation = Ractive.extend( {
template: '#animation',
components: {
'canvas-sprite': CanvasSpriteComponent
}
});
var canvasAnimation = new CanvasAnimation({
el: 'main',
data: { repeaters: repeater }
});
可以说,您的CanvasSprite
类采用画布节点更有意义,因为这样它就不再与该节点的位置(当前为document.getElementById
)相关联
如果您根本不愿意更改该类,那么只需要创建一个唯一的id(或者如果repeater集合不会发生变化,则使用索引)。在这种情况下,我将重用组件的唯一id:
const CanvasSpriteComponent = Ractive.extend({
// ...
onrender(){
const canvas = this.find('canvas');
canvas.id = `canvas-${this._guid}`
const repeater = this.get('repeater');
var sprite = new CanvasSprite(canvas.id, repeater.width, repeater.height, repeater.spriteSheetURL, repeater.rows, repeater.columns, repeater.totalFrames);
sprite.left = repeater.left; //add variables *not* in the constructor
sprint.setFrame(0);
this.on('setFrame', function (event) {
var offsetY = event.original.clientY - event.node.getBoundingClientRect().top;
var relY = offsetY/sprite.height;
sprite.setFrame(relY);
});
}
});
那不行。如果我在类中调用document.getElementById(this.id),它将返回null。与document.querySelector(this.id)相同。我已经解释了从Ractive.findComponent()得到的错误。无论渲染后是否实例化对象,这两种情况都会发生。请检查this.id
的值是否与元素的id匹配-它肯定会工作。至于find()
-它是一个实例方法,因此请确保在您的ractive实例(ractiveExtended
)上调用它,而不是全局ractive变量。是的,请确保:this.id与id匹配。不过,感谢您解释find()。但如果我必须打电话,我