Toon posts:

[JS] IE setAttributeNode('event') problemen

Pagina: 1
Acties:

Verwijderd

Topicstarter
Voor m'n site lees ik de navigatie uit een XML-bestand.

In Mozilla/Firefox gaat alles perfect, maar IE doet moeilijk, namelijk het geeft de rollovers niet weer als je over een menu-item gaat.

Na wat snel opzoekwerk ben ik tot de conclusie gekomen dat je in IE geen events kan toevoegen op een tag via de setAttributeNode() methode.
Nu heb ik wat zitten klungelen met attachEvent maar niets wil werken.

Weet er hier iemand een oplossing?


Er zijn 4 externe JS files:
- portfolio.js: verzameling van scriptjes, waaronder de rollovers
- xmlParser.js: script om een XML file te parsen
- slideMenuParser.js: script om uit de geparste XML het menu op te bouwen
- menus.js: animatie van de menus (waaronder het in en uitklappen van het slideMenu)

De eerste 3 worden in de head van de html file geladen, menus.js op het einde van de body.


Code:

slideMenuParser.js
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
////////////////////////////////////////////
//            XML Menu script            //
//----------------------------------------//
//                                        //
//----------------------------------------//
// Dubois Philip                          //
////////////////////////////////////////////



function addContent()
    {
    parseXml(escape('XML/SlideMenuItems.xml'));
    
    var oItems = oDomDoc.getElementsByTagName('SlideMenuItem');
    addItems(oItems);   
    }

function addItems(oItems)
    {
    var slideMenuContent = document.getElementById('slideMenuContent');
    
    for(var i=0; i < oItems.length; i++)
        {
        var oItem = oItems[i];
        clean(oItem);
        
        var div = document.createElement('div');
        var divClass = document.createAttribute('class');
        var a = document.createElement('a');
        var aId = document.createAttribute('id');
        var aClass = document.createAttribute('class');
        var href = document.createAttribute('href');
        var title = document.createAttribute('title');
        var onmouseover = document.createAttribute('onmouseover');
        var onmousemove = document.createAttribute('onmousemove');
        var onmouseup = document.createAttribute('onmouseup');
        var onmousedown = document.createAttribute('onmousedownr');
        var onmouseout = document.createAttribute('onmouseout');
        var aText = document.createTextNode(oItem.firstChild.firstChild.nodeValue);
        
        divClass.value = oItem.firstChild.nextSibling.nextSibling.firstChild.nodeValue;
        aId.value = 'slide' + oItem.lastChild.firstChild.nodeValue;
        aClass.value = 'slideMenuLink';
        href.value = oItem.firstChild.nextSibling.nextSibling.nextSibling.firstChild.nodeValue;
        title.value = oItem.firstChild.nextSibling.firstChild.nodeValue;
        onmouseover.value = 'hover(' + oItem.lastChild.firstChild.nodeValue + ',true)';
        onmousemove.value = 'hover(' + oItem.lastChild.firstChild.nodeValue + ',true)';
        onmouseup.value = 'hover(' + oItem.lastChild.firstChild.nodeValue + ',true)';
        onmousedown.value = 'hover(' + oItem.lastChild.firstChild.nodeValue + ',true)';
        onmouseout.value = 'hover(' + oItem.lastChild.firstChild.nodeValue + ',false)';
        
        a.setAttributeNode(aClass);
        a.setAttributeNode(href);
        a.setAttributeNode(title);
        
        a.setAttributeNode(onmouseover);
        a.setAttributeNode(onmousemove);
        a.setAttributeNode(onmouseup);
        a.setAttributeNode(onmousedown);
        a.setAttributeNode(onmouseout);
        
        a.appendChild(aText);
        div.setAttributeNode(divClass);
        div.appendChild(a);
        slideMenuContent.appendChild(div);
        }
    }


portfolio.js
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
// Locatie van de afbeeldingen om te preloaden
var urlImages = new Array();
urlImages[0] = 'images/home.gif';
urlImages[1] = 'images/profiel.gif';
urlImages[2] = 'images/algemeen.gif';
urlImages[3] = 'images/ci.gif';
urlImages[4] = 'images/mct.gif';
urlImages[5] = 'images/mm.gif';
urlImages[6] = 'images/wt.gif';
urlImages[7] = 'images/netwerk.gif';
urlImages[8] = 'images/office.gif';
urlImages[9] = 'images/support.gif';
urlImages[10] = 'images/cv.gif';
urlImages[11] = 'images/show.gif';
urlImages[12] = 'images/contact.gif';
urlImages[13] = 'images/links.gif';
urlImages[14] = 'images/Terug_hover.gif';
urlImages[15] = 'images/Portfoliov2b_01_hover.gif';
urlImages[16] = 'images/vxhtml10.gif';
urlImages[17] = 'images/vcss.gif';


// <- Preload ->
function initPreload()
    {
    var images = new Array();
    if(document.images)
        for(var i = 0; i < images.length; i++)
            images[i] = newImage(urlImages[i]);
    }

function newImage(urlImage)
    {
    if(document.images)
        {
        img = new Image();
        img.src = urlImage;
        return img;
        }
    }
// <- Preload end ->



// <- Rollover ->
function hover(img, status)
    {
    var imgSrc = 'images/Logo.gif';
    
    if(status)
        imgSrc = urlImages[img];
    
    document.getElementById('LogoImg').src = imgSrc;
    }

[ Voor 37% gewijzigd door Verwijderd op 14-08-2006 19:33 ]


  • crisp
  • Registratie: Februari 2000
  • Laatst online: 13:05

crisp

Devver

Pixelated

eventhandlers zijn in feite geen HTML attributen in de zin dat ze CDATA bevatten; ze bevatten script of een referentie naar een functie. Derhalve zijn de methods createAttribute en setAttribute niet voor deze properties bedoelt, daar zijn namelijk eventhandlers voor:
JavaScript:
1
2
3
4
5
6
7
8
9
10
11
// DOM level 0:
element.onmouseover = functionref;
element.onmouseover = function() { doeiets(); }

// DOM level 2:
element.addEventHandler('mouseover', functionref, false);
element.addEventHandler('mouseover', function() { doeiets(); }, false);

// IE's brakke eventmodel:
element.attachEvent('onmouseover', functionref);
element.attachEvent('onmouseover', function() { doeiets(); });


Overigens doe je ontzettend veel DOM-traversing, maar uiteindelijk in je hover() functie doe je een regelrechte lookup. Dat kan m.i. veel netter, sneller en eenvoudiger (te beginnen met gebruikmaken van het 'this' keyword in je handlers)...
Je preload is ook niet echt effectief; je moet naar de src property van je preloaded image-object verwijzen; niet naar de stringvalue van de locatie.

[ Voor 22% gewijzigd door crisp op 14-08-2006 22:39 ]

Intentionally left blank


Verwijderd

crisp schreef op maandag 14 augustus 2006 @ 22:35:
eventhandlers zijn in feite geen HTML attributen in de zin dat ze CDATA bevatten; ze bevatten script of een referentie naar een functie. Derhalve zijn de methods createAttribute en setAttribute niet voor deze properties bedoelt, daar zijn namelijk eventhandlers voor:
Ter verduidelijking:
HTML:
1
<button onclick="melp();">

Is eigenlijk iets als:
JavaScript:
1
2
button = document.createElement('button');
button.onclick = new Function("melp();");

Ik gok dat als je voor veel verschillende elementen dezelfde function calls doet, het sneller is om met function references te werken in plaats van het in HTML attributen te zetten. Maar in praktijk zul je dat niet zo snel tegenkomen of nodig hebben.

  • crisp
  • Registratie: Februari 2000
  • Laatst online: 13:05

crisp

Devver

Pixelated

Voor Cheatah: ik zie je veel gebruik maken van de Function constructor, ook in situaties waar een function literal eigenlijk een betere keuze is aangezien deze eenmalig bij het parsen gecompileerd wordt itt de Function constructor waar de functie elke keer at runtime gecompileerd moet worden. Beide genereren een anonymous function, dus als de function-body statisch is kan je beter een literal gebruiken ;) (dat geldt overigens ook voor andere objecten zoals strings, numbers, regexps etcetera)

[ Voor 9% gewijzigd door crisp op 14-08-2006 22:51 ]

Intentionally left blank


Verwijderd

Topicstarter
crisp schreef op maandag 14 augustus 2006 @ 22:35:

Overigens doe je ontzettend veel DOM-traversing, maar uiteindelijk in je hover() functie doe je een regelrechte lookup. Dat kan m.i. veel netter, sneller en eenvoudiger (te beginnen met gebruikmaken van het 'this' keyword in je handlers)...
De rollover gebeurt niet over de link zelf, maar helemaal onderaan de site verandert het logo. Dus ik kan niet naar het triggerobject verwijzen om daar de image op te veranderen.


code:
1
2
button = document.createElement('button');
button.onclick = new Function("melp();");

This did the trick! Bedankt.
Ik had iets gelijkaardigs geprobeerd, nl.
code:
1
2
button = document.createElement('button');
button.onclick = melp();

Wat dus niet werkte :)

  • crisp
  • Registratie: Februari 2000
  • Laatst online: 13:05

crisp

Devver

Pixelated

Verwijderd schreef op maandag 14 augustus 2006 @ 23:48:
[...]


De rollover gebeurt niet over de link zelf, maar helemaal onderaan de site verandert het logo. Dus ik kan niet naar het triggerobject verwijzen om daar de image op te veranderen.
Als je dat element veel moet benaderen zou ik iig de referentie daarnaar cachen in een global javascript variabele.
code:
1
2
button = document.createElement('button');
button.onclick = new Function("melp();");

This did the trick! Bedankt.
Ik had iets gelijkaardigs geprobeerd, nl.
code:
1
2
button = document.createElement('button');
button.onclick = melp();

Wat dus niet werkte :)
Lees ook even mijn stukje hierboven over function literals en de Function constructor ;)

Intentionally left blank


Verwijderd

crisp schreef op maandag 14 augustus 2006 @ 22:49:
Voor Cheatah: ik zie je veel gebruik maken van de Function constructor, ook in situaties waar een function literal eigenlijk een betere keuze is aangezien deze eenmalig bij het parsen gecompileerd wordt itt de Function constructor waar de functie elke keer at runtime gecompileerd moet worden. Beide genereren een anonymous function, dus als de function-body statisch is kan je beter een literal gebruiken ;) (dat geldt overigens ook voor andere objecten zoals strings, numbers, regexps etcetera)
Ik gebruik de Function constructor zelf eigenlijk nooit, maar het helpt vaak om uit te leggen wat er eigenlijk met de on... attribute values gebeurt. Die worden in principe gebruikt als argument voor de Function constructor. Ik hoopte eigenlijk dat iedereen wel in zou zien dat het overal neerplanten van new Function niet zo handig is ;)
Nee, ik houd het zelf bij het definieren van functies in een los javascript bestand. En dan krijg je dus:
JavaScript:
1
2
button = document.createElement('button');
button.onclick = melp;

  • crisp
  • Registratie: Februari 2000
  • Laatst online: 13:05

crisp

Devver

Pixelated

Een functie-referentie is inderdaad nog beter :)

Intentionally left blank

Pagina: 1