Mianowicie, piszę UserJS-a dla Opery do Blipa. Jako entry-point, przeciążyłem metodę Prototype'a Element.insert. Dla tych, którzy nie wiedzą, jak działa Blip - ściąga sobie AJAX-em kod JS, który operuje bezpośrednio na stronie; nie ma żadnego JSON-a, czy czegoś w stylu parsowania, ale to nie jest problem.
I wszystko fajnie-cacy działa, jeżeli są to pojedyncze elementy - moje hooki nie zawodzą.
Jednak problem pojawia się, gdy użytkownik korzysta z paginacji - całe drzewo jest usuwane i metoda Element.insert jest wywoływana wielokrotnie. Wówczas mój skrypt parsuje tylko pierwszy element, w dodatku wielokrotnie. Tak, jakby zmienna z uchwytem elementu była nie uaktualniana przy dodawaniu kolejnych elementów...

Metoda przeciążająca:
var overload = function(){ // extract item ID var Rexpr = /update\-([0-9]+)/i; // overload Prototype's method var o = Element.insert; Element.insert = function(a,b){ // execute filters for(i in filters){ if(filters[i] && (filters[i].test(b.top) || filters[i].test(b.bottom))){ return; } } // use Prototype's previous method: var node = o(a,b); // and parse parseNode(node); } }
Samo parseNode wykonuje naprawdę podstawowe operacje na DOM, ale wariuje nawet odczyt (sprawdzałem). Liczba wywołań się zgadza, ale same dane już nie - za każdym razem jest to samo albo gdzieś znikają elementy (!)...
Jest to bombardowane w mniej-więcej ten sposób:
$$("li.update").each(function(value, index) { value.remove(); }); Element.insert("dashboard-updates", { bottom: "..." }); Element.insert("dashboard-updates", { bottom: "..." }); Element.insert("dashboard-updates", { bottom: "..." }); Element.insert("dashboard-updates", { bottom: "..." }); Element.insert("dashboard-updates", { bottom: "..." }); Element.insert("dashboard-updates", { bottom: "..." }); Element.insert("dashboard-updates", { bottom: "..." }); Element.insert("dashboard-updates", { bottom: "..." }); Element.insert("dashboard-updates", { bottom: "..." }); Element.insert("dashboard-updates", { bottom: "..." }); Element.insert("dashboard-updates", { bottom: "..." }); Element.insert("dashboard-updates", { bottom: "..." }); Element.insert("dashboard-updates", { bottom: "..." }); Element.insert("dashboard-updates", { bottom: "..." }); $$('.next-page').invoke('show');
Moje pytanie - co zrobić, abym mógł manipulować obiektami DOM przy ich dodawaniu zamiast całkowitego skanowania po wykonaniu wielu operacji?
edit: najciekawsza jest jednak inna rzecz, spróbowałem dojść krokami, wtf:
// use Prototype's previous method: var node = o(a,b); // and parse parseNode(node);
Kod do funkcji trafia prawidłowy. Jeżeli wyłuskam ID z kodu i odwołam się przez document.getElementById, to do funkcji zostanie dostarczony zawsze pierwszy, ten sam identyfikator. Jakby DOM nie nadążało za samym sobą...? O.o