Necesito cambiar una página después de la carga.
La estructura fuente aquí:
<div id='content'> <h1>...</h1> <p>...</p> <h1>...</h1> <p>...</p> <h1>...</h1> <p>...</p> </div>Necesito reconstruirlo a este:
<div id='content'> <div> <div> <h1>...</h1> <div> <p>...</p> </div> </div> </div> <div> <div> <h1>...</h1> <div> <p>...</p> </div> </div> </div> <div> <div> <h1>...</h1> <div> <p>...</p> </div> </div> </div> </div>Aquí está mi algoritmo:
const createComplexNode = () => { const parentBlock = document.querySelector('#content') const parentContent = parentBlock.querySelectorAll('h1, p') if (parentContent.length === 0) return const mainNode = document.createElement('div') const titleNode = document.createElement('div') const bodyNode = document.createElement('div') mainNode.className = 'desc-container' titleNode.className = 'desc-head' bodyNode.className = 'desc-body' const indexes = getIndex(parentContent) console.log(parentContent[indexes.start]) titleNode.appendChild(parentContent[indexes.start]) for (let i = 1; i <= indexes.end; i++) { bodyNode.appendChild(parentContent[i]) } mainNode .appendChild(titleNode) .appendChild(bodyNode) parentBlock.appendChild(mainNode) return createComplexNode() } const getIndex = nodeList => { const indexes = { start: -1, end: -1, } const regex = new RegExp('h?') for (let i = 0; i < nodeList.length; i++) { if (regex.test(nodeList[i].localName) && indexes.start < 0) { indexes.start = i } if (nodeList[i].localName === 'p') { indexes.end = i break } } return indexes } Mi principal problema es aquí const parentContent = parentBlock.querySelectorAll('h1, p') .
Funciona bien, pero solo en el primer ciclo. Porque esta función captura todas las etiquetas en el nodo principal y también los elementos ya envueltos. Es debido a la recursividad infinita. ¿Cómo puedo prevenirlo?
Con algunas funciones de utilidad para consultar y crear elementos DOM, y el método .append() :
// DOM Utility functions: const EL = (sel, el) => (el || document).querySelector(sel); const ELS = (sel, el) => (el || document).querySelectorAll(sel); const ELNew = (tag, prop) => Object.assign(document.createElement(tag), prop); // Recreate DOM: const EL_content = EL("#content"); const ELS_h1 = ELS("h1", EL_content); ELS_h1.forEach(EL_h1 => { const EL_div_outer = ELNew("div", {className: "wrapper-outer"}); const EL_div_inner = ELNew("div", {className: "wrapper-inner"}); const EL_div_parag = ELNew("div", {className: "wrapper-parag"}); const EL_p = EL_h1.nextElementSibling; EL_div_outer.append(EL_div_inner); EL_div_inner.append(EL_h1, EL_div_parag); EL_div_parag.append(EL_p); EL_content.append(EL_div_outer); }); div { padding: 10px; background: rgba(0,0,0, 0.1); } <div id="content"> <h1>Title 1</h1> <p>Paragraph 1</p> <h1>Title 2</h1> <p>Paragraph 2</p> <h1>Title 3</h1> <p>Paragraph 3</p> </div>h1 dentro "#content" y haz un bucle con NodeList.prototype.forEach()p de h1 usando Element.nextElementSibling .ELNew ).append() para mover los elementos entre sí y reinsértelos en el "#content"El código es bastante mínimo, limpio y debe explicarse por sí mismo.