Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
341 views
in Technique[技术] by (71.8m points)

javascript - Load a script using nodes included by another script

I need to make a web page with a lot of content. In order to be more efficient when modifying this content, I decided to put it in separate files and then include these files, following this tutorial: https://www.w3schools.com/howto/howto_html_include.asp.

For example one of these files may contain some clickable links to book descriptions, which are modal boxes. So I need to get them in a loading script to get these clickable links and make them trigger some events. But it seems this loading script is called before JavaScript gets the included nodes, even if I add an event listener after reading some threads (I tried to run it at 'DOMContentLoaded' or 'load') : document.getElementById or document.getElementsByClassName still returns null so it fails to define an onclick function. Let me show an example code:

script.js

function includeHTML()  { /* Some code replacing the div by some-content.html, which is : <a id="clickable">Hello</a> */}

var button = null

window.addEventListener('load', function()  {
  button = document.getElementById("clickable");
  button.onclick = function() { alert('Hello'); }
});

index.html

<!DOCTYPE html>
<html>
<head>
  <script type="text/javascript" src="script.js"></script>
</head>

<body>
  <p>Here is a trigger button : </p>
  <div include-html="some-content.html"></div>
  
  <script>includeHTML();</script>
</body>
</html>

On Firefox, this will fail on defining button.onclick as button is still null. Any idea on how to fix it?

Not only should I be adding links, but also modal boxes. Here is a script code, more complete, for what my guess was:

script.js

var boxNames = ["bibliography", "about", "book1", "book2" ];
var boxes = null /* Contains the boxes to be displayed */
var trigs = null /* Contains the trigger buttons for each box */
var close = null /* Contains the close buttons for each box */

function setTrigger(i) {
    trigs[i].onclick = function() { setBoxVisible(true, i); }
}

function setClose(i) {
    trigs[i].onclick = function() { setBoxVisible(false, i); }
}

function load() {
    boxes = new Array(4);
    trigs = new Array(4);
    close = new Array(4);
    for(var i = 0; i < boxNames.length; i++) {
        boxes[i]=document.getElementById(boxNames[i]+"-box");
        trigs[i]=document.getElementById(boxNames[i]+"-trig");
        close[i]=document.getElementById(boxNames[i]+"-close");
        setTrigger(i); setClose(i);
    }
}

window.onload = function() { load(); }

For the code of includeHTML(), you can have a look at the tutorial I shared, I copy/pasted.

I think this kind of function would be more elegant if dealing with such stuff, but I would need it to be launched once everything is loaded, as if I was running it manually.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Your code only added the event listener when the page was loading, likely before the link existed.

You need to delegate from the nearest static container.

Here in your code it is document

Give the link a class instead of ID and do

window.addEventListener('load', function(e) {
  document.addEventListener('click', function(e) {
    const tgt = e.target;
    if (tgt.classList.contains("clickable")) {
      e.preventDefault(); // because it is a link
      alert('Hello');
    }
  });
});
<a class="clickable" href="#">Click</a>

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...