How I can get DOM-element if I had and @media() ... in the content of this element? This is something like custom template engine that I made.
For case below, I need an <article> Node and <time> Node, because upper on every of these nodes exists @media tag (one or more).
<div class="d-flex mt-20 vertical-around-flex">
@media(1080) mmw-400 mmh-300
@media(770) mmw-300
<article class="card bubble mmw-500 mmh-400">
@media(770) hide
<time>14 June, 2023</time>
</article>
</div>
@media(1080) mmw-400 mmh-300 connected to <article>
@media(770) mmw-300 connected to <article>
@media(770) hide connected to <time>
I need @media text and connected NODE element. Example structure:
{
ARTICLE_NODE: {
"media": "1080": {
"classes": ["mmw-400", "mmh-300"]
}
"media": "770": {
"classes": ["mmw-400", "mmh-300"]
}
},
TIME_NODE: {
"media": "770": {
"classes": ["hide"]
}
}
}
This is my code but it not working properly. This code return 6 Nodes, but I need 2 instead. Also, this code does not return me the @media text, only a HTML DomElement
const REGEX_MEDIA = new RegExp('@media\\((\\d+)\\)\\s(.+)\\n', 'gm');
const HTML = document.body.innerHTML;
console.log(
Array.prototype.slice.call(document.querySelectorAll('*')).filter(function(element) {
const match = element.outerHTML.match(REGEX_MEDIA);
if (match == null) {
return false;
}
if (match === void 0) {
return false;
}
return true;
})
)
>Solution :
No regexps needed. Just walk the node tree, look for text nodes that contain your @media tag and grab that value and the next sibling element (which is the "tagged" element).
Formatting the nodes from the example below to your object structure is left as a separate exercise.
const nodes = [];
function walkChildNodes(n) {
for (let c of n.childNodes) {
if (c.nodeType === 3) { // text node
const val = c.nodeValue.trim();
if (val.startsWith("@media")) {
nodes.push([val, c.nextSibling]);
}
} else {
if (c.hasChildNodes()) {
walkChildNodes(c);
}
}
}
}
walkChildNodes(document.body);
console.log(nodes);
<div class="d-flex mt-20 vertical-around-flex">
@media(1080) mmw-400 mmh-300 @media(770) mmw-300
<article class="card bubble mmw-500 mmh-400">
@media(770) hide
<time>14 June, 2023</time>
</article>
</div>