javascript - createdocumentfragment - ¿Hay alguna forma de encontrar un elemento en un documentFragment?
createdocumentfragment js (8)
NickFitz tiene razón, DocumentFragment
no tiene la API que esperas de Document
o Element
, en el estándar o en los navegadores (lo cual es una lástima, sería realmente útil poder establecer el innerHTML
un fragmento).
Incluso los marcos no lo ayudan aquí, ya que tienden a requerir que los nodos estén en el documento, o utilizan métodos en el nodo de contexto que no existen en los fragmentos. Probablemente deberías escribir el tuyo propio, por ejemplo:
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;
}
Seguramente sería mejor seguir las referencias a medida que avanzas 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
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?
No. La API DocumentFragment
es, como mínimo, mínima: no define propiedades ni métodos, lo que significa que solo admite las propiedades y métodos definidos en la API del Node
. Como los métodos tales como getElementById
se definen en Document
API , no se pueden usar con DocumentFragment
.
Qué pasa:
var oFra = document.createDocumentFragment();
var myDiv = document.createElement("div");
myDiv.id="myId";
oFra.appendChild(myDiv);
oFra.getElementById("myId"); //not in FF
A menos que hayas agregado el div
creado a tu fragmento de documento, no estoy seguro de por qué getElementById
lo encontraría.
--editar
Si está dispuesto a ejecutar su propia función getElementById, debería poder obtener la referencia que busca, porque 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);
Una fuente externa, que se muestra a continuación, mostró el siguiente fragmento de código:
var textblock=document.createElement("p")
textblock.setAttribute("id", "george")
textblock.setAttribute("align", "center")
Que muestra una forma diferente de configurar el parámetro de ID del objeto.
Todas estas respuestas son bastante antiguas, desde atrás cuando querySelectorAll
y querySelector
no estaban ampliamente disponibles. Cabe señalar que estas dos funciones que aceptan selectores de CSS como parámetros sí funcionan en DocumentFragment
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 querySelectorAll
o querySelector
.
Aquí hay 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 implementación debería usar primero la detección de objetos para ver si el navegador lo admite. Por ejemplo:
function getElementByIdInFragment(fragment, id) {
if (fragment.querySelector) {
return fragment.querySelector(''#'' + id);
} else {
// your custom implementation here
}
}
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/
Sin embargo, tienes la ventaja de crear el div con jQuery. Un poco hacky, pero funciona.
Mi DOM tiene un # fragmento de documento debajo de la etiqueta del elemento.
Esto es lo que estoy usando (usando jQuery), También tengo un caso de uso donde tengo el HTML DOM 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>]
La mejor manera de averiguar qué puede y qué no puede hacer con DocumentFragment
es examinar su prototipo:
const newFrag = document.createDocumentFragment();
const protNewFrag = Object.getPrototypeOf( newFrag );
console.log( ''£ protNewFrag:'' );
console.log( protNewFrag );
yo obtengo
DocumentFragmentPrototype {getElementById: getElementById (), querySelector: querySelector (), querySelectorAll: querySelectorAll (), prepend: prepend (), append: append (), hijos: Getter, firstElementChild: Getter, lastElementChild: Getter, childElementCount: Getter, 1 más ...}
... lo 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 te dirá que "el objeto no implementa la interfaz DocumentFragment"