考虑以下示例
// a sample constructor
var SampleConstructor = function(element,options);
// a full live collection
var domCollection = document.getElementsByTagName('*');
// bulk init
for (var i = 0; i < domCollection.length; i++) {
if ('some conditions required by component') {
new SampleConstructor( domCollection[i], {});
}
}
问题
- DOM中新添加的元素会被示例构造函数初始化吗
- 如果没有,有没有一种方法可以在没有jQuery的情况下完成,也没有在间隔的基础上循环遍历集合
注意
所需的解决方案是针对IE8+
这里有一个代码示例来说明我的注释。然而,正如你所看到的,它并没有跟踪DOM的变化,事实上,我更喜欢Angular等现代JavaScript框架广泛使用的相反方式:观察原始数据结构并相应地更新DOM。
// Observable
Observable = function () {
this.observers = [];
};
Observable.prototype.addObserver = function (observer) {
this.observers.push(observer);
};
Observable.prototype.emit = function (evt, args) {
var i, n = this.observers.length;
for (i = 0; i < n; i++) {
this.observers[i].update(this, evt, args);
}
};
// Collection
Collection = function () {
this.items = [];
Observable.call(this);
};
Collection.prototype = new Observable();
Collection.prototype.size = function () {
return this.items.length;
};
Collection.prototype.add = function (item) {
this.items.push(item);
this.emit("added", [item]);
};
Collection.prototype.removeAt = function (i) {
var items = this.items.splice(i, 1);
this.emit("removed", [items[0], i]);
};
// program
var i, s = "h*e*l*l*o";
var collection = new Collection();
var words = document.getElementsByTagName("div");
var wordA = words[0], wordB = words[1];
collection.addObserver({
update: function (src, evt, args) {
this[evt](args);
},
added: function (args) {
wordA.appendChild(
this.createSpan(args[0])
);
wordB.appendChild(
this.createSpan(args[0])
);
},
removed: function (args) {
wordB.removeChild(
wordB.childNodes[args[1]]
);
},
createSpan: function (c) {
var child;
child = document.createElement("span");
child.textContent = c;
return child;
}
});
for (i = 0; i < s.length; i++) {
collection.add(s[i]);
}
for (i = 1; i < 5; i++) {
collection.removeAt(i);
}
function rdm (max) {
return Math.floor(
Math.random() * max
);
}
function addRdmLetter () {
collection.add(
(rdm(26) + 10).toString(36)
);
}
function removeRdmLetter () {
var n = collection.size();
if (n > 0) collection.removeAt(rdm(n));
}
function showLetters () {
alert(collection.items.join(""));
}
body {
font-size: 16px;
font-family: Courier;
}
span {
padding: 5px;
display: inline-block;
margin: -1px 0 0 -1px;
border: 1px solid #999;
}
#buttons {
position: absolute;
top: 10px;
right: 10px;
}
<p>wordA</p><div></div>
<p>wordB</p><div></div>
<div id="buttons">
<button type="button" onclick="addRdmLetter()">Add letter</button>
<button type="button" onclick="removeRdmLetter()">Remove letter</button>
<button type="button" onclick="showLetters()">Show letters</button>
</div>
function compare(arr,newarr,callback){
var index=0;
var newindex=0;
while(newarr.length!=newindex){
if ( arr[index] == newarr[newindex]) {
index++; newindex++;
} else {
callback (newarr[newindex]);
newindex++;
}
}
}
//onload
var store=[];
compare([],store=document.getElementsByClassName("*"),yourconstructor);
//regular
var temp=document.getElementsByClassName("*");
compare(store,temp,yourconstructor);
store=temp;
我认为检查是最有效的。我知道的唯一解决方案是定期使用setTimeout。另一种方法是检测所有js-dom的更改,比如:
var add = Element.prototype.appendChild;
Element.prototype.appendChild=function(el){
yourconstructor(el);
add.call(this,el);
};
注意:非常黑客