ugrás a tartalomhoz

Crossbrowser JS esemény hozzáadása (library nélkül)

Cooty13 · 2011. Jún. 28. (K), 23.06
Sziasztok!

Használtam már addEventListenert is meg az IE borzasztó buta attachEvent() függvényét is. Most szeretnék egy olyan egyszerű függvényt írni ami összekombinálja a kettőt, hogy ne kelljen minden egyes eseményvezérlő hozzáadásánál if()-ekkel piszmogni, meg lehessen ciklusban is használni.
Szóval a következő kódot írtam erre a problémára:

function bindEvent(obj,eventName,func,propagate){
    if(obj){
        if(obj.addEventListener()){
            obj.addEventListner(
                eventName,
                func,
                propagate
            )
        }
        else if(obj.attachEvent){
            obj.attachEvent(
                'on'+eventName,
                func
            )
        }
    return true;}
    else{
        return false;}
}

function myFunction(arg){
    alert(arg);
    if(console){
        console.log('No meghívódtam');
    }
}

bindEvent(document.getElementById('mybutton'),
          'click',
          function(){myFunction('Helló világ!'),
false
}
);
A következő kis demó oldalon meg is lehet tekinteni a HTML-el együtt.

A cél hogy a kód böngésző-konzisztens legyen tulajdonképpen teljesült is, ugyanis egyetlen egy böngészőben sem működik! :)
Én viszont azt szeretném, ha a mybutton gomb lenyomása meghívná a myFunction() függvényt az adott paraméterrel, azaz ki-alertezné, hogy "Helló világ!".

A Firebug dob ugyan hibaüzit (uncaught exception: [Exception... "Not enough arguments" nsresult: "0x80570001 (NS_ERROR_XPC_NOT_ENOUGH_ARGS)" location: "JS frame :: http://kismeszaros.hu/eventhandler_demo/script.js :: bindEvent :: line 3" data: no]), de ez nekem semmit sem mond! :(

Tudna valaki segíteni? - Ja igen, légyszi ne kérdezgesse senki, hogy "Miért nem használsz JQuery-t, az tud ilyet!?" - Direkt tanulás miatt írtam a kódot (no meg vannak olyan projektek, amikor az ember nem akar/nem tud library-re támaszkodni), szóval ha valaki azt is meg tudja magyarázni, hogy ez a kód MIÉRT nem működik és egy működő kód pontosan mitől is működik azért nagyon hálás lennék! :)

Előre is köszönöm!
 
1

szintaktikai hiba

Poetro · 2011. Jún. 28. (K), 23.16
Van benne egy szintaktikai hiba.
function(){myFunction('Helló világ!'),  
false  
}  
Itt rossz helyen van a , és a }. Talán inkább:
function () { myFunction('Helló világ!') }, false  
Erről egyébként annó írtam 2 blog bejegyzést.

A szintaktikai hibák elkerülése végett pedig használj konzisztens kódolási stílust (megfelelően elhelyezett szóközök / új sorok) valamint JSLint / JSHint eszközöket.
2

Nem csak a szintaxis hibás

Cooty13 · 2011. Jún. 29. (Sze), 21.16
Köszi szépen a segítséget, javítottam a szintaktikai hibát, de semmi eredmény pontosan ugyanaz - a számomra megfejthetetlen - hibaüzenet mint eddig.

function bindEvent(obj, eventName, func, propagate ) {
    if(obj){
        if(obj.addEventListener()){
            obj.addEventListner(
                eventName,
                func,
                propagate
            )
        }
        else if(obj.attachEvent){
            obj.attachEvent(
                'on'+eventName,
                func
            )
        }
    return true;}
    else{
        return false;}
}

function myFunction(arg){
    alert(arg);
    if(console){
        console.log('No meghívódtam');
    }
}

bindEvent(document.getElementById('mybutton'),
          'click',
          function(){myFunction('Helló világ!')},
          false
);


4

4. sorban meg elírtad,

Karvaly84 · 2011. Jún. 29. (Sze), 21.37
4. sorban meg elírtad, kihagytál egy betüt
9

Nincsen benne semmilyen

Pusztai Tibor · 2011. Jún. 30. (Cs), 18.46
Nincsen benne semmilyen szintaktikai hiba, csak éppen teljesen más volt leírva, mint amit szeretett volna.

The JavaScript Comma Operator
3

3. sor

Karvaly84 · 2011. Jún. 29. (Sze), 21.23
Hali nem vagyok benne biztos de a 3. sorban a feltételben ha le akarod kérdezni hogy egy objektum támogat e egy metódust akkor azt ne úgy tedd, hogy a feltételben futtatod annak függvényét.. egyrészt explorerben ez hibát dob mert a undefied másrészt ha a függvény nem ad vissza semmit akkor is undefined ami false-ra értékelödik ki ezért sose teljesül ez a feltétel,

if (obj.addEventListener()) {
    // Ez nem jó
}
// Így lessz a jó:
if (obj.addEventListener) {}
// vagy
if ('addEventListener' in obj) {}
5

Megvan!

Cooty13 · 2011. Jún. 30. (Cs), 10.43
Köszi a segítséget Karway! Valóban az ellenőrzésben volt a hiba (no meg valóban elírtam az addEventListener-t, amit azért nem értek, mert a Komodo Editben van autocomplate JS-re, de ez már kijött volna mert ugye azt mondta volna a konzol, hogy "addEventListner is undefined" erről meg már csak rájöttem volna... :D)

Fura egyébként mert eredetileg asszem én is '.()' nélkül írtam, hogy if(obj.addEventListener){...}, nem tudom miért változtattam meg rosszra. Most már ezt is tudom, hogy ha van mögötte '.()' akkor futtatni akarja. A végén aztán in operátort használtam. Most működik IE (8-as) és FF-ben meg Chrome-ban is. És elvileg ennek ciklusba betéve is futnia kell gondolom ha az obj=arrElements[i].

Mondjuk tisztában vagyok vele, hogy ez elég primitív megoldás, mert ugye nem normalizálom az Event objektumot, hogy tudjak mindenhol this-t használni (ha jól értem Poetro linkelt kódjában ez történik), meg nincs megoldva, hogy le is tudjam szedni az eseményvezérlőt, de egyelőre ez is megteszi.

Köszi még egyszer!
6

Az a helyzet, hogy ez már

inf · 2011. Jún. 30. (Cs), 14.06
Az a helyzet, hogy ez már volt párszor itt téma, szóval simán visszakereshetnéd.
A másik meg, hogy nem lehet egyszerűen megcsinálni, mert vannak különbségek az eventek nevei között is.
pl:
w3c: oninput
msie: onpropertychange + event.propertyName=="value"


Szóval mindenképp kell egy map, ahol adsz valami közös nevet egy-egy eseménynek, meg letárolod, hogy az event object tulajdonságait hogyan kell közös nevezőre hozni. Innentől meg már ugrott az egyszerű megoldás.

A másik lehetőség, hogy msie-ben csinálsz egy behavior-t, ami megcsinálja ugyanezt, amit írtam, csak alapból beépül a dom objektumokba (és mellesleg széteszi a procit).
7

Ezért csináltam

Poetro · 2011. Jún. 30. (Cs), 15.40
Pont ezért csináltam meg a saját megoldásomat, ami ugyan nem teljes, és lehetne még optimalizálni (amit lehet hamarosan meg is teszek), de "elég" megbízhatóan működik ahhoz, hogy használni lehessen a leggyakoribb körülmények között.
8

Jaja, láttam már. Nekem is

inf · 2011. Jún. 30. (Cs), 16.42
Jaja, láttam már. Nekem is van saját megoldásom, de én inkább framework párti vagyok, egyszerűbb nekem úgy az élet...
10

Üdw Poetro!

Karvaly84 · 2011. Jún. 30. (Cs), 21.59
Anno nekem is te segítettél ebben a kérdésben, és néztem a kódodat is ötletekért, utána bújtam a szabványt és teszteltem....

Amit le írtam hsz-ben is de sztem nem olvastad, a lényeg a buborékban van, mikor te a event.target -et adod át a callback függvénynek this objektumként, ami ugye azonos lesz a buborékban a target-el, szabvány szerint a this marad az amihez a listener be lett állítva. de azért sokat és sokszor segitettél már, nem kötekszem.. BéKE!
11

Tudom

Poetro · 2011. Jún. 30. (Cs), 22.03
Tudom, hogy nem tökéletes a megoldásom, és vannak hibái. Nyugodtan lehet kötekedni, nem bántódok me.