본질적으로 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 방법 .
-
말 그대로 DOM 변경을 감지하는 MutationObserver ( docs ) :
-
DOM 이벤트를 전송하여 컨텐츠 변경을 알리는 사이트의 이벤트 리스너 :
pjax:end
document
GitHub와 같은 많은 pjax 기반 사이트 에서 사용되는 경우 pjax로드 전후에 jQuery를 실행하는 방법을
참조하십시오 .message
에window
크롬 브라우저에서 예를 들어, Google 검색에서 사용하는,
참조 크롬 확장 프로그램 Google 검색 새로 고침을 감지spfdone
document
Youtube 에서 사용하는 방법 은 Youtube에서 페이지 탐색을 감지하고 페이지를 렌더링하기 전에 HTML을 수정하는 방법을
참조하십시오 .
-
setInterval을 통해 DOM을 주기적으로 검사 :
이것은 분명히 id / selector로 식별되는 특정 요소가 나타날 때까지만 작동하며 어떤 종류의 지문을 만들지 않으면 동적으로 추가 된 새로운 내용을 보편적으로 감지 할 수 없습니다 기존 내용. -
주입 된 DOM 스크립트 내에서 클로킹 히스토리 API :
document.head.appendChild(document.createElement('script')).text = '(' + function() { // injected DOM script is not a content script anymore, // it can modify objects and functions of the page var _pushState = history.pushState; history.pushState = function(state, title, url) { _pushState.call(this, state, title, url); window.dispatchEvent(new CustomEvent('state-changed', {detail: state})); }; // repeat the above for replaceState too } + ')(); this.remove();'; // remove the DOM script element // And here content script listens to our DOM script custom events window.addEventListener('state-changed', function(e) { console.log('History state changed', e.detail, location.hash); doSomething(); });
-
hashchange , popstate 이벤트 청취 :
window.addEventListener('hashchange', function(e) { console.log('URL hash changed', e); doSomething(); }); window.addEventListener('popstate', function(e) { console.log('State changed', e); doSomething(); });
확장 프로그램 별 : 백그라운드 / 이벤트 페이지 에서 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 사이트에서 플러그인 튜토리얼을 확인하십시오.
답변
MutationObserver
API 에서 제공하는 “원시”도구 외에도 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);
}