Как отобразить данные между двойными скобками в наборе всех совпадений элементов без использования какой-либо библиотеки? - PullRequest
1 голос
/ 12 октября 2019

Я хочу создать функцию, которая может делать что-то вроде этого:

HTML:

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

JS:

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

Вывод:

 I am Arc
 Arc learn JavaScript

Можно ли создать функцию data (), которая может это сделать? Я не хочу использовать какую-либо внешнюю библиотеку для использования этой функции!

1 Ответ

2 голосов
/ 12 октября 2019

Используйте регулярное выражение для замены {{ .. }} s в HTML соответствующим значением в переданном объекте, если оно есть:

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>

Если вам также необходимо учесть вложенные элементы, выберите все текстовые узлы родительского элемента и сделайте то же самое:

const getTextNodes = (parent) => {
    // /2124767/getelementsbytagname-ekvivalent-dlya-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>
...