lo que estoy tratando de lograr es cuando divido el contenido interno de un elemento, obtengo cada elemento por separado, pero el elemento html debe ser 1 elemento en la división.
Por ejemplo:
<p id="name1" class=""> We deliver <span class="color-secondary">software</span> & <span class="color-secondary">websites</span> for your organization<span class="color-secondary">.</span> </p> Como en el ejemplo anterior, quiero hacer cualquier cosa dentro del elemento de matriz <span> 1 después de dividir el contenido interno de #name1 .
Entonces, en otras palabras, quiero que la matriz dividida se vea así:
[ 'we', 'deliver', '<span class="color-secondary">software</span>', '&', '<span class="color-secondary">websites</span>' ... etc. ] Actualmente esto es lo que tengo. Pero esto no funciona ya que ignora el texto dentro del elemento html y por lo tanto lo divide a la mitad del elemento. También me gustaría que fuera cualquier elemento html, y no solo limitado a <span> .
let sentence = el.innerHTML; // el being #name1 in this case let words = sentence.split(/\s(?=<span)/i);¿Cómo podría lograr esto con expresiones regulares? es posible? Gracias por cualquier ayuda.
Aquí hay una solución basada en DOMParser que analiza el HTML y luego itera sobre los elementos secundarios del nodo superior, insertando el HTML en la matriz de resultados si el nodo es un elemento, o dividiendo el texto en el espacio (si es un elemento de texto) y agregando esos valores a la matriz de resultados:
const html = `<p id="name1" class=""> We deliver <span class="color-secondary">software</span> & <span class="color-secondary">websites</span> for your organization<span class="color-secondary">.</span> </p>` const parser = new DOMParser(); const s = parser.parseFromString(html, 'text/html'); let result = []; for (el of s.body.firstChild.childNodes) { if (el.nodeType == 3 /* TEXT_NODE */ ) { result = result.concat(el.nodeValue.trim().split(' ').filter(Boolean)); } else if (el.nodeType == 1 /* ELEMENT_NODE */ ) { result.push(el.outerHTML); } } console.log(result);Los detalles se comentan en el ejemplo a continuación.
const nodeSplitter = (mainNode) => { let scan; /* Check if initial node has text or elements */ if (mainNode.hasChildNodes) { scan = /* Collect all elements, text, and comments into an array */ Array.from(mainNode.childNodes) /* If node is an element, return it... ...if node is text, use `.matchAll()` to find each word and add to array... .filter() any falsy values and flatten the array and then return it */ .flatMap(node => { if (node.nodeType === 1) { return node; } else if (node.nodeType === 3) { const rgx = new RegExp(/[\w\\\-\.\]\&]+/, 'g'); let strings = [...node.textContent.matchAll(rgx)] .filter(node => node).flat() return strings; } else { /* Otherwise, return empty array which is basically nothing since .flatMap() flattens an array as default */ return []; } }); } else { // Return if mainNode is empty return; } // return results return scan; } const main = document.getElementById('name1'); console.log(nodeSplitter(main)); <p id="name1" class=""> We deliver <span class="color-secondary">software</span> & <span class="color-secondary">websites</span> for your organization <span class="color-secondary">.</span> </p>