Avatar billede freesite Nybegynder
10. april 2012 - 23:08 Der er 2 kommentarer

dynamisk tilføjelse af dom-element

Hej Eksperter


Jeg har 2 div elementer som opdateres på baggrund af indtastning i 2 input's elementer, dvs. forslag til indtastning input felt vises i div element.

Disse elementer skal virke parvis uafhængigt af hinanden. Koden er dog skrevet så der nemt kan tilføjes flere felter.

Koden virker også fint når kun et objekt er oprettet, ligegyldigt hvilket.

Enten
    //-- Load hint for place 2
    url = 'jshandle/xmlP.hint.php?q=';
    var hint_obj2 = new Hint(url,'dom_hint_field2','field2');
    function load_hint_func2(str){
        hint_obj2.load(str);
    }

eller

    //-- Load hint for place 2
    url = 'jshandle/xmlP.hint.php?q=';
    var hint_obj2 = new Hint(url,'dom_hint_field2','field2');
    function load_hint_func2(str){
        hint_obj2.load(str);
    }

kan være indkommenteret, men ikke begge på samme tid. Når begge er indkommenteret vises indhold altid i 'dom_hint_field2','field2' som defineret i det object der er oprettet sidst.

Tror problemet opstår ved måden Dom-objektet defineres, kan dog ikke lige komme på en bedre metode.


Håber nogen kan hjælpe med at finde fejlen...



Koden ser ud som følger.

<head>
<script language="javascript" type="text/javascript">
    //-- Load hint for place 1
    url = 'jshandle/xmlS.hint.php?q=';
    var hint_obj1 = new Hint(url,'dom_hint_field1','field1');
    function load_hint_func1(str){
        hint_obj1.load(str);
    }

    //-- Load hint for place 2
    url = 'jshandle/xmlP.hint.php?q=';
    var hint_obj2 = new Hint(url,'dom_hint_field2','field2');
    function load_hint_func2(str){
        hint_obj2.load(str);
    }

   
    //-- Load the place ----
    function Hint(url, divHintDist, divDist){
        if (window.XMLHttpRequest){// code for IE7+, Firefox, Chrome, Opera, Safari
              xmlhttp=new XMLHttpRequest();
          }
        else{// code for IE6, IE5
              xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
          }
        xmlhttp.onreadystatechange=function(){
              if (xmlhttp.readyState==4 && xmlhttp.status==200){
                  x=xmlhttp.responseXML.documentElement.getElementsByTagName("item");
                div = document.getElementById(divHintDist);
                div.innerHTML='';
                if(x.length>0){
                      for (i=0;i<x.length;i++){
                          var text = x[i].firstChild.nodeValue;
                        var p = document.createElement('p');
                        p.appendChild(document.createTextNode(text));
                          p.className='hint';
                          p.onclick =  function(text) {return function(){
                              document.getElementsByName(divDist)[0].value=text;
                              document.getElementById(divHintDist).style.display="none";
                          };}(text);
                          div.appendChild(p);
                      }
                    div.style.display="block";
                }
                else
                    div.style.display="none";
            }
        }
        //-- Load hint ---
        this.load = function(str){
            if (str.length==0){
                document.getElementById(divHintDist).style.display="none";
                  return;
            }
            xmlhttp.open("GET",url+str,true);
            xmlhttp.send();
        }
    }

</script>
</head>


<body>
    <div class="formcontent">
        <input class='inputfield' type='text' name='field1' style="width: 200px;" onkeyup="load_hint_func1(this.value);"  autocomplete="off"  value=""/>
        <div id="dom_hint_field1" class="hint" style="width:200px; display:none"></div>
    </div>                       
    <div class="formcontent">
        <input class='inputfield' type="text" name="field2" style="width:320px;" onkeyup="load_hint_func2(this.value);"  autocomplete="off" value=""/>
        <div id="dom_hint_field2" class="hint" style="width:320px; display:none"></div>
    </div>   
</body>
Avatar billede olebole Juniormester
10. april 2012 - 23:43 #1
<ole>

Prøv at uploade et eksempel, så vi kan teste.

Derudover er det ikke en særlig god kode, du har skruet sammen. Den lægger op til adskillige memory leaks. Du må aldrig bruge XHR-objektets navn (xmlhttp) indenfor readystatechange handleren. Her skal der refereres til objektet med this.

Derudover sætter man ikke event handlers på den måde. De skal tilføjes med addEventListener eller attachEvent. Når elementet nedlægges igen, skal handleren fjernes igen med removeEventListener eller detachEvent. Ellers bruger du bare mere og mere hukommelse.

I den forbindelse at notere sig, at du ikke bør fjerne elementer ved at overskrive innerHTML'en af det omkransende element. Det introducerer memory leaks. De skal fjernes med removeChild metoden.

At sætte feltets event handler inde i XHR-objektets event handler - og oven i købet bag dobbelt closure - lægger også voldsomt op til memory leaks.

Til sidst har din kode ikke så meget med 'rigtig' OOP at gøre.

Avanceret JavaScript/DOM er ikke helt ligetil  =)

/mvh
</bole>
Avatar billede freesite Nybegynder
11. april 2012 - 19:18 #2
Hej Ole

Mange tak for en meget detaljeret gennemgang samt beskrivelse af min kode.

>>Du må aldrig bruge XHR-objektets navn (xmlhttp) indenfor readystatechange handleren. Her skal der refereres til objektet med this.

Dette løste problemet. Jeg vender lige tilbage med koden, når jeg har rettet de øvrige punkter til.

Du må gerne smide et svar.
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