1

How do i display a text anywhere on a html page

I want to achieve something like this

Example

{{title}} // there will be more than one like this one

If something like this is available anywhere on the page it should display ​"This is the title" ​so if i change the “This is the title” the {{title}} should also change

I know don't know much about this but i guess this is possible with javascript

Yeshwanth B
  • 85
  • 10
  • 1
    Have you tried anything yet? Sounds like this is possible by just reading from an input and querying a bunch of document elements. – Ian H. Jun 17 '21 at 12:04
  • 1
    Where/how have you planned to change the text? – Teemu Jun 17 '21 at 12:04

1 Answers1

3

HTML

<div id="updatable">
  <q>{{QUOTE}}</q>
  <br>
  <h1>{{HEADING}}</h1>
  <p>
    My name is  {{NAME}}  and i am {{AGE}} yrs old . I love to play {{GAME}} and my hobbies include {{HOBBIES}} .
  </p>
</div>

JS

  class Template {

    constructor(element, obj) {
      this.element = element;
      this.state = obj;
    }

    initState = function () {
      this.element = document.querySelector(this.element);
      this.#setState();
    }

    #setState() {
      const obj = this.state;
      Object.entries(obj).forEach(pair => {
        this.element.innerHTML = this.element.innerHTML.replaceAll('{{'+ pair[0] +'}}', `<span data-var="${pair[0]}"> ${pair[1]} </span>`)
      })
    }

    updateState = function (obj) {
      Object.entries(obj).forEach(pair=> {
        let key = pair[0]
        let value = pair[1]
        this.state[key] = value;
      })
      let template_elements = document.querySelectorAll('[data-var]');
      template_elements.forEach(template_element => {
        let attr = template_element.getAttribute("data-var");
        template_element.innerText = this.state[attr];
      })

    }
  }


  const app = new Template("#updatable", {
    QUOTE: "Coolest person in world ? ya that's me  :-)",
    NAME: "sanmeet",
    GAME: "football",
    HEADING: "About Me",
    AGE: 19,
    HOBBIES: "Coding and doing cool stuff",
  });

  // Initialize the functionality
  app.initState()

  // Updating variables

  setTimeout(function() {
    app.updateState({
      GAME: "chess",
      HEADING: "Really about me ! "
    })
  }, 2000);
Sanmeet
  • 1,191
  • 1
  • 7
  • 15
  • 1
    @Yeshwanth B Does this cool answer solves your problem ? – Sanmeet Jun 17 '21 at 12:40
  • [Cooler, no innerHTML](https://jsfiddle.net/w6saq2et/1/) = ). – Teemu Jun 17 '21 at 20:09
  • I made some performance tests with 122kB of HTML and 400 placeholders to replace. Actually your code is almost twice faster than mine (`childNodes` as a live NodeList [eats the performance](https://stackoverflow.com/a/66480319)). The only advantage of my code seems to be, that it preserves the pre-attached event listeners. You can make your code even faster, see [innerText vs. textContent](https://kellegous.com/j/2013/02/27/innertext-vs-textcontent/). Overall, modern browsers are incredible fast, your code took ~12 msecs, my code took ~20 msecs to initialize the placeholders in my tests. – Teemu Jun 18 '21 at 07:26
  • Yes, indeed it's surprising. Though that was in FF only, in Chromium browsers the times were 20 msecs vs. 59 msecs, TextNode manipulation being faster. – Teemu Jun 18 '21 at 08:46
  • You're right. The task is actually interesting (not sure how usueful such a feature would be), and we both have learned something when creating our implementations and during the conversation here. – Teemu Jun 18 '21 at 09:04
  • @Teemu updated the code check it no span used for upadting the html ! Inspect it and then check whoo .... Me and curiosity can't wait for your response ! – Sanmeet Jun 18 '21 at 12:39
  • Thanks you guys i was not able to respond much quick this is amazing i am using a static website and i required a single name to be shows on multiple places it was hard to change everything manually by editing all the titles one by one and since there are going to be a lot of pages that would have been a problem once again thanks – Yeshwanth B Jun 18 '21 at 15:46
  • @Yeshwanth B Welcome ! But without Teemu's support I would have ended up in a small function ... btw you finally responded :-) – Sanmeet Jun 18 '21 at 16:11
  • I had a busy friday. It seems you've separated the concerns better in the new code. However, creating an instance should not have side effects, `constructor` should be a pure function. I'd consider a separate `init` method. Also, the eventlisteners are still vanishing. @YeshwanthB All this would be much more efficient, if you'd accept an element instead of the placeholder. Replacing placeholders in JS isn't how the DOM is designed to work. Writing `` instead of a placeholder shouldn't be unconscionable, and you could still apply the most of Sanmeet's code. – Teemu Jun 19 '21 at 07:47
  • @Teemu got the init one but how to event Listeners shulod I use` innerText or textContent ` since it is not replacing html but .... then what i wrote ( update one ) will be just of no use ! ... – Sanmeet Jun 19 '21 at 09:37
  • @Teemu sticking to first code ( not updated one ) and adding just init function ...all event listeners now works ! I my final answer ..let me know if it can be improved more – Sanmeet Jun 19 '21 at 10:07
  • `setState` will still remove all eventlisteners attached with `addEventListener`, if they're attached before this code runs. [I'd stick to elements](https://jsfiddle.net/xed6fr40/) instead of placeholders, it's just so much faster, and much more intuitive when manipulating the DOM. (The fiddle contains the very first version of the code, I'm sorry for the finnish text in the markup.) – Teemu Jun 19 '21 at 10:32
  • [Fixed a bug in the jsFiddle example](https://jsfiddle.net/xed6fr40/1/). – Teemu Jun 19 '21 at 10:50
  • @Teemu No doubt using placeholder is a pain whereas using an element its much better ..... but as in question I used placeholder....( THE FIDDLE it was really a big markup ).. Also i updated the code before did u checked ! btw thanks I learnt alot this time ! My question : why did you used some code like HTMLspanELEMENT one saying it must be placed in head I really don't understand what it was ! – Sanmeet Jun 19 '21 at 13:06
  • That class defines a custom HTML element, which inherits from HTMLSpanElement. Though I'm actually not sure, if it's needed at all, browsers can create custom elements without it too. But the element code in my work machine was impressive, it usually logged zero time consumed, which means everything was done within 1 msec. – Teemu Jun 19 '21 at 13:15
  • @Teemu Ok now I understand ! Why not you add that answer here now I think that's perfect ... Also thanks for improving my knowledge alot ... – Sanmeet Jun 19 '21 at 14:32
  • My code snippets are far from well-tested implementations, only some stabs into dark. Now I finally got Chrome at hands, I noticed, that the custom elements are not working in Chrome (works nicely in FF). Addtionally, I've VTC'd this question because it "_needs more focus_", I don't dare to answer a question which I've voted to close. But, these are fun exercises, answered or not, and I also have learned new things and got some ideas from the monkeypatching code (now removed) in your original answer. Now we really should stop commenting on this, if something still appears, please open a chat. – Teemu Jun 19 '21 at 15:02