2008-12-05 9 views
5

Ich habe zwei Funktionen erstellt erweiterten Ansichten eines Monats im Archiv Abschnitt meines Blogs zu laden, wenn es Link ist angeklickt wird:Funktioniert getElementById mit Elementen, die mit Javascript erstellt wurden?

// Load open view of a month in the Archive section 
function loadMonth(date) { 
    // Remove other open month 
    removeMonth(); 

    // Hide opening month's link 
    // Define variable to hold month anchor tag 
    var monthLink = document.getElementById(date); 
    monthLink.style.display = "none"; // Hide month anchor 

    // Define new open month node and its attributes 
    var openMonth = document.createElement("div"); 
    openMonth.setAttribute("id", "openMonth"); 
    openMonth.innerHTML = "Testing one, two, three."; 

    // Insert open month 
    // Define a variable to hold the archive Div node 
    var archive = document.getElementById("archive"); 
    // Insert the open month in the archive node before it's link 
    archive.insertBefore(openMonth,monthLink); 

    return; 
    } 


// Close full view of a month and replace with respective link 
function removeMonth() { 

    // Define global function vars 
    var archive = document.getElementById("archive"); // Define a var to hold the archive Div node 
    var openMonth = document.getElementById("openMonth"); // Define var to hold the open month Div node 

    // Get date of full view month for replacement anchor tag where ID = date 
    var month = openMonth.getElementsByTagName("span")[0].innerHTML; // Define var to hold the name of the open month 
    var date = (new Date(month + " 15, 2008").getMonth() + 1); // Define var to hold the numerical equivalent of the month 
    var year = archive.getElementsByTagName("h3")[0].innerHTML.split(" "); // Define var to hold the year being displayed in the archive 
    date = year[1] + "" + date; // Change date var to string and insert year 

    // Remove the open month 
    archive.removeChild(openMonth); 

    // Show Link for that month 
    document.getElementById(date).className = "big"; // Fixes display error when anchor has class firstLink 
    document.getElementById(date).style.display = "inline"; // Returns link from display "none" state 
    return; 
} 

Die Funktionen, wenn sie auf den ursprünglichen statischen Inhalten, aber wenn ein zweiten laufen arbeiten Link wird im Archiv angeklickt, sie tun nichts. Ich frage mich, ob vielleicht, weil die Elemente, die von meinen Funktionen erstellt wurden, nicht von document.getElementById aufgerufen werden kann. Vielleicht sollte eine andere Methode zum Zugriff auf diese Knoten verwendet werden, oder vielleicht "Dokument" durch etwas ersetzen, das auch auf Javascript-Elementen funktioniert?

Jeder Rat würde sehr geschätzt werden. Vielen Dank.

+0

half Können Sie ein funktionierendes Beispiel für Code schreiben (zum Beispiel eines, das das Problem zeigt) irgendwo (zB hier http://pastebin.me/)? Wenn Sie Ihren Code betrachten, glaube ich, dass Ihr Ansatz ein allgemeines Missverständnis ist. – Tomalak

Antwort

3

Ihre wichtigste Frage zu beantworten: document.getElementByIdtut Arbeit mit dynamisch hinzugefügten Elemente.

In Ihrem Beispielcode erstellen Sie das openMonth-div und setzen es innerHTML. Dann in der Entfernen-Tag Sie dies tun:

var month = openMonth.getElementsByTagName("span")[0].innerHTML; 

openMonth.getElementsByTagName("span") nicht existieren und wird eine Fehlermeldung angezeigt, weil es keine Spanne Elemente sind. Ich weiß nicht, ob das ein Fehler im Code ist oder ob es nur eine unvollständige Probe in der Post ist.

+0

Sie haben absolut recht! Um ehrlich zu sein, war ich in meinem Code nicht so weit gekommen. Ich bin neu in Javascript und wusste nicht, dass das die ganze Funktion abwerfen würde. Ich danke dir sehr! – bloudermilk

5

sollten Sie sich gut mit:

openMonth.id = "openMonth"; 

getElementById() nur funktionieren kann, wenn das Element Teil des DOM ist, aber da Sie bereits insertBefore() verwenden ist dies lediglich eine Randnotiz.

Es gibt eine gemeinsame Quelle der Verwirrung beteiligt hier: Ein Attribut „id“ genannt wird, nicht unbedingt derjenige, die als Element-ID in der zugrundeliegenden DTD definiert ist. In deklarativem HTML werden sie automatisch verknüpft. Wenn Sie setAttribute() verwenden, sind Sie nicht mehr als das Erstellen eines Attributs namens "ID". Die Element-ID selbst ist über die Eigenschaft .id zugänglich.

bearbeiten

Die folgenden Werke für mich:

function test() 
{ 
    // create element, set ID 
    var p = document.createElement("P"); 
    p.innerHTML = "Look ma, this is a new paragraph!"; 
    p.id = "newParagraph"; 

    // make element part of the DOM 
    document.getElementsByTagName("BODY")[0].appendChild(p); 

    // get element by ID 
    var test = document.getElementById("newParagraph"); 
    alert(test.innerHTML); 
} 
+0

Leider hat das Ändern dieser Zeile das Problem nicht behoben. Nicht sicher, was Sie mit "getElementById() meinen, kann nur funktionieren, wenn das Element ein Teil des DOM ist ..." Ist das Objekt, das ich einfüge, Teil des DOM? Oder haben Sie gesagt, dass es nur eine Randnotiz ist ... – bloudermilk

+0

Gleich nachdem Sie ein Element erstellt haben, ist es nur * da *, nicht mit irgendetwas verbunden und für getElementById() unsichtbar. Sie müssen es dem DOM hinzufügen, um es sichtbar zu machen. Ich werde einen Testfall hinzufügen. – Tomalak

+0

Da Sie das Element "openMonth" mit insertBefore() zum Element "archive" hinzufügen, muss irgendwo ein zusätzlicher Fehler auftreten. Vielleicht ist das Archivelement selbst nicht Teil des Dokuments? – Tomalak

0

Eine andere Idee - Sie verwenden die ID 'openMonth' für verschiedene Elemente, vielleicht ist das ein Problem, auch wenn Sie das vorherige Element zuerst entfernen.

Sie könnten versuchen, eine Klasse anstelle von ID zu verwenden, oder Sie könnten eine globale Variable mit dem 'aktuelles Monatselement' halten.

0

Es funktioniert nur, wenn Sie beim Erstellen eine ID für das Element angeben. Ich erinnere mich, als ich creatin Elemente im laufenden Betrieb war, würde ich einen Zähler für die ID setzen oder wenn die Daten aus einer Datenbank abgerufen wurden, würde ich stattdessen die Zeilen-ID verwenden.

Ich würde das Element mit dem InnerHTML-Feld eines Elements erstellen und das Element als Text einfügen, dann würde die Rendering-Engine es von dort nehmen. Es ist nicht der beste Weg dies zu tun, aber es ist sehr schnell Ich bin in etwas Eile ...

Hoffnung, die