Autor Zpráva
JaySee
Profil
Ahoj,

řeším situaci, kdy potřebuji vykonat script ve chvíli, když se na stránce objeví specifický identifikátor.
Vím že se objeví po nějaké konkrétní akci a potřebuji na to zareagovat co nejrychleji od chvíle, kdy začne existovat.
Potíž je v tom, že původce události neznám (jedná se o cizí script, potažmo několik scriptů které neznám a mohou se měnit). Takže to nemohu řešit jako jejich callback.

Současně bych to řešil tak, že když je zavolána akce (to si zjistím event handlerem), tak bych nastavil setInterval a zjišťoval by, jestli už vznikl onen AJAXem načtený Identifikátor (to právě dělá ten cizí script) a ve chvíli, kdyby regulerní výraz (pro hledání onoho nově vzniknuvšího Identifikátoru) zahlásil shodu, pak bych vykonal svůj script a zrušil setInterval.

Ale říkám si, existuje lepší řešení? Věřím že ano, ale nevím, kterým směrem ubírat své myšlenky. Takže jestli někoho napadá, jak to udělat lépe, budu moc rád za náměty.
Díky
Amunak
Profil
Nejlepší by bylo kontaktovat původního autora skriptu a domluvit se s ním na nějakém API. Jinak můžete taky posílat ajaxové požadavky přes PHP na svém serveru (pokud je to v tomto případě možné), a zkoumat odpovědi tam. Na stránku už si je pak předáte tak, jak se vám to hodí. No a pokud to chcete řešit čistě javascriptem, bylo by nejlepší získat si objekt AJAX requestu a zkoumat při změně ten. A jestli ani to není možné, pak je třeba najít událost, která je vytvoření toho ID nejblíže (je to nějaké zapsání do stránky?) a pak ho co nejpřesněji zjistit (tedy nejlépe jen přečtením proměnné, nebo konktrétního elementu, kam se to ID zapisuje), ale vyvarujte se parsování celé stránky, nebo se vám nejspíš bude sekat prohlížeč.
Jan Tvrdík
Profil
JaySee:
Tvé řešení mi připadá v pořádku. Lepší řešení (např. websockety) by to zbytečně komplikovaly.

Možná to ale vůbec nechápu. Co si představuješ pod identifikátorem a kde by se měl objevit?


Zajímá-li tě, jak detekovat změnu v DOM, tak lze použít třeba developer.mozilla.org/en-US/docs/DOM/MutationObserver, ale funguje to akorát v novém Chrome a FF.
JaySee
Profil
Amunak:
Jednoduše.
- při kliknutí na odkaz (javascript:void(0) nebo #) se začne vykonávat funkce, která ajaxem načte novou část stránky a pak ji vykreslí
- já jsem schopen odchytit ono kliknutí (při kterém se posílá IDčko) a chci sledovat v DOM, zda se objeví ten nově načtený obsah.
- detekovat jej chci právě pomocí přítomnosti IDčka v konkrétníém stringu (URL), proto ten regulerní výraz
- tuším, v jaké části DOMu se ten nově načtený obsah objeví, takže nebudu muset parsovat vše
- komunikace s autory scriptů nepřipadá moc v úvahu

Jan Tvrdík:
MutationObserver je vpodstatě řešení, co bych potřeboval, ale jak to udělat crossbrowser?
Chamurappi
Profil
Reaguji na JaySeeho:
se začne vykonávat funkce, která ajaxem načte novou část stránky a pak ji vykreslí
Jakým způsobem je vyvolán ten AJAX? Můžeš té funkci vyměnit pod nosem objekty či funkce, které používá.
Jan Tvrdík
Profil
JaySee:
MutationObserver je vpodstatě řešení, co bych potřeboval, ale jak to udělat crossbrowser?
Použij ten setTimeout, už jsem psal na začátku, že je to poměrně dobré řešení. Prohlížeč to zatíží minimálně (napíšeš-li to rozumně) a reagovat to bude téměř okamžitě. Ideálně použij ten MutationObserver tam, kde funguje, a setTimeout použij jako fallback.

Chamurappi:
Psal, že ty skripty nezná a mohou se měnit.
Amunak
Profil
A to se pokoušíš napsat bookmarklet, který hledá toto ID, nebo userscript, nebo co vlastně? Přeci když máš JS+DOM přístup k té stránce, tak můžeš změnit funkci kterou volá kliknutí na ten odkaz, a přidat si tam vlastní kód pro hlídání toho AJAX requestu a následně pro získání ID.
JaySee
Profil
Ahoj,
tak tady mám řešení,
script běží dokud nenajde onen specifický object, který obsahuje v jednom konkrétním odkaze ID. A když ho najde, tak se zastaví. Co vy na to pánové, je to přijatelné řešení?

$(".item a").click(function(){
    // get the ID
    var $s = $(this).parent("div").attr("data-id");
    
    function theLoop() {
      return window.setInterval( function() {

            var $x = $(".box a.button");
            // check if is not empty
            if($x.length > 0)
                {
                $inID = $x.attr('href');
                    if ($inID.indexOf($s)>=0)
                        {
                          // do the magic stuffs
                          //.....
                          // and destroy Interval
                          window.clearInterval(finder);
                        }
                }           
          }, 200 );
    };
    var finder = theLoop();
});

Amunak:
Je to parazitní script, takže dalo by se říci, že bookmarlet. Co se týče přístupu do DOM, neznám vůbec ty scripty, které to způsobují a vlastně jsou mi uplně šum a fuk. Vycházím pouze ze dvou stavů a to jest před kliknutí a po vykonání funkce na kliku. Mým cílem je eliminovat časovou prodlevu po vykonání prvotního scriptu a zatížit browser co možná nejméně.
Chamurappi
Profil
Reaguji na Jana Tvrdíka:
Nejspíš by mohl podchytit obecně všechny XMLHttpRequesty.


Reaguji na JaySeeho:
$inID
Podle jaké logiky dáváš na začátek názvu proměnné dolar? Tohle není PHP.
JaySee
Profil
Chamurappi:
Podle jaké logiky dáváš na začátek názvu proměnné dolar? Tohle není PHP.
To je síla zvyku a nevím o tom, že by to javascriptu vadilo. Vadí mu to?
_es
Profil
JaySee:
nevím o tom, že by to javascriptu vadilo. Vadí mu to?
„Nevadí“ mu to o nič viac než dávať na začiatok názvu trebárs „Q“, prečo si teda nenazval premennú Q$x, keď to „nevadí“?

Jan Tvrdík:
Psal, že ty skripty nezná a mohou se měnit.
To by sa ale potom už mohol zmeniť aj ten „identifikátor“.
JaySee
Profil
_es:
Mohl jsem to tak udělat, leč odkojen na PHP, Q mi nic neříká :-D ale mohu-li požádat, neřešme v tomto vlákně $x a Q$x zápis proměnných. Děkuji.

Co se týče toho identifikátoru, tak ten se mění, jsou jich tam stovky, ale vždy se na základě jednoho, který je odchycen, zašle dodatečný obsah AJAXem, ve kterém je to ID přítomno. Takže proto to nazývám Identifikátorem, jakožto ukazatel na specifickou část DOMu.

Nicméně, vyvstal mi ještě jeden problém v souvislosti s tímto tématem.
Dosud jsem řešil, že očekávám po kliknutí do nějaké krátné doby objevení se nového obsahu. Stačilo tedy rozjet smyčku, který chvíli číhá. Řekněme, že zátěž pro browser nikterak extremní. Jenže ono je možno výše popisovaný jev způsobit i jen obyčejným scrollováním na stránce, a to přemýšlím, jestli zkoumat část DOMu vždy, když user hejbne myšítkem dolů či nahoru. Nebo-li jakým způsobem detekovat přítomnost či nepřítomnost prvku na stránce co nejefektivněji s co nejmenšími nároky na uživatele?
Amunak
Profil
Já si stále myslím, že nejsnazší by bylo upravit si tu funkci, která "se může měnit". Nečekal bych, že se změní, a když, tak úprava kódu pro to, abys to znovu rozchodil, by byla triviální. Nebo opravdu odchytávat všechny AJAX requesty.
JaySee
Profil
Amunak:
Nakonec jsem to udělal méně elegantním způsobem. Když uživatel scrolluje, tak ověřuji, jestli se změnila výška stránky a pokud ano, tak spustím smyčku, která hledá nově vzniknuvší elementy.

Vaše odpověď

Mohlo by se hodit

Neumíte-li správně určit příčinu chyby, vkládejte odkazy na živé ukázky.
Užíváte-li nějakou cizí knihovnu, ukažte odpovídajícím, kde jste ji vzali.

Užitečné odkazy:

Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm: