2012-07-15 34 views
38

Tôi cần phải theo dõi sự thay đổi thuộc tính trên bất kỳ phần tử con nào của một phần tử DOM cụ thể. Cho đến nay, tôi đã sử dụng mutation events.Xem các thay đổi DOM, cách thanh lịch

Vấn đề là - chúng là lỗi: ví dụ: dưới Chromium, DOMAttrModified không được kích hoạt nhưng DOMSubtreeModified là. Vấn đề rất dễ giải quyết: bởi vì theo đặc điểm kỹ thuật, DOMSubtreeModified bị sa thải nếu bất kỳ sự kiện nào khác bị sa thải, vì vậy tôi chỉ nghe DOMSubtreeModified.

Dù sao, Chromium, trong các phiên bản gần đây, đã ngừng kích hoạt bất kỳ điều gì nếu thuộc tính đã được sửa đổi.

Tuy nhiên, Mutation Observer API mới hoạt động hoàn hảo. Cho đến bây giờ, tôi chỉ cần gọi lại khi bất kỳ thay đổi nào của thành phần cụ thể - đơn giản vì không có gì khác thay đổi - vì vậy tôi đã giải quyết được vấn đề của mình bằng cách sử dụng sự kiện đột biến & trình theo dõi đột biến (nếu có)) trong cùng một đoạn mã. Tuy nhiên, bây giờ tôi cần phải lọc mạnh hơn các sự kiện (ví dụ trên nút mới, trên nút đã loại bỏ) - như vậy có một thư viện, có thể là một plugin jQuery, điều đó sẽ cho phép tôi sử dụng một cách thanh lịch cả hai trong số các API này - MutationObserver nếu các sự kiện có sẵn và đột biến là dự phòng, với khả năng lọc cho các loại sự kiện cụ thể (ví dụ: phần tử được thêm, thuộc tính đã thay đổi).

Ví dụ:

$("#test").watch({onNewElement: 1}, function(newElement){}) 
$("#test").watch({onNewAttribute: 1}, function(modifiedElement) {}) 

Hoặc không jQuery

watchChanges("#test", {onNewElement: 1}, function(newElement){}) 
watchChanges("#test", {onNewAttribute: 1}, function(modifiedElement){}) 
+0

một số tìm kiếm tìm thấy này, nhưng nó chỉ hỗ trợ các API mới: http://code.google.com/p/mutation-summary/ . Tôi cũng tìm thấy điều này, dường như là một phiên bản đơn giản của những gì bạn đang yêu cầu: http://stackoverflow.com/questions/10868104/can-you-have-a-javascript-hook-trigger-after-a- dom-elements-style-object-change – thirtydot

+0

Tôi cũng tìm thấy tóm tắt đột biến, nhưng nó không hỗ trợ các sự kiện đột biến làm dự phòng. Câu trả lời đầu tiên của chuỗi bạn đã đăng về cơ bản là những gì tôi làm trong mã của mình để quan sát các thay đổi thuộc tính. Trong cùng một nguyên tắc, một thư viện có thể được xây dựng cho phép xem các sự kiện DOM cụ thể bằng cách sử dụng cả các quan sát đột biến và (dưới dạng dự phòng). Đó là những gì tôi cần. – Ivo

+2

+1: Tôi thực sự đào các câu hỏi 'thực hành tốt nhất'. –

Trả lời

2

Sẽ làm việc này?

http://darcyclarke.me/development/detect-attribute-changes-with-jquery/

$.fn.watch = function(props, callback, timeout){ 
    if(!timeout) 
     timeout = 10; 
    return this.each(function(){ 
     var el  = $(this), 
      func = function(){ __check.call(this, el) }, 
      data = { props: props.split(","), 
         func: callback, 
         vals: [] }; 
     $.each(data.props, function(i) { data.vals[i] = el.css(data.props[i]); }); 
     el.data(data); 
     if (typeof (this.onpropertychange) == "object"){ 
      el.bind("propertychange", callback); 
     } else if ($.browser.mozilla){ 
      el.bind("DOMAttrModified", callback); 
     } else { 
      setInterval(func, timeout); 
     } 
    }); 
    function __check(el) { 
     var data = el.data(), 
      changed = false, 
      temp = ""; 
     for(var i=0;i < data.props.length; i++) { 
      temp = el.css(data.props[i]); 
      if(data.vals[i] != temp){ 
       data.vals[i] = temp; 
       changed = true; 
       break; 
      } 
     } 
     if(changed && data.func) { 
      data.func.call(el, data); 
     } 
    } 
} 
+0

Tôi đã thấy nó, nhưng nó chỉ dành cho các thuộc tính. Thêm vào đó, nó rơi trở lại setInterval ngay cả khi trình duyệt có thể hỗ trợ DOMAttrModified. – Ivo

+0

@Ivo đúng. Đây là một suy nghĩ mặc dù - là bạn trong kiểm soát của tất cả những thay đổi này xảy ra cho dom?Bạn đã cân nhắc việc ghi đè các phương thức thao tác jquery để kích hoạt một sự kiện thay đổi/chắp thêm/loại bỏ (nhưng đó là giả định tất cả các thay đổi xảy ra thông qua jquery). Tôi biết đó là rất nhiều công việc, và không chính xác những gì bạn đang tìm kiếm, nhưng hoàn thành công việc. –

+1

Tôi đã hoàn thành công việc từ lâu rồi - tôi sử dụng cả các sự kiện đột biến và quan sát để theo dõi các thuộc tính, và tôi chỉ sử dụng các sự kiện để xem các nội dung mới được thêm vào DOM - và tôi không hoàn toàn kiểm soát được vì tôi xem các thay đổi được thực hiện qua trình soạn thảo có thể chỉnh sửa/soạn thảo WYSIHTML5. Nhưng tất cả đều hoạt động cho các trình duyệt mà tôi đã lên kế hoạch hỗ trợ. Đây là câu hỏi "tiếp cận tốt nhất". Và jQuery vá lỗi khỉ có vẻ như là một ý tưởng tồi. Khỉ vá DOM API có thể phù hợp hơn nhưng tôi vẫn không chắc chắn. – Ivo

2

Đối với giám sát DOM hiệu quả với jQuery, bạn có thể có một cái nhìn tại jQuery Behavior Plugin (Disclaimer: Tôi là tác giả) trong đó sử dụng một phiên bản tối ưu hóa của Live Query. Tôi đang sử dụng nó trong một số sản phẩm trong 3 năm nay, mà không có bất kỳ vấn đề.

Edit: Nghe cho những thay đổi thuộc tính sẽ làm việc như thế này:

$.behavior({ 
    'div:first': { 
     'changeAttr': function (event, data) { 
      console.log('Attribute "' + data.attribute + '" changed from "' + data.from + '" to "' + data.to + '"'); 
     } 
    } 
}); 

$('div:first').attr('foo', 'bar'); 
Các vấn đề liên quan