29

HTML5 bao gồm khái niệm về "mutation observers" để theo dõi các thay đổi đối với DOM của trình duyệt.Bộ chọn jQuery có thể được sử dụng với các nhà quan sát đột biến DOM không?

Gọi lại người quan sát của bạn sẽ được chuyển dữ liệu trông giống như đoạn mã DOM của cây. Tôi không biết liệu chúng có chính xác hay không và chúng hoạt động như thế nào. Tuy nhiên, khi bạn đang viết mã để tương tác với trang web của bên thứ ba mà bạn không có quyền kiểm soát, hãy nói với tập lệnh Greasemonkey hoặc tập lệnh người dùng Google Chrome, bạn phải kiểm tra cây yếu tố được truyền để tìm thông tin nào có liên quan đến bạn.

Điều này đơn giản hơn nhiều với các bộ chọn, giống như làm việc với bất kỳ DOM nào, hơn là di chuyển cây theo cách thủ công, đặc biệt là đối với mã trình duyệt chéo.

Có cách nào để sử dụng bộ chọn jQuery với dữ liệu được chuyển tới lời gọi quan sát đột biến HTML5 không?

+0

Câu hỏi liên quan: [Có trình lắng nghe thay đổi jQuery DOM không?] (Http://stackoverflow.com/questions/2844565/is-there-a-jquery-dom-change-listener), [Sự kiện biến đổi DOM trong JQuery hoặc vanilla Javascript] (http://stackoverflow.com/questions/7692730/dom-mutation-event-in-jquery-or-vanilla-javascript) – hippietrail

+0

Xem thêm: [Tôi có thể sử dụng bộ chọn Jquery trên chuỗi HTML không đính kèm với DOM?] (http://stackoverflow.com/questions/4336674) – hippietrail

+1

Có một ** plugin ** cho điều đó: https://github.com/kapetan/jquery-observe – vsync

Trả lời

35

Có, bạn có thể sử dụng bộ chọn jQuery trên dữ liệu được trả về cho các callback quan sát đột biến.

See this jsFiddle.

Giả sử bạn có HTML như vậy:

<span class="myclass"> 
    <span class="myclass2">My <span class="boldly">vastly</span> improved</span> 
    text. 
</span> 


Và bạn thiết lập một quan sát viên, như vậy:

var targetNodes   = $(".myclass"); 
var MutationObserver = window.MutationObserver || window.WebKitMutationObserver; 
var myObserver   = new MutationObserver (mutationHandler); 
var obsConfig   = { childList: true, characterData: true, attributes: true, subtree: true }; 

//--- Add a target node to the observer. Can only add one node at a time. 
targetNodes.each (function() { 
    myObserver.observe (this, obsConfig); 
}); 

function mutationHandler (mutationRecords) { 
    console.info ("mutationHandler:"); 

    mutationRecords.forEach (function (mutation) { 
     console.log (mutation.type); 

     if (typeof mutation.removedNodes == "object") { 
      var jq = $(mutation.removedNodes); 
      console.log (jq); 
      console.log (jq.is("span.myclass2")); 
      console.log (jq.find("span")); 
     } 
    }); 
} 

Bạn sẽ lưu ý rằng chúng ta có thể jQuery trên số mutation.removedNodes.


Nếu bạn sau đó chạy $(".myclass").html ("[censored!]"); từ giao diện điều khiển bạn sẽ có được điều này từ Chrome và Firefox:

mutationHandler: 
childList 
jQuery(<TextNode textContent="\n ">, span.myclass2, <TextNode textContent="\n text.\n ">) 
true 
jQuery(span.boldly) 

đó cho thấy rằng bạn có thể sử dụng phương pháp lựa chọn jQuery bình thường trên các bộ nút trả lại.

+1

Bạn có biết nếu nó được hỗ trợ chính thức bởi jQuery, nếu nó hoạt động trong tất cả các trình duyệt mà jQuery hỗ trợ và hỗ trợ các nhà quan sát đột biến? Nó có thể là nó chỉ xảy ra để làm việc trong các trình duyệt này? Có vẻ như đó là trường hợp vì hành vi có vẻ khác ... Tôi chắc chắn sẽ chơi với nó ngay bây giờ! (-: – hippietrail

+1

Tôi không nghĩ đó là câu hỏi về sự hỗ trợ "chính thức". Những thứ như 'removeNodes' và' addedNodes' [danh sách trả về của các nút] (http://dvcs.w3.org/hg/domcore/raw- file/tip/Overview.html # dom-mutationrecord-addednodes) jQuery hoạt động trên các danh sách như vậy suốt cả ngày, luôn luôn có. ... Mã hoạt động trên Firefox và Chrome, và theo thông số W3C. Nó sẽ hoạt động trên mọi trình duyệt –

+1

PS, xem câu trả lời được cập nhật và jsFiddle đã thêm –

2

Tôi đang làm việc trên một vấn đề rất giống với tập lệnh Stack Exchange tôi đang làm việc và tôi cần có khả năng giám sát DOM để thay đổi. Các tài liệu jQuery không có bất cứ điều gì hữu ích, nhưng tôi đã khám phá ra rằng sự kiện DOMNodeInserted làm việc trong Chrome:

document.addEventListener("DOMNodeInserted", function(event){ 
    var element = event.target; 

    if (element.tagName == 'DIV') { 
     if (element.id == 'seContainerInbox') { 
      //alert($('#seContainerInbox').parent().get(0).tagName); 
      trimStoredItems(); 
      $('#seTabInbox').click(); 
      // var newCount = getNewCount(); 
      // if there are new inbox items, store them for later 
      storeNewInboxItems(); 
      applyNewStyleToItems(); 
     } 
    } 
}); 

Tôi không chắc chắn 100% nếu điều này làm việc trong Firefox như tôi đã không nhận rằng đến nay chưa trong quá trình phát triển. Hi vọng điêu nay co ich!

+0

Tôi đang sử dụng 'WebKitMutationObserver() 'mà tôi nghĩ là mới và được hỗ trợ và những thứ cũ không được chấp nhận. Tôi không chắc chắn nếu 'DOMNodeInserted' là một phần của" công cụ cũ "đó. 'WebKitMutationObserver' chuyển cho bạn một đối tượng đột biến trong khi tôi đoán nó không phải là bản thân DOM về cơ bản là một gói các tham chiếu DOM. Tôi muốn biết nếu tôi có thể quấn nó hoặc một số tài liệu tham khảo với jQuery ... – hippietrail

+0

Tôi đã không sử dụng bản thân mình, nhưng từ cách bạn mô tả nó, tôi nghi ngờ bạn có thể phải truy cập vào các nguyên tố RAW DOM vì vậy bạn có thể chuyển chúng vào một đối tượng jQuery như các phần từ hai câu đố. Tôi đoán nó sẽ thực sự phụ thuộc vào các loại dữ liệu thực tế. Có thể nhìn vào những gì "typeof" cung cấp cho bạn để xem nếu nó là một cái gì đó mà có thể dễ dàng bọc. Hi vọng điêu nay co ich! – jmort253

+5

'DOMNodeInserted' không phải là một phần của các nhà quan sát đột biến. Đó là hệ thống cũ, lỗi, * không dùng nữa *, đột biến-sự kiện mà các nhà quan sát đột biến thay thế! –

7

tôi không có bất kỳ đoạn mã cá nhân cho thế này, nhưng tôi có ba nguồn tài nguyên có thể giúp:

Ví dụ từ liên kết # 3 'thư viện jquery-mutation-summary':

// Use document to listen to all events on the page (you might want to be more specific) 
var $observerSummaryRoot = $(document); 

// Simplest callback, just logging to the console 
function callback(summaries){ 
    console.log(summaries); 
} 

// Connect mutation-summary 
$observerSummaryRoot.mutationSummary("connect", callback, [{ all: true }]); 

// Do something to trigger mutationSummary 
$("<a />", { href: "http://joelpurra.github.com/jquery-mutation-summary"}).text("Go to the jquery-mutation-summary website").appendTo("body"); 

// Disconnect when done listening 
$observerSummaryRoot.mutationSummary("disconnect"); 
+3

Hi Vita, Stack Overflow câu trả lời thường bao gồm các ví dụ mã, không chỉ là một liên kết đến một bên thứ ba. Bạn có thể xin vui lòng gửi một ví dụ ở đây trong Stack Overflow chính nó bằng cách thực hiện một [sửa] cho bài viết của bạn? Nếu liên kết bị vỡ, câu trả lời của bạn sẽ vô dụng. Với một ví dụ, nó sẽ hữu ích cho các du khách tương lai khác, những người đang đối mặt với cùng một vấn đề, trong nhiều năm tới. Chúc may mắn! – jmort253

+0

Chắc chắn! Cũng tìm thấy một số tài nguyên khác có thể hữu ích. –

+0

Hmm Tôi đã cố gắng sử dụng phiên bản gốc không phải jQuery của [Tóm tắt đột biến] (https://code.google.com/p/mutation-summary/) nhưng thấy nó không hoạt động tốt với các trang không được thiết kế kịch bản người dùng trong tâm trí. Thật tốt khi xem các thay đổi đối với các phần tử được tham chiếu bởi 'id' hoặc' class' nhưng không tốt lắm khi tất cả các thay đổi mà bạn quan tâm là một số phần tử sâu hoặc với 'id's và' className's được tạo. – hippietrail

2

Tôi biết đây là câu hỏi cũ nhưng có lẽ điều này có thể giúp những người khác tìm kiếm giải pháp thay thế. Gần đây tôi đã học về các nhà quan sát đột biến và muốn thử nghiệm với việc sử dụng chúng cùng với jQuery. Tôi đã đưa ra hai cách tiếp cận có thể và biến chúng thành các plugin. Mã có sẵn here.

Phương pháp đầu tiên (jquery.observeWithEvents.js) sử dụng trigger() chức năng của jQuery để kích hoạt hoặc một sự kiện insertNode hoặc removeNode có thể bị ràng buộc để qua on() chức năng của jQuery. Cách tiếp cận thứ hai (jquery.observeWithCallbacks.js) sử dụng các tham số gọi lại truyền thống. Vui lòng xem README để biết các ví dụ và cách sử dụng.

Các vấn đề liên quan