2017-01-14 11 views
0

는 다음과 같은 예를JavaScript : 라이브 콜렉션의 요소를 자동으로 초기화하는 방법이 있습니까?

// 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 +

+0

은 쉽게 https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver –

+1

에서 봐 가지고있다 변경 내용을 추적합니다. – leaf

답변

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을 사용하여 정기적으로 수행하는 것입니다.

var add = Element.prototype.appendChild; 
Element.prototype.appendChild=function(el){ 
yourconstructor(el); 
add.call(this,el); 
}; 

참고 : 다음

+0

'propertyChange' 이벤트는 어떻습니까? https://msdn.microsoft.com/en-us/library/ms536956(v=vs.85).aspx – thednp

+0

_Note 자식 요소의 innerText 또는 innerHTML을 변경해도 onpropertychange 이벤트가 발생하지 않습니다. 부모 element._ –

+0

appendChild,'document.all.length'를 변경할 때'propertyChange' 이벤트가 발생한다고 생각합니다. 새로운 ITEMS가 DOM에 추가 될 때를 확인하는 방법을 찾았습니다. – thednp

1

comment을 설명하는 코드 샘플 매우 해키 또 다른 방법은 모든 DOM 변경, 같은 것을 JS 감지하는 것입니다. 그러나 DOM 변경 사항을 추적 할 수는 없지만 Angular와 같은 최신 JavaScript 프레임 워크에서 널리 사용되는 반대 방법을 선호합니다. 즉, 원시 데이터 구조를 관찰하고 이에 따라 DOM을 업데이트합니다. 당신이 직접 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>

+0

이 접근법은 매우 흥미 롭습니다. AngularJS의 사용자, DOM을 즉석에서 조작하는 JS가 내 'bootstrap.native' 라이브러리를 사용하여 모두 행복하게 만드는 방법에 관심이 있습니다. 아마도이 업데이트를 신속하고 신속하게 수행 할 수 있습니다. – thednp

+0

이 시점에서 나는'onpropertychange'를 수행 할 작은 유틸리티 함수를보고있다. 'DOMAttrModified' | 'DOMNodeInserted', 작업을 수행하는 4-5 줄의 코드. AngularJS에 대해 전혀 알지 못하기 때문에 당신이 가질 수있는 제안은 아직 열려 있습니다. – thednp

+0

@thednp 여러 가지 방법으로 재현 할 수있는 유명한 데이터 바인딩 패턴 (데이터가 변경됨 -> DOM 업데이트)을 제외하고는 Angular와 공통점이 없습니다. DOM 조작을 완벽하게 제어 할 수 있다면 상황이 좋지 않을 수도 있습니다. 그래도 내 기부는 여기에서 끝납니다. – leaf