Warm tip: This article is reproduced from stackoverflow.com, please click
html javascript

How to use .innerHTML in template element

发布于 2020-03-29 21:03:10

I'm making an app with a framework that uses templates in HTML pretty heavily. It was all going well until I bumped into this problem:

Uncaught TypeError: Cannot read property 'querySelector' of null

correct me if I'm wrong, but I think this has to do with my code itself using templates and JavaScipt not being able to read the inside of that template.

Here's a minature version of my code which I am experiencing errors with.

HTML

<template id="main.html">
     <p id="paragraph">This text needs to be changed in 
     JS</p>
     <button onclick=example()>Click ME!</button>
</template>

JavaScript

 function example (){
 document.getElementById("paragraph").innerHTML = "This text has been changed!"}

Error:

 Uncaught TypeError: Cannot read property 'innerHTML' 
 of null

Is there any way of avoiding this error?

Questioner
Ved Tiwari
Viewed
15
O'Niel 2020-02-05 01:08

1) Template-element content is not rendered by default

You can re-use the content in a template-element as many times as you want, but you need to manually specify that using Javascript. If you don't use any Javascript to render your template-element it won't be visible in the DOM. Resulting in your code not finding the paragraph (which is in the template-element).

2) Make sure you call your Javascript after the DOM is loaded

A web-page gets loaded from top to bottom. If you don't place your Javascript-code on the bottom of your body tag, or manually say it needs to be loaded after the DOM is ready, your code tries to find an element before that element even exists.

3) Your code has small mistakes like missing paragraphs etc.

Fix that using a good editor.

This example code shows you how it can be done:

Javascript:

function example() {
    document.getElementById("paragraph").innerHTML = "This text has been changed!";
}


function init() {
    //Get the template-element by id
    let mainTemplate = document.getElementById("main");
    //Create a new div-element to hold template content
    let parent = document.createElement("div");

    //IMPORTANT!
    //Cloning template content into HTML DOM so it's visible.
    //This part - content.cloneNode - makes your template content visible after being appended to the body, or another legal element in the DOM.
    parent.append(mainTemplate.content.cloneNode(true));

    //Append to body
    document.body.append(parent);
}   

//After dom is ready: Launch init function
document.onload = init();

HTML:

<template id="main">
     <p id="paragraph">This text needs to be changed in 
     JS</p>
     <button onclick="example()">Click ME!</button>
</template>

Working JSFiddle: https://jsfiddle.net/ovc1mrs2/

You probably want to append the content of your template directly to the body, or to another element.