Andrew
Andrew

Reputation: 165

Loading HTML elements from template in separate file with jQuery

I want to build a web page by loading HTML elements from a separate file using jQuery.

Files I have:

index.html

   <!DOCTYPE html>
   <html lang="en">
   <head>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
   </head>
   <body>
     <script src="app.js"></script>
   </body>
   </html>

app.js

$.get("template.html",function(data) {
    let a = $(data).contents().clone()
    let b = a.find("#par1")
    a.html()
    $("body").append(b)   
 })

template.html

<template>       
    <div>
      <p id="par1">apple</p>
      <p id="par2">banana</p>
    </div>    
</template>

When I load index.html, par1 from template.html is loaded into the body, and the word apple is rendered. This is what I want, but I can't figure out why I need the line "a.html()" in app.js. If I comment it out, I get the error: "Uncaught TypeError: Cannot read property 'contains' of null" at the line with $("body").append(b). What is going on here?

Upvotes: 5

Views: 1169

Answers (2)

ROOT
ROOT

Reputation: 11622

Aside from what is right and what is wrong in your code, here is explanation of what is happening in your code.

The error you are having is caused by appending a none DOM element to the HTML body, so if you console.log(b, typeof b) it will log the following:

k.fn.init [p#par1, prevObject: k.fn.init(3)] "object"

So what is happening here is that your code, let a = $(data).contents().clone(); will create javascript object Array of your HTML tags, and assign it to a variable, then you are holding a reference to the array element in which it have the ID par1. and it is still an javascript Object, so when you call a.html() it will convert all a elements to Text and DOM elements, and b variable is holding a reference to one of those HTML elements, so that's why your code need a.html() or you can also have it like the following:

$.get("template.html",function(data) {
    let a = $(data).contents().clone();
    let b = a.find("#par1")
    $("body").append(b.html())   
 })

Upvotes: 2

Juho Rutila
Juho Rutila

Reputation: 2478

Are you sure the a.html() is not the one rendering the "apple" to the body?

I tried this in the here: https://codepen.io/BenKennish/pen/BtwEn

And the $(data).contents().clone() seems to be not working (so, b is empty). $(data).clone() on the other hand works.

I have no clear answer to your question other than that the list contents() returns is probably not something you can find() on.

Upvotes: 0

Related Questions