[javascript] JavaScript / jQuery DOM 변경 리스너가 있습니까?

본질적으로 DIV변경 내용이있을 때 스크립트를 실행하고 싶습니다 . 스크립트는 분리되어 있기 때문에 (Chrome 확장 프로그램 및 웹 페이지 스크립트의 콘텐츠 스크립트) DOM 상태의 변화를 간단히 관찰 할 수있는 방법이 필요합니다. 폴링을 설정할 수는 있지만 부주의 한 것 같습니다.



답변

오랫동안 DOM3 돌연변이 이벤트가 가장 유용한 솔루션이지만 성능상의 이유로 더 이상 사용되지 않습니다. DOM4 Mutation Observers 는 더 이상 사용되지 않는 DOM3 돌연변이 이벤트를 대체합니다. 그들은되어 현재 최신 브라우저에 구현 으로 MutationObserver(또는 벤더 접두사 WebKitMutationObserver크롬의 이전 버전에서) :

MutationObserver = window.MutationObserver || window.WebKitMutationObserver;

var observer = new MutationObserver(function(mutations, observer) {
    // fired when a mutation occurs
    console.log(mutations, observer);
    // ...
});

// define what element should be observed by the observer
// and what types of mutations trigger the callback
observer.observe(document, {
  subtree: true,
  attributes: true
  //...
});

이 예제는 DOM 변경 사항 document과 전체 서브 트리 에 대해 청취 하고 구조적 변경 사항뿐만 아니라 요소 속성에 대한 변경 사항을 시작합니다. 초안 사양에는 유효한 돌연변이 리스너 속성 의 전체 목록이 있습니다 .

childList

  • true대상의 자식에 대한 돌연변이가 관찰 되는 경우로 설정됩니다 .

속성

  • true대상 속성에 대한 돌연변이가 관찰 되는 경우로 설정됩니다 .

characterData

  • true대상 데이터에 대한 돌연변이가 관찰 되는 경우로 설정됩니다 .

하위 트리

  • 세트에 true에 돌연변이가 단지 대상으로하지 않을 경우뿐만 아니라 대상의 후손을 준수해야한다.

attributeOldValue

  • 로 설정 true하면 attributes변이 필요가 기록 될 전에의 진정한 및 대상 속성 값으로 설정됩니다.

characterDataOldValue

  • 로 설정 true하면 characterData변이 필요가 기록 될 전에 진실하고 대상의 데이터로 설정됩니다.

attributeFilter

  • 모든 속성 돌연변이를 관찰 할 필요가없는 경우 속성 네임 스페이스없이 속성 로컬 이름 목록으로 설정하십시오.

(이 목록은 2014 년 4 월 현재이며, 사양이 변경되었는지 확인할 수 있습니다.)


답변

편집하다

이 답변은 더 이상 사용되지 않습니다. apsillers 의 답변을 참조하십시오 .

이것은 Chrome 확장 프로그램을위한 것이므로 표준 DOM 이벤트-를 사용할 수도 있습니다 DOMSubtreeModified. 브라우저 에서이 이벤트에 대한 지원을 참조하십시오 . 1.0부터 Chrome에서 지원되었습니다.

$("#someDiv").bind("DOMSubtreeModified", function() {
    alert("tree changed");
});

실제 예제를 참조 하십시오 .


답변

많은 사이트에서 AJAX를 사용하여 컨텐츠를 동적으로 추가 / 표시 / 변경합니다. 경우에 따라 사이트 내 탐색 대신 사용되기 때문에 현재 URL이 프로그래밍 방식으로 변경되고이 경우 페이지가 원격 서버에서 완전히 페치되지 않으므로 브라우저에서 컨텐츠 스크립트가 자동으로 실행되지 않습니다.


콘텐츠 스크립트 에서 사용 가능한 페이지 변경을 감지하는 일반적인 JS 방법 .


확장 프로그램 별 : 백그라운드 / 이벤트 페이지 에서 URL 변경을 감지 합니다 .

이 탐색과 작업에 고급 API 있습니다 webNavigation , WebRequest 클래스는 하지만, 우리는 간단한 사용합니다 chrome.tabs.onUpdated의 이벤트 리스너 메시지를 전송 내용 스크립트를 :

  • manifest.json을 :
    선언 배경 / 이벤트 페이지
    선언 콘텐츠 스크립트
    추가 "tabs" 허가 .

  • background.js

    var rxLookfor = /^https?:\/\/(www\.)?google\.(com|\w\w(\.\w\w)?)\/.*?[?#&]q=/;
    chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab) {
        if (rxLookfor.test(changeInfo.url)) {
            chrome.tabs.sendMessage(tabId, 'url-update');
        }
    });
  • content.js

    chrome.runtime.onMessage.addListener(function(msg, sender, sendResponse) {
        if (msg === 'url-update') {
            doSomething();
        }
    });

답변

div를 변경하는 방법에 따른 또 다른 접근법. JQuery를 사용하여 html () 메소드로 div 컨텐츠를 변경하는 경우 html을 div에 넣을 때마다 해당 메소드를 확장하고 등록 함수를 호출 할 수 있습니다.

(function( $, oldHtmlMethod ){
    // Override the core html method in the jQuery object.
    $.fn.html = function(){
        // Execute the original HTML method using the
        // augmented arguments collection.

        var results = oldHtmlMethod.apply( this, arguments );
        com.invisibility.elements.findAndRegisterElements(this);
        return results;

    };
})( jQuery, jQuery.fn.html );

우리는 단지 html ()에 대한 호출을 가로 채고 이것으로 등록 함수를 호출합니다. 컨텍스트에서 새로운 내용을 얻는 대상 요소를 참조한 다음 호출을 원래 jquery.html () 함수에 전달합니다. JQuery는 메소드 체인에 대해 예상하므로 원래 html () 메소드의 결과를 리턴해야합니다.

메서드 재정의 및 확장에 대한 자세한 내용 은 http://www.bennadel.com/blog/2009-Using-Self-Executing-Function-Arguments-To-Override-Core-jQuery-Methods.htm을 확인 하십시오 . 폐쇄 기능을 움켜 쥐었다. JQuery 사이트에서 플러그인 튜토리얼을 확인하십시오.


답변

MutationObserverAPI 에서 제공하는 “원시”도구 외에도 DOM 변이를 다루는 “편의”라이브러리가 있습니다.

고려 : MutationObserver는 하위 트리 측면에서 각 DOM 변경을 나타냅니다. 예를 들어 특정 요소가 삽입되기를 기다리는 경우의 하위 요소 안에있을 수 있습니다 mutations.mutation[i].addedNodes[j].

또 다른 문제는 돌연변이에 반응하여 자신의 코드가 DOM을 변경하는 경우입니다. 종종이를 필터링하려고합니다.

그러한 문제를 해결하는 좋은 편의 라이브러리는 mutation-summary(면책 조항 : 저자가 아니며 만족 한 사용자입니다) 관심있는 쿼리를 지정하고 정확하게 얻을 수 있습니다.

문서의 기본 사용법 예 :

var observer = new MutationSummary({
  callback: updateWidgets,
  queries: [{
    element: '[data-widget]'
  }]
});

function updateWidgets(summaries) {
  var widgetSummary = summaries[0];
  widgetSummary.added.forEach(buildNewWidget);
  widgetSummary.removed.forEach(cleanupExistingWidget);
}


답변