Autor Zpráva
1Pupik1989
Profil
Zdravím, vymýšlím do své knihovničky ovládání událostí. Problém je, že attachEvent spouští frontu od poslední uložené události.

Přiřazení události ala DOM 0 jsem zavrhnul, protože by událost mohl někdo přepsat a nic by se nestalo. Má někdo nějaký typ jak obrátit pořadí spouštěných funkcí v attachEvent nebo jak zabránit přepsání události?

Napadlo mě něco jako:
function addEvent(ctx,name,callback,bubble){
  if(!ctx.eventList){ ctx.eventList = {}; }
  var event_name = name;

  var self_list = ctx.eventList[name];
  if(!self_list){ self_list = ctx.eventList[name] = []; }
  
  if(self_list.length === 0){
    ctx.attachEvent('on'+event_name,function(e){
      var list = ctx.eventList[name];
      if(!list){ return false; }

      for(var i=list.length-1;i>=0;i--){
        list[i].call(this,e);
      }
    });
  }                                    
  
  self_list.push(callback);
};

No ale zrovna 2x nadšený z toho nejsem.
_es
Profil
1Pupik1989:
Problém je, že attachEvent spouští frontu od poslední uložené události.
Myslím, že nie je vôbec zaručené nejaké poradie, v akom sa zavolajú priradené funkcie. Ak ti záleží na poradí, tak to máš asi od základu zle navrhnuté. Okrem toho, nebude attachEvent fungovať len v niektorých prehliadačoch? Tiež nebude rovnako fungovať this ako v addEventListener.

protože by událost mohl někdo přepsat
Kto „niekto“? Tvoje druhé ja? Rovnako môže „niekto“ celý DOM element zmazať a to chceš riešiť ako?
1Pupik1989
Profil
Je to selector na styl jQuery pro prohlížeče co nepodporují querySelector a querySelectorAll. Tu první funkci spouštím já, zbytek může být definován uživateli. Já sám si událost nepřepíšu. Uložím si jí do proměnné a spustím jí před novou po zavolání události.

Bohužel ten attachEvent funkce opravdu náhodně spouští. Proto jsem napsal funkci addEvent.

Svoji funkci musím zavolat jako první, protože traversuje celý DOM a přidává nextElementSibling a podobné neexistující vlastnosti.
_es
Profil
[#3] 1Pupik1989
Ak ti záleží na poradí a to tak, aby bola posledná priradená udalosť spustená ako posledná, tak by mohlo byť riešenie:
function pridajOnclick(element, funkcia) {
  var onclick = element.onclick;
  if(onclick) element.onclick = function(){ onclick.apply(this, arguments); funkcia.apply(this, arguments)}
  else element.onclick = funkcia;
};
1Pupik1989
Profil
Tak jsem jí zapisoval původně. Jenže kdokoliv později v kódu může zapsat:
element.onclick = function(){
 //blabla
};

A tím celou původní událost vyruší. Proto jsem přešel na attachEvent a addEventListener, ač nerad. Napadlo mě celé to ovládat přes událost onpropertychange, jenže i ta se dá vyrušit.
_es
Profil
1Pupik1989:
Jenže kdokoliv později v kódu může zapsat...
A tiež môže napísať:
element.parentNode.replaceChild(inýElement, element);
Alebo predefinovať metódy attachEvent a addEventListener. Alebo vo všeobecnosti hocijako zmeniť hocijaký DOM element. To chceš „riešiť“ ako?
Jan Tvrdík
Profil
Z hlediska rozšiřitelnosti je dobré se chovat „slušně“ a předpokládat od ostatních, že se budou chovat stejně. Zapisovat přímo (tj. bez řešení popsané v [#4]) do např. onclick je neslušné, protože tam mohl mít někdo něco uloženo. Když se chováš neslušně ty, tak se k tobě budou chovat stejně i ostatní.

Tedy problém není v tom, že mi to někdo může přepsat, ale že já možná někomu něco přepisuji.
_es
Profil
Jan Tvrdík:
Zapisovat přímo (tj. bez řešení popsané v [#4]) do např. onclick je neslušné, protože tam mohl mít někdo něco uloženo.
Asi si si to „riešenie“ nedostočne pozrel. Ak by tam mal niekto „niečo uložené“, tak by sa tá uložená funkcia pri udalosti kliknutia spustila.
Jan Tvrdík
Profil
_es:
Přečti si znova, co jsem napsal. S řešením popsaným v [#4] je to úplně v pořádku.
_es
Profil
[#9] Jan Tvrdík:
Aha, tak som to naopak ja nepozorne prečítal. No nejde o to, či je niečo niekam zapisované „priamo“ alebo nepriamo, ale o to, aby zostala zachovaná funkčnosť od iných spolupracujúcich na projekte, čo sa však nemusí zaobísť bez dohody vopred, čo kto môže a nemôže prepisovať. No 1Pupik1989 má podmienku, že jeho funkcia sa má spustiť prvá zo všetkých definovaných pre tú udalosť, čo je však v konflikte s princípom metód attachEvent a addEventListener, ktoré sú navrhnuté práve na predpoklade, že na poradí nezáleží. Čo ak si dá takú požiadavku aj niekto ďalší?
1Pupik1989
Profil
Jde hlavně o událost onload, DOMContentLoaded a onreadystatechange, aby se to traversování spustilo ještě před zavoláním selektoru. U zbytku událostí samozřejmě na pořadí záležet nebude.

Zkusím se na to podívat z druhé strany. Další možnost by mohla být kontrolování document.readyState.
1Pupik1989
Profil
Tak jsem přestal vymýšlet blbosti a v konstruktoru kontroluji jestli traversování proběhlo úspěšně. Pokud ne a "document.readyState" je "complete", tak spustím traversování. Kdyby podpora previousElementSibling a nextElementSibling byla úplná, tak jsem se tomu vyhnul úplně.

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: