2008-12-05 21 views
5

que he creado dos funciones para cargar vistas ampliadas de un mes en la sección de archivos de mi blog cuando llega el enlace se hace clic en:¿GetElementById funciona en elementos creados por javascript?

// 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; 
} 

Las funciones funcionan cuando se ejecuta en el contenido estático original, pero cuando un segundo se hace clic en el enlace en el enlace, no hacen nada. Me pregunto si tal vez porque los elementos que fueron creados por mis funciones no pueden ser llamados por document.getElementById. ¿Quizás debería usarse un método diferente para acceder a esos nodos, o quizás reemplazar el "documento" por algo que también funciona en los elementos creados por JavaScript?

Cualquier consejo sería muy apreciado. Gracias.

+0

Se puede publicar un ejemplo de trabajo de su código (un ejemplo que muestra el problema) en algún lugar (por ejemplo aquí http://pastebin.me/)? Al mirar su código, creo que hay un concepto erróneo general en su enfoque. – Tomalak

Respuesta

3

Para responder a su pregunta principal: document.getElementByIdhace trabajo con elementos añadidos de forma dinámica.

En su código de ejemplo está creando el div de openMonth y configurando su innerHTML. Luego, en la etiqueta de eliminación que está haciendo esto:

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

openMonth.getElementsByTagName("span") no existirá y se produce un error porque no hay elementos span. No sé si esto es un error en el código o si solo se trata de una muestra incompleta en la publicación.

+0

¡Tienes toda la razón! Para ser honesto, no había llegado tan lejos en mi código. Soy nuevo en Javascript y no me di cuenta de que arrojaría toda la función. Muchas gracias! – bloudermilk

5

que debe estar bien con:

openMonth.id = "openMonth"; 

getElementById() sólo puede funcionar si el elemento es parte de la DOM, pero dado que ya utiliza insertBefore() esto es simplemente una nota al margen.

Hay una fuente común de confusión en juego aquí: Un atributo llamado "id" no es necesariamente el que es definido como el ID de elemento subyacente en el DTD. En HTML declarativo, se vinculan automáticamente. Cuando usa setAttribute(), no es más que crear un atributo llamado "id". La ID del elemento en sí es accesible a través de la propiedad .id.

Edición

Los siguientes obras para mí:

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

Desafortunadamente, cambiar esa línea no solucionó el problema. No estoy seguro de lo que quiere decir con "getElementById() solo puede funcionar si el elemento es parte del DOM ..." ¿El objeto no está insertando parte del DOM? O es por eso que dijiste que era solo una nota al margen ... – bloudermilk

+0

Inmediatamente después de que creaste un elemento, está solo * allí *, no conectado a nada, e invisible a getElementById(). Debe agregarlo al DOM para hacerlo visible. Agregaré un caso de prueba. – Tomalak

+0

Dado que agrega el elemento "openMonth" al elemento "archive" utilizando insertBefore(), debe haber un error adicional en alguna parte. Tal vez el elemento de archivo en sí no es parte del documento? – Tomalak

0

Otra idea: está reutilizando la identificación 'openMonth' para diferentes elementos, quizás eso sea un problema incluso si elimina primero el elemento anterior.

Puede intentar usar una clase en lugar de una identificación, o puede mantener una variable global con el 'elemento de mes actual'.

0

Funciona solo si especifica una identificación para el elemento al crearlo. Recuerdo que cuando estaba creando elementos creativos sobre la marcha, establecía un contador para la identificación o si los datos se recuperaban de una base de datos, usaba la identificación de la fila en su lugar.

Crearía el elemento usando el campo innerHTML de un elemento e insertando el elemento como texto, luego el motor de representación lo tomaría desde allí. No es la mejor manera de hacerlo, pero es muy rápido, tienes un poco de prisa ...

esperanza de que ayudó

Cuestiones relacionadas