2012-03-19 1 views
7

Мне нравится запускать собственные скрипты на страницах, которыми я не владею или не управляю. Во многих случаях эти страницы имеют динамически созданный контент, к которому я хотел бы применить функцию.Обработчик динамически созданных узлов DOM при их вставке

Возможно ли это? Если да, то как я могу это сделать? В идеале я ищу что-то живое jQuery's live, но вместо привязки события, такого как click, это будет больше похоже на событие, которое происходит, когда элемент загружается в DOM. load Событие будет работать для некоторых элементов, но я не думаю для всех ...

Для этого вопроса предположим, что вы не можете посмотреть или изменить код, вставляющий узлы DOM. Я хотел бы использовать технику, которую я мог бы использовать в пользовательском или букмаркете, который можно было бы использовать на нескольких несвязанных сайтах.

Изменить: Я ищу что-то, чтобы использовать на моем инвертировать цвета букмарклет: JavaScript: Invert color on all elements of a page

+0

Какие функции вы хотите применить? Вы могли бы прослушать событие DOMNodeInsertedIntoDocument, но это, вероятно, применимо ко многим вставленным узлам, вас это не интересует. – nrabinowitz

+0

Меня интересует каждый узел на самом деле. Я меняю цвета всего на странице. – Muhd

ответ

6

Предполагая, что вы используете браузер, как Firefox или Chrome, вы можете слушать для DOMNodeInserted события:

$(document).on('DOMNodeInserted', function(e) { 
    $(e.target).css({ color : '#c00' }); 
}); 

$('body').append('<div>test</div>');​ 

Fiddle: http://jsfiddle.net/VeF6g/ (вероятно, терпит неудачу в IE)

+1

Я просто хотел бы отметить ради случайных читателей: не используйте мутационные события, если вы можете этого избежать. Подробности: http://lists.w3.org/Archives/Public/public-webapps/2011JulSep/0779.html – Nickolay

+1

@ Nickolay - спасибо за ссылку. Я знаю, что это плохая идея в целом использовать их, но, по-видимому, это разумно для случая использования OP (среди прочего, обсуждение касается пользовательского скрипта, поэтому он будет единственным, кто пострадает от медлительности или сбоев). – nrabinowitz

1

Это довольно трудно сделать, потому что не жизнеспособны событие для реагирования на изменения DOM. Вместо этого я предпочел бы придерживаться делегирования событий.

Но есть некоторые события, которые могут оказаться полезными или интересными. На Mozilla Developer Network's list of DOM events вы можете увидеть, например .:

  • DOMNodeInserted,
  • DOMNodeInsertedIntoDocument,
  • DOMNodeRemoved,
  • DOMElementNameChanged,

Все из них, однако помечены как W3C сквозняков.

+0

Какие браузеры реализованы? В идеале мне хотелось бы что-то, что работает в Chrome. – Muhd

+0

Маркер «черновик» является надзором со стороны редакторов MDC. Эти события были также в событиях DOML2, что является «рекомендацией». Факт в том, что большинство этих событий работают на всех, кроме IE; но вы должны избегать их использования, если можете, поскольку у них есть серьезные недостатки (подробности: http://lists.w3.org/Archives/Public/public-webapps/2011JulSep/0779.html) – Nickolay

1

Общим способом обнаружения вставки узлов является использование события мутации DOMNodeInserted.

Меня интересует каждый узел на самом деле. Я меняю цвета всего на странице.

Для этой цели лучшим решением является введение динамической таблицы стилей, которой обладает флаг !important. Если вы хотите изменить цвета, я рекомендую расширение Stylish (Stylish for Chrome) вместо GreaseMonkey.

+0

Правильно, но '! important' flag уничтожит много страниц. Я ищу создать интеллектуальный скрипт, который работает на разных страницах и выглядит хорошо. – Muhd

+0

@Muhd Вы можете выбирать интеллектуальные селектора только для выбора определенных элементов. Стильный поддерживает выбор домена с помощью RegExes с помощью '@ -moz-document regexp()' - См. Также ['@ document'] (https://developer.mozilla.org/en/CSS/@document). –

1

Если у вас нет доступ к библиотеке, как JQuery, вот синтаксис в только- JavaScript:

document.addEventListener('DOMNodeInserted', nodeInsert) 

function nodeInsert() { 
    event.srcElement.style.color = '#ffffff' 
} 

Я думаю, что он должен работать в большинстве браузеров.

3

Вот один хороший способ обработки события вставки узла. установите анимации для элемента, который вы собираетесь добавить с помощью css.

<style type="text/css"> 

/* set up the keyframes; remember to create prefixed keyframes too! */ 

@keyframes nodeInserted { 
from { opacity: 0.99; } 
to { opacity: 1; } 
} 

#parent > button { 
animation-duration: 0.001s; 
animation-name: nodeInserted; 
} 

</style> 

#parent это идентификатор для DIV, в котором я буду добавлять кнопки он динамически.

<script type="text/javascript"> 

    var insertListener = function(event){ 
     if (event.animationName == "nodeInserted") { 
      // This is the debug for knowing our listener worked! 
      // event.target is the new node! 
      console.warn("Another node has been inserted! ", event, event.target); 
     } 
    } 

    document.addEventListener("animationstart", insertListener, false); // standard + firefox 
    document.addEventListener("MSAnimationStart", insertListener, false); // IE 
    document.addEventListener("webkitAnimationStart", insertListener, false); // Chrome + Safari 

    setInterval(function(){ 

     var btn = document.createElement("BUTTON"); 

     var t = document.createTextNode("CLICK ME");  // Create a text node 

     btn.appendChild(t);   

     document.getElementById("parent").appendChild(btn); 

    }, 2000); 

</script> 
+0

Я реализовал этот метод и запрограммировал некоторое отзывчивое изменение размера iframe внутри метода insertListener. Странно, что пользовательское поведение изменения размера происходит только после прокрутки до 'iframe', а не раньше. Любая идея, что может здесь происходить? –