2009-10-29 29 views
15
var oFra = document.createDocumentFragment(); 
// oFra.[add elements]; 
document.createElement("div").id="myId"; 
oFra.getElementById("myId"); //not in FF 

¿Cómo puedo obtener "myId" antes de adjuntar el fragmento al documento?¿Hay alguna manera de encontrar un elemento en un documentFragment?

+3

Esta pregunta se realizó en 2009. __En 2012 tenemos querySelectorAll, que funciona en fragmentos de documento__. Vea la respuesta de @ Stephen a continuación. – mikemaccana

Respuesta

0

¿Qué hay de:

var oFra = document.createDocumentFragment(); 
var myDiv = document.createElement("div"); 
myDiv.id="myId"; 
oFra.appendChild(myDiv); 
oFra.getElementById("myId"); //not in FF 

A menos que haya añadido el del div creado a su fragmento de documento No estoy seguro de por qué getElementById lo encontraría?

--edit

Si usted está dispuesto a rodar su propia función getElemenById entonces usted debería ser capaz de obtener la referencia que está buscando, ya que este código funciona:

var oFra = document.createDocumentFragment(); 
var myDiv = document.createElement("div"); 
myDiv.id = "myId"; 
oFra.appendChild(myDiv); 
if (oFra.hasChildNodes()) { 
    var i=0; 
    var myEl; 
    var children = oFra.childNodes; 
    for (var i = 0; i < children.length; i++) { 
     if (children[i].id == "myId") { 
      myEl = children[i]; 
     } 
    } 
} 
window.alert(myEl.id); 
+0

Estaba tratando de evitar esa solución, ya que diseño un formulario de entrada de datos en el fragmento, agrego los eventos y los adjunto al documento. Funciona en IE. La razón parece que en el fragmento IE hereda del documento, pero en FF hereda del nodo (W3C) – pkario

+0

OK, pero si está compilando el formulario en JS, ¿por qué no mantener referencias a los elementos mientras los crea y utiliza? esas referencias para agregar los eventos? – robertc

+0

Hay muchos botones, cuadros de texto, combos, etc. en todas y cada una de las formas. Intento mantener los ID y minimizar las referencias al objeto dom cuando sea posible. Me conectaré primero y asignaré eventos más tarde. – pkario

7

n El DocumentFragment API es mínimo, por lo menos: no define propiedades ni métodos, lo que significa que solo admite las propiedades y métodos definidos en Node API. Como los métodos como getElementById se definen en Document API, no se pueden usar con un DocumentFragment.

+0

Aunque getElementById se define en Document API, no funcionará en un elemento recién creado que no esté conectado al dom. myObj.getElementById no funciona, mientras que myObj.getElementsByTagName funciona. – Olivvv

+2

@Olivvv: eso es de esperar: 'getElementById' es un método de' HTMLDocument' http://www.w3.org/TR/REC-DOM-Level-1/level-one-html.html#ID-36113835 , mientras que 'getElementsByTagName' es un método de' Document' http://www.w3.org/TR/REC-DOM-Level-1/level-one-core.html#i-Document y 'Element' http: //www.w3.org/TR/REC-DOM-Level-1/level-one-core.html#ID-745549614 Por lo tanto, 'getElementById' arrojará siempre una excepción cuando se intente invocarla sobre un objeto de tipo 'Elemento' si ese elemento está adjunto al DOM o no. – NickFitz

0

una fuente externa, se enumeran a continuación, mostraron el código siguiente fragmento:

var textblock=document.createElement("p") 
textblock.setAttribute("id", "george") 
textblock.setAttribute("align", "center") 

que muestra una forma diferente de configuración de parámetro ID del objeto.

Javascript Kit - Document Object Methods

7

NickFitz que es correcto, DocumentFragment no tiene la API que se espera de Document o Element, en el estándar o en los navegadores (que es una lástima, sino que sería muy útil para poder establecer una del fragmento innerHTML.

marcos Incluso no le ayuda aquí, ya que tienden a requerir nodos estén en el documento, o de otra manera utilizar métodos en el nodo de contexto que no existe en fragmentos. probablemente usted tiene que escribir el suyo propio, p. ej .:

function Node_getElementById(node, id) { 
     for (var i= 0; i<node.childNodes.length; i++) { 
      var child= node.childNodes[i]; 
      if (child.nodeType!==1) // ELEMENT_NODE 
       continue; 
      if (child.id===id) 
       return child; 
      child= Node_getElementById(child, id); 
      if (child!==null) 
       return child; 
     } 
     return null; 
} 

Casi con certeza sería mejor hacer un seguimiento de las referencias a medida que avanza que confiar en una función ingenua y de bajo rendimiento como la anterior.

var frag= document.createDocumentFragment(); 
var mydiv= document.createElement("div"); 
mydiv.id= 'myId'; 
frag.appendChild(mydiv); 
// keep reference to mydiv 
24

Todas estas respuestas son bastante antiguo, de cuando querySelectorAll y querySelector no estaban ampliamente disponibles. Cabe señalar que estas dos funciones que aceptan selectores CSS como parámetros funcionan en DocumentFragment s en los navegadores modernos, y deberían ser la forma preferida de abordar la situación en la pregunta. Las soluciones alternativas presentadas en algunas de las respuestas serían un buen enfoque para los navegadores heredados que no admitían querySelectorAll o querySelector.

Aquí es un ejemplo de uso:

var df = document.createDocumentFragment(); 
var div = document.createElement('div'); 
div.id = 'foo'; 
df.appendChild(div); 
var result = df.querySelector('#foo'); // result contains the div element 

Una buena aplicación debe utilizar primero la detección de objetos para ver si el navegador es compatible con esto.Por ejemplo:

function getElementByIdInFragment(fragment, id) { 
    if (fragment.querySelector) { 
     return fragment.querySelector('#' + id); 
    } else { 
     // your custom implementation here 
    } 
} 
+0

Estoy seguro de que hay otra forma, que recuperar un elemento de documentfragment. De todos modos ** perderás todo el beneficio **. –

1

Usando jQuery:

// Create DocumentFragment 
var fragment = document.createDocumentFragment(), 
    container = document.createElement('div'); 

container.textContent = 'A div full of text!'; 
container.setAttribute('id', 'my-div-1'); 
container.setAttribute('class', 'a-div-class'); 
fragment.appendChild(container); 

// Query container's class when given ID 
var div = $('<div></div>').html(fragment); 
console.log(div.find('#my-div-1').attr('class')); 

jsFiddle: http://jsfiddle.net/CCkFs/

Usted tiene la sobrecarga de crear el div con jQuery, sin embargo. Un poco hacky, pero funciona.

+0

$ ("

") .find (# my-div-1 ") funciona. Simplemente no puede buscar el nodo raíz. – Scott

0

Mi DOM tiene # document-fragment debajo de la etiqueta del elemento.

Esto es lo que estoy utilizando (usando jQuery), también tengo un caso de uso en el que tengo el DOM HTML en una cadena -

var texttemplate = $(filecontents).find('template').html(); 


$(texttemplate).children() 

     <p>​Super produced One​</p>​, 
     <appler-one>​</appler-one>, 
     <p>​Super produced Two​</p>, 
     <appler-two>​…​</appler-two>] 

$(texttemplate).html() 

       "<p>Super produced One</p> 
       <appler-one></appler-one> 
       <p>Super produced Two</p> 
       <appler-two> 
        <p>Super produced Three</p> 
        <appler-three></appler-three> 
       </appler-two>" 


$(texttemplate).find("appler-one") 

       [<appler-one>​</appler-one>​] 
0

La mejor manera, con mucho, para averiguar lo que puede y no se puede hacer con un DocumentFragment es examinar su prototipo:

const newFrag = document.createDocumentFragment(); 
const protNewFrag = Object.getPrototypeOf(newFrag); 
console.log('£ protNewFrag:'); 
console.log(protNewFrag); 

consigo

DocumentFragmentPrototype {getElemenById: getElementById(), querySelector: querySelector(), querySelectorAll: querySelectorAll(), prepend: prepend(), append: append(), los niños: Getter, firstElementChild: Getter, lastElementChild: Getter, childElementCount: Getter, 1 más ...}

... que me dice que puedo hacer cosas como:

const firstChild = newFrag.children[ 0 ]; 

PS esto no funcionará:

const firstChild = Object.getPrototypeOf(newFrag).children[ 0 ]; 

... se le informará que "el objeto no implementa la interfaz DocumentFragment"

Cuestiones relacionadas