1

I want to make a function that can do something like this :

HTML :

 <h1 class="demo">I am {{ name }}</h1>
 <span class="demo">{{ name }} learn JavaScript</span>

JS :

data(".demo", {
   name: "Arc"
};

Output :

 I am Arc
 Arc learn JavaScript

Can the data() function be made which can do this ? I don't want to use any external library for just using this function !

Debarchito
  • 1,305
  • 7
  • 20
  • Welcome to Stack Overflow! Please take the [tour] (you get a badge!) and read through the [help], in particular [*How do I ask a good question?*](/help/how-to-ask) Your best bet here is to do your research, [search](/help/searching) for related topics on SO, and give it a go. ***If*** you get stuck and can't get unstuck after doing more research and searching, post a [mcve] of your attempt and say specifically where you're stuck. People will be glad to help. – T.J. Crowder Oct 12 '19 at 10:38

1 Answers1

2

Use a regular expression to replace {{ .. }}s in the HTML with the appropriate value in the passed object, if there is one:

const data = (selector, obj) => {
  document.querySelectorAll(selector).forEach((elm) => {
    elm.textContent = elm.textContent.replace(
      /{{ *(\w+) *}}/g,
      // If key is in the obj, replace with the value
      // otherwise, replace with the match (make no changes):
      (match, key) => key in obj ? obj[key] : match
    );
  });
};

data(".demo", {
   name: "Arc"
});
 <h1 class="demo">I am {{ name }}</h1>
 <span class="demo">{{ name }} learn JavaScript</span>

If you also need to take into account nested elements, then select all text nodes of the parent, and do the same thing:

const getTextNodes = (parent) => {
    // https://stackoverflow.com/questions/2579666/getelementsbytagname-equivalent-for-textnodes
    var walker = document.createTreeWalker(
        parent, 
        NodeFilter.SHOW_TEXT, 
        null, 
        false
    );

    var node;
    var textNodes = [];

    while(node = walker.nextNode()) {
        textNodes.push(node);
    }
    return textNodes;
}

const data = (selector, obj) => {
  document.querySelectorAll(selector).forEach((elm) => {
    getTextNodes(elm).forEach((node) => {
      node.textContent = node.textContent.replace(
        /{{ *(\w+) *}}/g,
        // If key is in the obj, replace with the value
        // otherwise, replace with the match (make no changes):
        (match, key) => key in obj ? obj[key] : match
      );
    });
  });
};

data(".demo", {
   name: "Arc"
});
span > span {
  background-color: yellow;
}
<h1 class="demo">I am {{ name }}</h1>
 <span class="demo">{{ name }} learn JavaScript <span> nested {{ name }} </span></span>
CertainPerformance
  • 356,069
  • 52
  • 309
  • 320