One effective method is to view the entire document as a string initially, and then re-parse it once modifications are complete.
The utilization of the .innerHTML
property acts as an HTML decompiler or compiler based on whether you are reading from or writing to it. For instance, if there are variables in the document that need replacing, you can execute:
let vars = {
msg: msg,
test_number: 10,
test_str: 'hello'
};
let htmlText = document.body.innerHTML;
// Locate each variable (assuming format is {{var_name}})
// and substitute with its corresponding value:
for (let var in vars) {
let pattern = '\\{\\{\\s*' + var + '\\s*\\}\\}';
let regexp = new RegExp(pattern, 'g');
htmlText = htmlText.replace(regexp, vars[var]);
}
// Re-parse the modified HTML text to update the page
document.body.innerHTML = htmlText;
This approach efficiently implements the {{var}}
syntax. As long as the syntax is properly designed to prevent interference with HTML tags within the document, this method should work effectively.
There may be some performance drawbacks due to redrawing the entire page, but unless this action is constant (e.g., during animations), the impact would generally be minimal. It is advisable to benchmark the code for performance concerns.
An alternative technique involves solely processing text nodes to avoid unintended alterations to actual HTML tags. One way to achieve this is by creating a recursive descent parser. Because all nodes have a .childNodes
attribute and the DOM functions as a tree structure (non-cyclic), searching for the specified syntax throughout the entire DOM is feasible.
I will not provide a detailed code example for this process since it can become quite intricate, but the basic concept is outlined below:
const TEXT_NODE = 3;
let vars = {
msg: msg,
test_number: 10,
test_str: 'hello'
};
function walkAndReplace(node) {
if (node.nodeType === TEXT_NODE) {
let text = node.nodeValue;
// Implement necessary logic for handling text here.
// You can integrate the RegExp functionality from the earlier example
// for straightforward text substitutions. If new DOM elements like <span> or <a> are needed, remove
// the current node from its .parentNode, generate the required
// elements, and subsequently add them back to the .parentNode.
} else {
if (node.childNodes.length) {
for (let i = 0; i < node.childNodes.length; i++) {
walkAndReplace(node.childNodes[i]);
}
}
}
}
walkAndReplace(document.body);