JavaScript:有没有办法自动初始化动态集合中的元素?

时间:2017-01-14 10:42:24

标签: javascript initialization live htmlcollection

请考虑以下示例

// 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], {});
  }
}

问题

  • 新添加的元素是否会被样本构造函数初始化?
  • 如果没有,有没有办法在没有jQuery的情况下进行,并且没有间隔循环遍历集合?

注意

所需的解决方案适用于IE8 +

2 个答案:

答案 0 :(得分:1)

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);
};

注意:非常hacky

答案 1 :(得分:1)

以下是一个代码示例来说明我的comment。但是,正如您所看到的那样,它并没有跟踪DOM的变化,实际上,我更喜欢现代JavaScript框架(如Angular)广泛使用的相反方式:观察原始数据结构并相应地更新DOM。

&#13;
&#13;
// 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(""));
}
&#13;
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;
}
&#13;
<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>
&#13;
&#13;
&#13;