Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JavaScript: Replace html string from json file (no jQuery)

The texts.json:

[{
  "PageTextKeyId": 1,
  "PageTextKeyName": "page-first-text",
  "PageTextValueName": "Lorem ipsum dolor sit amet"
}, {
  "PageTextKeyId": 2,
  "PageTextKeyName": "after-page-first-text",
  "PageTextValueName": "Consectetuer adipiscing elit"
}, {
  "PageTextKeyId": 3,
  "PageTextKeyName": "third-text-on-json",
  "PageTextValueName": "Sed diam nonummy nibh"
}, {
  "PageTextKeyId": 4,
  "PageTextKeyName": "this-is-the-forth",
  "PageTextValueName": "Euismod tincidunt ut laoreet"
}, {
  "PageTextKeyId": 5,
  "PageTextKeyName": "last-text-from-the-file",
  "PageTextValueName": "Dolore magna aliquam erat volutpat"
}]

The index.html:

<!DOCTYPE html>
<html>
    <head>
        <title>Text from JSON</title>
        <meta charset="UTF-8">
        <meta name="format-detection" content="telephone=no">
        <meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
    </head>
    <body>
        <div id="container" class="some-class">
            <p>[page-first-text] - [page-first-text]</p>
            <div id="creatives">
                <b>[after-page-first-text]</b>
                <div>
                    <span>
                        <i>[third-text-on-json]</i>
                    </span>
                </div>
            </div>
            <div class="holder">
                <div id="sfc">
                    <div id="designer">
                        <a href="#">[this-is-the-forth]</a>
                    </div>
                    <div id="developer">
                        <div>
                            <div class="designer-class">
                                <a href="#">
                                    <span>[last-text-from-the-file]</span>
                                </a>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
            <script src="script.js" ></script>
        </div>
    </body>
</html>

This is just a sample html, it can also have lot's of [text-here] in a DOM without id or class.

The script.js:

(function() {
    var jsonRequest = new XMLHttpRequest();
    jsonRequest.open('GET', 'texts.json');
    jsonRequest.setRequestHeader("Content-Type", "application/json");
    jsonRequest.onload = function() {
        var jsonContent = JSON.parse(jsonRequest.responseText);

        /* NEED HELP HERE */

    }
    jsonRequest.send();
})();

I would like to replace the html string that starts & ends with "[" & "]" with the value inside the json file on-the-fly (only when I view the page on browser) not permanently.

Example output on browser:

...
   <body>
        <div id="container">
            <p>Lorem ipsum dolor sit amet</p>
            <div id="creatives">
                <b>Consectetuer adipiscing elit</b>
                <div>
                    <span>
                        <i>Sed diam nonummy nibh</i>
                    </span>
                </div>
            </div>
            <div id="holder">
                <div id="sfc">
                    <div id="designer">
                        <a href="#">Euismod tincidunt ut laoreet</a>
                    </div>
...

I was hoping for maybe a regex solution, something like:

var everyDom = document.getElementsByTagName('*');
for (var i=0; i<everyDom.length;i++) {
    /*
    check with regex if dom value starts with "[" and end with "]"
    if true replace value with json value from key-name
    else go and look for other doms
    */
} 
like image 500
Neo Genesis Avatar asked Feb 22 '26 04:02

Neo Genesis


1 Answers

Thanks to alex for the matchText function.

I would like to suggest the following key-value object format as your JSON data. It will be simpler, fast and uses less network bandwidth.

You can use this function to convert your data to a key-value object format.

var map = {};
data.map(function(d) {
  map[d.PageTextKeyName] = d.PageTextValueName;
});

Please see this jsFiddle

// parsed JSON data from response
var map = {
    "page-first-text": "Lorem ipsum dolor sit amet",
    "after-page-first-text": "Consectetuer adipiscing elit",
    "third-text-on-json": "Sed diam nonummy nibh",
    "this-is-the-forth": "Euismod tincidunt ut laoreet",
    "last-text-from-the-file": "Dolore magna aliquam erat volutpat"
};

// find matching text in given nodeand apply the callback for replacement
var matchText = function(node, regex, callback, excludeElements) {
  excludeElements || (excludeElements = ['script', 'style', 'iframe', 'canvas']);
  var child = node.firstChild;
  do {
    switch (child.nodeType) {
      case 1: // other html elements
        if (excludeElements.indexOf(child.tagName.toLowerCase()) > -1) {
          continue;
        }
        // iterate next element
        matchText(child, regex, callback, excludeElements);
        break;
      case 3: // TextNode
        child.data = child.data.replace(regex, callback);
        break;
    }
  } while (!!(child = child.nextSibling));
  return node;
};

matchText(document.body, /\[(.*?)\]/gi, function(match) {
  var key = match.substring(1, match.length-1);
  return (!!map[key]) ? map[key] : match;
});

Explanation.

matchText function iterates the children of given node from firstChild and its siblings(via nextSibling ).

When the NodeType is an Html Element (case 1), it calls matchText to iterate node recursively.

When the NodeType is a TextNode (case 3), it calls the callback function to replace the matching string.

/\[(.*?)\]/gi is a RegExp to find anything that starts from a '[' up to ']'.

like image 190
Sen Jacob Avatar answered Feb 24 '26 16:02

Sen Jacob



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!