Avatar billede chrisbookwood Nybegynder
14. september 2008 - 14:56 Der er 68 kommentarer og
1 løsning

Hvorfor stopper min event-handler IE?

Hej,
jeg sidder med et stykke kode hvor der indegår to event-handlere, og så vidt jeg kan se, er det oprettelse af den nye event (addEvent) der får IE til at gøre absolut intet - ikke engang reagere på den event der kalder editPhrase - addEvent(pElm, 'click', editPhrase)

Jeg har følgende:

function editPhrase(e) {
var phrase = getTarget(e).lastChild.nodeValue;
while(getTarget(e).lastChild) getTarget(e).removeChild(getTarget(e).lastChild);
               
var edit = document.createElement('input');
edit.setAttribute('type', 'text');
edit.setAttribute('value', phrase);
edit.setAttribute('class', 'text');
getTarget(e).appendChild(edit);
       
removeEvent(getTarget(e), 'click', editPhrase);
addEvent(getTarget(e), 'click', savePhrase);
}

Koden til addEvent, removeEvent og getTarget kan findes her: http://www.smidsmid.dk/showoff.txt

Jeg har testet det i Firefox, Chrome, Opera, Safari og IE, og det er kun i IE det går galt. IE siger hverken fejl eller noget, der sker bare intet.

Jeg håber der er nogen der kan kaste lys over problemet.
På forhånd tak
Avatar billede olebole Juniormester
14. september 2008 - 15:04 #1
<ole>

Prøv at vise et live eksempel, der ikke fungerer. Forøvrigt skal du i IE bruge:
    edit.setAttribute('className', 'text');

- men i andre browsere:
    edit.setAttribute('class', 'text');

/mvh
</bole>
Avatar billede chrisbookwood Nybegynder
14. september 2008 - 15:10 #2
Ja okay, giv mig lige 2sek så jeg kan fjerne noget sikkerhed fra siden
Avatar billede chrisbookwood Nybegynder
14. september 2008 - 15:13 #3
Avatar billede chrisbookwood Nybegynder
14. september 2008 - 15:18 #4
Det skal så lige siges, at måden du aktivere editPhrases funktionen er et trykke på en hvilken som helst sætning på listen, og for at gemme den redigerede sætning, trykker du på whitespace mellem inputfeltet og den grå streg under inputfeltet du redigere sætningen i.
Avatar billede chrisbookwood Nybegynder
14. september 2008 - 17:02 #5
er der ingen der har en idé til hvordan jeg løser det?
Avatar billede chrisbookwood Nybegynder
14. september 2008 - 19:49 #6
Ej, det kan da ikke passe at der ikke er nogen der kan hjælpe mig - eller er der bare ikke nogen der gider at kigge i denne tråd? -.-
Avatar billede olebole Juniormester
14. september 2008 - 20:11 #7
Rolig nu ... vi har også andet at lave! Det er forskellen på at betale E-points og kroner.

Du har under alle omstændigheder et problem omkring navngivningen af dine div. En id må ikke begynde med et tal, men _skal_ begynde med et bogstav eller en underscore.

Om det er årsagen - og IE ikke vil adressere felterne - ved jeg dog ikke. Under alle omstændigheder bør du rette det.

Jeg kan ikke teste så meget på din applikation, da load.php kun kan tilgås med XMLHttpRequests fra dit eget domæne, så prøv selv at teste på hvad somhelst med en alert.
Begynd i toppen af den funktion, du mistænker og alert alle variabler, der kan have interesse. Flyt derefter alerten en linje eller to og alert nye variabler og/eller ændrede tilstande/værdier ... fortsæt på denne måde til bunden af funktionen. Gå derefter videre til næste funktion, osv.
Avatar billede olebole Juniormester
14. september 2008 - 20:20 #8
Jo, i IE kan jeg åbenbart godt kalde load.php herfra. Det ser ud til, at serveren faktisk kaldes, hvis jeg klikker på et div. Det betyder, at det ikke er din event handler, der fejler noget. Jeg tester lige lidt mere  =)
Avatar billede chrisbookwood Nybegynder
14. september 2008 - 20:21 #9
Sorry, men jeg har siddet med denne fejl siden igår, så man bliver lidt frustreret med tiden...

Hvis jeg nu fortæller dig at hvis man fjerner addEvent(getTarget(e), 'click', savePhrase); fra funktionen, så gør IE alt helt perfekt (bortset fra selvfølgelig at tilføje eventen), men lige så snart den tilføjes, sker der intet igen.
Jeg har prøvet at debugge shittet, hele dagen, og det var det eneste jeg kunne finde.
Avatar billede olebole Juniormester
14. september 2008 - 20:42 #10
Problemet er, at når du sætter event'en i slutningen af editPhrase, er handleEvent ikke færdig med at loope igennem alle event handlers for typen 'click'. Derfor vil din nye event handler ligge som den sidste i array'et - og savePhrase bliver afviklet
Avatar billede olebole Juniormester
14. september 2008 - 20:46 #11
Løsningen kunne f.eks. være:


        removeEvent(getTarget(e), 'click', editPhrase);
        var x = getTarget(e);
        setTimeout(function(){addEvent(x, 'click', savePhrase)},50);
Avatar billede chrisbookwood Nybegynder
14. september 2008 - 20:46 #12
Ja, IE (8 beta) fortalte mig også at fejlen opstod i handleEvent...
Har du nogen idé til hvordan jeg løser dette?
Avatar billede chrisbookwood Nybegynder
14. september 2008 - 20:47 #13
aah, der må da være en mere rationel løsning - men måske ikke?
Avatar billede olebole Juniormester
14. september 2008 - 20:51 #14
Jeg ville nok også lade add- og remove-funktionerne være IE-aware:

function addEvent(element, type, handler) {
    if (element.addEventListener) {
        element.addEventListener(type, handler, false);
    } else if (element.attachEvent) {
        element.attachEvent("on"+type, handler);
    } else {
        // assign each event handler a unique ID

- og:

function removeEvent(element, type, handler) {
    if (element.removeEventListener) {
        element.removeEventListener(type, handler, false);
    } else if (element.detachEvent) {
        element.detachEvent("on"+type, handler);
    } else {
        // delete the event handler from the hash table
Avatar billede olebole Juniormester
14. september 2008 - 20:54 #15
Pas forøvrigt på med 'dit' logo  ;o)
Avatar billede chrisbookwood Nybegynder
14. september 2008 - 21:00 #16
Yeah, det er er kun et logo der vil være på den, normalt, private side du fik link til, så det går nok;)

Jeg sidder og forestiller mig at løsningen er at finde en killer event-handler samling, i stedet for det jeg kører med der. Har du nogen forslag? Jeg har før fundet et link til en konkurrence om hvem der kunne lave de bedste event handlers og sådan - ret hardcore kode, hvor jeg ikke fatter halvdelen af hvad der står i den, hvilket også er hvorfor jeg har valgt at bruge den jeg kører med nu. Men måske det var et dårligt valg:P
Avatar billede olebole Juniormester
14. september 2008 - 21:02 #17
Men hvorfor egentlig al den event gymnastik? Sæt én event handler på alle div. Lad denne handler sætte en attribut på div'et, der skifter hver anden gang, der klikkes. Værdien af attributten afgør så, hvad der skal ske, når der klikkes.

KISS  ;o)
Avatar billede olebole Juniormester
14. september 2008 - 21:04 #18
Husk også, at ECMA 262 reserverer tegnet '$' til maskingenereret kode. Det bør du ikke bruge i variabelnavne (selvom det desværre er vældig på mode for tiden)
Avatar billede chrisbookwood Nybegynder
14. september 2008 - 21:05 #19
Det skulle der jo så en helt ny funktion til for at lave, udover den linie der opretter eventen. Det er uden tvivl mere end de 4 linier jeg bruger til at skifte frem og tilbage med events'ne, ved hjælp af den event handler jeg bruger til alle events jeg arbejder med;)
Avatar billede olebole Juniormester
14. september 2008 - 21:07 #20
Det forstår jeg ikke
Avatar billede chrisbookwood Nybegynder
14. september 2008 - 21:07 #21
Det med ECMA 242 og '$' må du forklare nærmere - den event handler jeg bruger er en jeg fandt på en blog (i forbindelse med før nævnte konkurrence), som jeg så har bygget videre på og ændret nogen ting som jeg gerne vil have dem til at se ud. Men jeg har aldrig fattet hvad de '$' gør godt for:P
Avatar billede chrisbookwood Nybegynder
14. september 2008 - 21:08 #22
Det jeg mente var bare, at ved at lave det event-toggle-værk du snakkede om, ville der skulle bruges flere linier kode, end de 4 linier jeg bruger nu, til at slette og oprette de nødvendige events.
Avatar billede olebole Juniormester
14. september 2008 - 21:18 #23
Set denne ene handler på 'click':

function clickPhrase(e) {
    var oElm = getTarget(e);
    if (getAttribute("editing")!="yes") {
        var phrase = oElm.lastChild.nodeValue;
        while(oElm.lastChild) oElm.removeChild(oElm.lastChild);

        var edit = document.createElement('input');
        edit.setAttribute('type', 'text');
        edit.setAttribute('value', phrase);
        edit.className = 'text';
        var css = edit.style;
        css.width = "509px";
        css.fontSize = "12px";
        css.marginBottom = "9px";
        oElm.appendChild(edit);
        setAttribute("editing", "yes");
    } else {
        if (oElm.lastChild) {
            var id = oElm.getAttribute('id');
            var phrase = oElm.lastChild.value;
            while(oElm.lastChild) oElm.removeChild(oElm.lastChild);
           
            var savedPhrase = document.createTextNode(phrase);
            oElm.appendChild(savedPhrase);
           
            loadXMLRequest("POST", "update.php", "id="+id+"&phrase="+phrase, showMsg, false);
        }
        setAttribute("editing", "no");
    }
}
Avatar billede olebole Juniormester
14. september 2008 - 21:19 #24
ups ...  =)

function clickPhrase(e) {
    var oElm = getTarget(e);
    if (oElm.getAttribute("editing")!="yes") {
        var phrase = oElm.lastChild.nodeValue;
        while(oElm.lastChild) oElm.removeChild(oElm.lastChild);

        var edit = document.createElement('input');
        edit.setAttribute('type', 'text');
        edit.setAttribute('value', phrase);
        edit.className = 'text';
        var css = edit.style;
        css.width = "509px";
        css.fontSize = "12px";
        css.marginBottom = "9px";
        oElm.appendChild(edit);
        oElm.setAttribute("editing", "yes");
    } else {
        if (oElm.lastChild) {
            var id = oElm.getAttribute('id');
            var phrase = oElm.lastChild.value;
            while(oElm.lastChild) oElm.removeChild(oElm.lastChild);
           
            var savedPhrase = document.createTextNode(phrase);
            oElm.appendChild(savedPhrase);
           
            loadXMLRequest("POST", "update.php", "id="+id+"&phrase="+phrase, showMsg, false);
        }
        oElm.setAttribute("editing", "no");
    }
}
Avatar billede olebole Juniormester
14. september 2008 - 21:22 #25
Læg forøvrigt mærke til, hvormange opslag i event objektet, jeg sparer med var oElm = getTarget(e);

Hvorfor sætter du dimensioner på feltet, når du sætter en CSS-klasse? Style-objektet bør derudover tilgås direkte - ikke som en attribut på elementet
Avatar billede chrisbookwood Nybegynder
14. september 2008 - 21:24 #26
Ja ... så tænker jeg bare - er det smart at "lave" sine egne tags? (læs: editing)
Avatar billede chrisbookwood Nybegynder
14. september 2008 - 21:25 #27
Det med style i tagget er fordi jeg stadig arbejder på at fixe et problem der hedder at firefox ikke gider style edit-feltet når det er blevet oprettet, så jeg smed bare et hurtigt style på som en løsning, indtil jeg fik løst IE problemet.
Avatar billede chrisbookwood Nybegynder
14. september 2008 - 21:26 #28
-Og hvad var det med ECMA 242 og '$' du sagde? Hvad betyder '$' i javascript egentligt?
Avatar billede olebole Juniormester
14. september 2008 - 21:33 #29
- og hvad '$' angår, så er JavaScript underlagt ECMA's standard for scriptsprog - og som for tiden hedder ECMA 262. Denne standard reserverer '$' til maskingenereret kode. Med det forstås f.eks:

/(?:.*?)(bole)(?:.*?)/.test("olebolebum");
alert(RegExp.$1);

I de funktioner, du bruger, bliver '$' brugt som alm. bogstaver i den proprietære navngivning
Avatar billede roenving Novice
14. september 2008 - 21:35 #30
style er i javascript DOM-binding et objekt-property på et html-element og ikke en attribut, og så er det ret væsentligt, selvom der findes en cssText-ting i visse browsere (som nødvendigvis skal sættes meget forsigtigt, da den jo erstatter, præcis son en setAttribute jo vil gøre !-)

$ har i javascript ikke en egentlig betydning, og vil i mange tilfælde være gyldig til en hel del ting, men er i ECMA-script-rekommendationen reserveret til at bruges i 'maskin-genereret' kode, det bedste eksempel, jeg kender handler om matches i regExps:

var x = "Jeg er et kvaj";
var reg = /\s(e)/g;
var txt = x.replace(reg,"_$1")
alert(txt);
Avatar billede chrisbookwood Nybegynder
14. september 2008 - 21:38 #31
Så det vil sige jeg kan bruge reserverede ord som variabel navne, ved at sætte '$' foran?

Og som sagt - det style værk var kun midlertidigt indtil problemet var fikset, hvilket det er nu;)

Men hvad med det editing-tag? Er det smart at lave sine egne tag? Er det hundrede procent valid?
Avatar billede olebole Juniormester
14. september 2008 - 21:40 #32
Hvad CSS og FF angår, så virker denne kode fint hos mig  =)

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>TITLE</title>
<style type="text/css">
.text {
    background: red;
    font-size: 72px;
}
</style>
</head>
<body>

<div id="gnu"></div>
<script type="text/javascript">
var o = document.createElement("input");
o.setAttribute("type", "text");
o.className = "text";
document.getElementById("gnu").appendChild(o);
</script>

</body>
</html>
Avatar billede chrisbookwood Nybegynder
14. september 2008 - 21:41 #33
ja, det gør det også nu. Det var som sagt fordi jeg satte class-tagget ved brug af setAttribute at det ikke virkede;)
Avatar billede olebole Juniormester
14. september 2008 - 21:41 #34
"Så det vil sige jeg kan bruge reserverede ord som variabel navne, ved at sætte '$' foran?" >> Nej, det har du helt misforstået. Men i princippet kan du jo sette et hvilket somhelst bogstav foran et reserveret ord - for så er det jo et andet ord  =)
Avatar billede olebole Juniormester
14. september 2008 - 21:43 #35
'$' er desværre kommet på mode blandt visse kodere som begyndelsesbogstav på funktionsnavne - men det er ikke nogen særlig god idé, da '$' er reserveret til anden brug
Avatar billede chrisbookwood Nybegynder
14. september 2008 - 21:44 #36
Hmm så tror jeg ikke helt jeg forstod, nej ... Men hvad med det editing-tag? Er det helt legalt?
Avatar billede roenving Novice
14. september 2008 - 21:46 #37
Så længe du konstituerer det fra javascript, kan du sætte hvilkensomhelst property/attribut på et html-element ...
Avatar billede olebole Juniormester
14. september 2008 - 21:46 #38
Nej <editing></editing> er absolut invald kode - men <gnu:editing></gnu:editing> kan godt være valid kode
Avatar billede roenving Novice
14. september 2008 - 21:47 #39
xml ?-)
Avatar billede olebole Juniormester
14. september 2008 - 21:48 #40
Ja - under XHTML. Det er helt i orden, hvis det anvendte namespace defineres  =)
Avatar billede olebole Juniormester
14. september 2008 - 21:49 #41
- det er jo bl.a. dét, der vil gøre XHTML så fedt, når det engang i en fjern fremtid kommer til at virke  ;o)
Avatar billede roenving Novice
14. september 2008 - 21:51 #42
-- jeg manglede bare lige henvisningen !-)

-- og, ja, det vil f..... være fedt, at vi kan begynde at bruge en extended markup !o]
Avatar billede chrisbookwood Nybegynder
14. september 2008 - 21:51 #43
Men nu mente jeg mere et tag (læs: attribute) som i editing="";)
Avatar billede olebole Juniormester
14. september 2008 - 21:54 #44
Okay - en attribut er ikke et tag, så derfor forvirringen  =)

Du må ikke bruge en special attribut i dokumentets kode, med den må gerne sættes dynamisk  =)
Avatar billede roenving Novice
14. september 2008 - 21:55 #45
Du kan ikke bruge det direkte i en html-mark-up, men må gerne sæte det via javascript ...

-- til gengæld kan du selv i xhtml lave en namespace, der som olebole viser det, tillader en brug !-)

-- men xhtml -- når vi at blive pensionerede ?-)
Avatar billede chrisbookwood Nybegynder
14. september 2008 - 21:58 #46
Super, så er jeg mere rolig:P
Kan i så fortælle mig hvad brugen af $$ i min event-handlers gør godt for? ( http://www.smidsmid.dk/showoff.txt)
Avatar billede roenving Novice
14. september 2008 - 21:59 #47
Dobbelt misbrug ???
Avatar billede olebole Juniormester
14. september 2008 - 22:00 #48
Intet ... skift dem med 'xx'  =)
Avatar billede chrisbookwood Nybegynder
14. september 2008 - 22:01 #49
hmm, det virker ret dumt at de er der så:D
Avatar billede roenving Novice
14. september 2008 - 22:02 #50
Ja !-)
Avatar billede chrisbookwood Nybegynder
14. september 2008 - 22:18 #51
Nu er der så et andet problem - hvis du klikker i et edit felt efter at have "startet edit-mode" så vil både ie og ff komme med en fejl. Det prøvede jeg så at ordne med if(!oElm.lastChild) return; hvilket også virkede i alle browsere bortset fra ie, da ie  returnere event-target som HTMLInputElement ligemeget om du faktisk trykker på edit-feltet eller bare i selve div-element som input elementet ligger i.
Avatar billede olebole Juniormester
14. september 2008 - 22:29 #52
Er det så ikke bare:

function clickPhrase(e) {
    var oElm = getTarget(e);
    if (oElm.tagName.toLowerCase()!="div") return;
Avatar billede chrisbookwood Nybegynder
14. september 2008 - 22:32 #53
nej, for som sagt ser IE altid event-target som input feltet, ligegyldigt hvor i div'n du trykker.
Avatar billede olebole Juniormester
14. september 2008 - 22:38 #54
Den version, der ligger online nu, virker da fint
Avatar billede chrisbookwood Nybegynder
14. september 2008 - 22:40 #55
ikke hos mig - prøv at tryk på en sætning og så tryk i edit-feltet derefter, så skulle både FF og IE komme med en fejl.
Avatar billede olebole Juniormester
14. september 2008 - 22:47 #56
Prøv nu det, jeg foreslog
Avatar billede olebole Juniormester
14. september 2008 - 22:48 #57
"nej, for som sagt ser IE altid event-target som input feltet, ligegyldigt hvor i div'n du trykker." >> Nej, det er ikke korrekt. Det, jeg foreslog før, virker i hvertfald i IE (kan som sagt ikke teste i andet)
Avatar billede chrisbookwood Nybegynder
14. september 2008 - 22:52 #58
Ahh, nu har jeg identificeret insektet - IE tager margenen på et element med som en del af elementet, så hvis man trykker på margenen, er det det samme som at trykke på element. Og i så fald virker mit eksempel (if(!oElm.lastChild) return;) også perfekt... Det var da egentligt en dum opfattelse af elementer IE har -.-
Avatar billede olebole Juniormester
14. september 2008 - 22:58 #59
Tjaah ... IE og jeg har faktisk i denne sammenhæng samme opfattelse af W3C's box-model  =)
Avatar billede chrisbookwood Nybegynder
14. september 2008 - 23:05 #60
Jeg synes dog stadigvæk ikke at margnen faktisk er en del af emnet, men okay:P

Mange tak for hjælpen, ole - smider du ikke lige et svar?
Avatar billede roenving Novice
14. september 2008 - 23:49 #61
Til gengæld virker det almindelige rn- og cbs-tags !-)
Avatar billede olebole Juniormester
14. september 2008 - 23:50 #62
sorry - margins hører naturligvis ikke med til boksen  =)
Avatar billede olebole Juniormester
14. september 2008 - 23:50 #63
- og svaret  =)
Avatar billede olebole Juniormester
15. september 2008 - 01:27 #64
Tak for points  =)
Du kunne også skrive dette, som jeg nok ville foretrække (selvom jeg nok allerhelst ville foretrække en OOP-løsning):

    var editElm = null;
    var activeEdit = null;
    function clickPhrase(e) {
        var oElm = e.retInPhrase ? editElm.parentNode : getTarget(e);
        if (oElm.tagName.toLowerCase()!="div") return;
        if (!editElm) createInput();
        if (activeEdit) {
            var oPhrase = document.createTextNode(editElm.value);
            activeEdit.appendChild(oPhrase);
            activeEdit.removeChild(editElm);
            activeEdit = null;
        }
        if (!e.retInPhrase) {
            editElm.value = oElm.firstChild.nodeValue;
            oElm.removeChild(oElm.firstChild);
            oElm.appendChild(editElm);
            editElm.select();
            activeEdit = oElm;
        }
    }
    function returnInPhrase(e) {
        e = e ? e : event;
        if (e.keyCode==13) clickPhrase({retInPhrase:true});
    }
    function createInput() {
        editElm = document.createElement('input');
        editElm.setAttribute('type', 'text');
        editElm.className = 'text';
        addEvent(editElm, 'keyup', returnInPhrase);
    }
Avatar billede olebole Juniormester
15. september 2008 - 01:29 #65
- lidt mere 'sexy':

    function returnInPhrase(e) {
        if ((e?e:event).keyCode==13) clickPhrase({retInPhrase:true});
    }
Avatar billede olebole Juniormester
15. september 2008 - 01:49 #66
Oooops ... opdateringen var slet ikke med  =)


    function clickPhrase(e) {
        var oElm = e.retInPhrase ? editElm.parentNode : getTarget(e);
        if (oElm.tagName.toLowerCase()!="div") return;
        if (!editElm) createInput();
        if (activeEdit) {
            var phrase = editElm.value;
            var id = activeEdit.getAttribute('id');
            activeEdit.appendChild( document.createTextNode(phrase) );
            activeEdit.removeChild(editElm);
            activeEdit = null;
            loadXMLRequest("POST", "update.php", "id="+id+"&phrase="+phrase, showMsg, false);
        }
        else if (!e.retInPhrase) {
            editElm.value = oElm.firstChild.nodeValue;
            oElm.removeChild(oElm.firstChild);
            oElm.appendChild(editElm);
            editElm.select();
            activeEdit = oElm;
        }
    }
Avatar billede chrisbookwood Nybegynder
01. oktober 2008 - 15:15 #67
Det virker perfekt > smider du et svar?
Avatar billede olebole Juniormester
01. oktober 2008 - 16:15 #68
(14/09-2008 23:50:56) - men tak for points  ;D
Avatar billede chrisbookwood Nybegynder
01. oktober 2008 - 16:49 #69
Oh, crap:D
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Vi tilbyder markedets bedste kurser inden for webudvikling

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester

IT-JOB

Forsvarsministeriets Materiel- og Indkøbsstyrelse

IT-Sikkerhedsrådgiver til Cyberdivisionen i Hvidovre

Unik System Design A/S

QA Engineer

BEC Financial Technologies

Java software engineer (regular)