Avatar billede kpdk Nybegynder
12. oktober 2009 - 02:38 Der er 9 kommentarer og
1 løsning

Kodeafvikling fejler i IE men virker i FF

Hej,

Jeg har et problem med et stykke hjemmebrygget javascript kode. Først og fremmest vil jeg tilføje at jeg er absolut på tynd is med javascript, hvilket også er en del af grunden til at jeg nu hører mig af her.

Koden virker - tilsyneladende - helt fint på Firefox (latest version) men i IE (8) fejler det miserabelt.

Basalt set har jeg en funktion som udskriver indhold til en udvalgt <label> baseret udfra funktions-parametre.

function outputClientMessage(objid, message, state)
{
    var formattedString;
   
    if (objid != null || objid.length > 0)
    {
        if (!message.length > 0)
        {
            formattedString = '<p class="objJSErrorMarker"><img src="gfx/warn.gif" height="16" width="16" alt="!" />No error message supplied</p>';
        }
   
        formattedString = ((state) ? '<p class="objJSErrorMarker"><img src="gfx/warn.gif" height="16" width="16" alt="!" />' + message + '</p>' : '<p>' + message + '</p>');
        document.getElementById(objid).innerHTML = formattedString;
    }
}

Ideen er så at mine andre "validator-funktioner" som foretager en meget simpel og overfladisk validering vil kalde den funktion hvis valideringen fejler. Objid er navnet (id) på den label der skal skrives til, message er beskeden som skal skrives og state er en boolsk indikator om der er en fejl eller blot en info besked.

Så vidt, så godt. Jeg troede at alt var godt da jeg primært bruger Firefox, men IE 8 piver over følgende:

document.getElementById(objid).innerHTML = formattedString;

Jeg har, som en sidenote, læst mig frem til på nettet at innerHTML tilsyneladende er deprecated og bør undgåes (dog umiddelbart lyder det til at folk er delt i to lejre på det udsagn).

Er der nogen der kan forklare mig hvor det går galt (og hvordan det rettes til så det virker i begge browsere) - og kan det gøres pænere (det er jeg overbevist om, det kan).


/kpdk
Avatar billede j4k0b Nybegynder
12. oktober 2009 - 08:24 #1
innerHTML er deprecated fordi folk gerne vil have dig til at arbejde med HTML som en DOM-struktur (alá XML). Det er der både fordele og ulemper i, men det kan jeg ikke forklare kort her.

Et eksempel til en løsning kunne være (koden er ikke testet men skulle give et billede af hvordan du kan gøre):


var paragraph = document.createElement('p');
var image = document.createElement('img');
var text = document.createTextNode(message);
var container = document.getElementById(objid);

image.src = 'gfx/warn.gif';
image.width = 16;
image.height = 16;

paragraph.class = 'objJSErrorMarker';
paragraph.appendChild(image);
paragraph.appendChild(text);

container.appendChild(paragraph);
Avatar billede TagMan101 Nybegynder
12. oktober 2009 - 10:13 #2
Prøv med .innerText i stedet og se om det gør dit liv bedre....

/T
Avatar billede kpdk Nybegynder
13. oktober 2009 - 04:40 #3
Jeg har tidligere leget med innerText, men den virker ikke i Firefox.

j4k0b, dit eksempel ser interessant ud men jeg synes ikke umiddelbart jeg kan få det til at gøre noget. Her er en lettere omskrevet funktion:

function outputClientMessage(obj, message, state)
{
    var s = document.createElement('span');
    var img = document.createElement('img');
    var text = document.createTextElement("Test: " + message);
    var target = document.getElementById(obj);
   
    img.src = 'gfx/warn.gif';
    img.width = 16;
    img.height = 16;
   
    s.class = 'objJSErrorMarker';
    s.appendChild(img);
    s.appendChild(text);
   
    target.appendChild(s);
}

Og så tester jeg den med at kalde den fra en anden funktion på eksempelvis følgende måde:

...
outputClientMessage("LblErrorHandler", "Dette er en test", true);
...

LblErrorHandler er ren html, defineret som:

<label id="LblComparisonErrorHandler"></label>


Firefox melder igen ikke fejl, men gør ikke noget. Jeg havde forventet at der var sket noget :-)

IE melder fejl og siger at "Id var ventet" til denne linie:
s.class = 'objJSErrorMarker';
Avatar billede j4k0b Nybegynder
13. oktober 2009 - 07:32 #4
Det er min fejl.

document.createTextElement

skal erstattes med:

document.createTextNode


Og så virker det :) Dog skal du også tage højde for at fjerne elementet igen, som er en af ulemperne i forhold til innerHTML. Gem en reference til objektet i en global variabel, og brug target.removeChild før du appender nyt (s)
Avatar billede ebusiness Nybegynder
13. oktober 2009 - 15:19 #5
Jeg kan ikke reproducere nogen fejl i den originale kode.

Det eneste jeg kan sige er at du bør droppe brugen af label elementer og gå over til div eller p elementer i stedet.

Der er en åbenlys fejl i det sidste stykke kode du har postet da du kalder din funktion med et id end det dit element har.

Omkring innerHTML, funktionen virker ganske glimrende, og er i øvrigt inkluderet i HTML5 http://www.w3.org/TR/html5/embedded-content-0.html#dom-innerhtml
Avatar billede kpdk Nybegynder
13. oktober 2009 - 17:32 #6
Hej igen,

Vedr. den åbenlyse fejl, så er det korrekt. Det var dog blot en fejl da jeg kopierede over. Min reelle up-to-date kode matchede id'et på det objekt :-)

Efter at have erstattet "document.createTextElement" med "document.createTextNode" virker det igen fint på Firefox, men jeg har stadig lidt små-problemer med at få IE til at rette ind til højre...

IE nægter stadig at acceptere:

s.class = 'objJSErrorMarker';

Hvis jeg sletter eller udkommenterer ovenstående linie, virker koden også i IE.

Har I nogen ide om hvad det er, som den er ked af?
Avatar billede j4k0b Nybegynder
13. oktober 2009 - 17:51 #7
kpdk: Det er mig der igen var lidt for hurtig

Prøv med:
s.className = 'objJSErrorMarker';

Beklager :-)
Avatar billede kpdk Nybegynder
13. oktober 2009 - 19:11 #8
Ah, ja så virker det straks :-)

Smid et svar for velfortjente point!

Et lille tillægsspørgsmål, om man må være så fri - hvis man (utilsigtet!) udfører valideringen flere gange (valideringen foretages når man trykker på en knap) vil den indsætte flere og flere enslydende besked - er der nogen nem måde at stoppe den så den kun laver én?

F.eks. giver 2x tryk på valideringsknappen 2x fejlbeskeder på skærmen, osv. Kan man på nogen måde se om et objekt (getElementById...) indeholder noget allerede eller skal man gå ad andre veje?

Med det sagt - så tusind tak for hjælpen, det var ganske uvurderligt :-)
Avatar billede kpdk Nybegynder
13. oktober 2009 - 19:18 #9
Jeg fik faktisk selv løst det sidste... :-)

Ved at bruge sit objekt kunne man fantastisk nok kalde getElementsByTagName samt angive det tag man vil ha' antallet af og så bare hive length egenskaben ud :-)
Avatar billede j4k0b Nybegynder
13. oktober 2009 - 19:30 #10
currClientMsgObj = null;

function hideClientMessage(obj)
{
    try {
        var target = document.getElementById(obj);
        target.removeChild(currClientMsgObj);
    } catch(e) {
    }
}

function outputClientMessage(obj, message, state)
{
    var s = document.createElement('span');
    var img = document.createElement('img');
    var text = document.createTextNode("Test: " + message);
    var target = document.getElementById(obj);
 
    img.src = 'gfx/warn.gif';
    img.width = 16;
    img.height = 16;
 
    s.className = 'objJSErrorMarker';
    s.appendChild(img);
    s.appendChild(text);

    // prøv at fjern uanset hvad
    hideClientMessage(obj);
    currClientMsgObj = s;
 
    target.appendChild(s);
}
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