/    Sign up×
Community /Pin to ProfileBookmark

Event Listener to dynamically loaded content

I have a main js file. I would like to keep all my JS inside this.

I’m also loading content via AJAX or FETCH into my index.php page.

I get errors for my event listeners as my DOM elements are not on the page when the page is loaded.

Is there a way around this? Loading my JS into my page content loaded with fetch does not seem to work either.

to post a comment
JavaScript

10 Comments(s)

Copy linkTweet thisAlerts:
@kiwisauthorJun 26.2020 — Even this script does not work

``<i>
</i>document.addEventListener("click", function(){
console.log( "Hello World!");
});<i>
</i>
``


I'm assuming it's being treated as text only. How can I get the JS within this page to run?
Copy linkTweet thisAlerts:
@SempervivumJun 26.2020 — 
  • 1. What error messages does the console output? At least your second script should work.

  • 2. Please post the complete code, HTML and JS, or better the URL of your site.

  • 3. Simple solution: Add the event listeners after the new content has been loaded.

  • 4. More sophisticated: Use event bubbling: Add an event listener to document and check the target in order to determine which element has been clicked:
    document.addEventListener("click", function(event){
    const id = event.target.id;
    if (id == 'id-to-be-clicked') {
    console.log( "#" + id + "has been clicked");
    });

    (jQuery made this a bit easier).
  • Copy linkTweet thisAlerts:
    @kiwisauthorJun 26.2020 — Okay here is mypage.php

    ``<i>
    </i> &lt;div class="container"&gt;
    &lt;span class="next" id="next"&gt;&lt;/span&gt;
    &lt;span class="prev" id="prev"&gt;&lt;/span&gt;
    &lt;div id="box"&gt;&lt;/div&gt;
    &lt;/div&gt;
    &lt;script&gt;
    document.getElementById("next").addEventListener("click", nextNum());
    document.getElementById("prev").addEventListener("click", prevNum());
    var numbers = document.getElementById('box');
    for ( var i=1.20, l=2.5; i&lt;l; i+=0.01 ){
    var span = document.createElement('span');
    span.textContent = i.toFixed(2);
    numbers.appendChild(span);
    }

    var num = numbers.getElementsByTagName('span');
    var index = 0;

    function nextNum(){
    num[index].style.display = 'none';
    index = (index + 1) % num.length;
    num[index].style.display = 'initial';
    }
    function prevNum(){
    num[index].style.display = 'none';
    index = (index - 1 + num.length) % num.length;
    num[index].style.display = 'initial';
    }

    &lt;/script&gt;<i>
    </i>
    `</CODE>
    Here's my JScode which includes this content from index.php

    <CODE>
    `<i>
    </i>document.getElementById("my-link").addEventListener("click", function(e){

    fetch('content/second.php')
    .then(function(response) {
    return response.text()
    })
    .then(function(html) {
    document.getElementById("content").innerHTML = html;
    })
    .catch(function(err) {
    console.log('Failed to fetch page: ', err);
    });

    });<i>
    </i>
    ``
    Copy linkTweet thisAlerts:
    @kiwisauthorJun 26.2020 — on it's own it works, when included it fails.
    Copy linkTweet thisAlerts:
    @SempervivumJun 26.2020 — Did your omit the script tags `&lt;script&gt;...&lt;/script&gt;` in the JS being included?

    And did your include the JS after the HTML?

    I can't find the ID "content" in your HTML?
    Copy linkTweet thisAlerts:
    @SempervivumJun 26.2020 — PS: Maybe I misunderstood something: When writing "on it's own it works, when included it fails." you don't mean the JS but the content being included by fetch, right?

    and mypage.php is the page that is included and inserted into index.php?
    Copy linkTweet thisAlerts:
    @SempervivumJun 26.2020 — PPS: Obviously javascript is not executed when inserted by innerHTML:

    https://stackoverflow.com/questions/2592092/executing-script-elements-inserted-with-innerhtml
    Problem is that the code inside the <script> tag doesn't get executed.[/quote]
    The solutions given there are fairly complex and I would recommend instead:

    Put the code for adding the event listeners into a function, define this function in index.php and call it after the content has been fetched and inserted into the container.
    Copy linkTweet thisAlerts:
    @daveyerwinJun 26.2020 — @kiwis80#1619936

    document.getElementById("next").addEventListener("click", nextNum());

    document.getElementById("prev").addEventListener("click", prevNum());

    should be ...

    document.getElementById("next").addEventListener("click", nextNum);

    document.getElementById("prev").addEventListener("click", prevNum);
    Copy linkTweet thisAlerts:
    @daveyerwinJun 26.2020 — @DaveyErwin#1619948

    working example here ...

    https://drivebyjavascript.com/kiwis80/

    ``<i>
    </i>fetch('content/second.php')
    .then(
    function(response) {
    return response.text()
    }
    ).then(
    function(html) {
    content.innerHTML = html;
    var forienScriptText = content.getElementsByTagName('script')[0].innerHTML;
    var forienScript=document.createTextNode(forienScriptText);
    var scr = document.createElement('script');
    scr.appendChild(forienScript);
    document.body.appendChild(scr);
    }
    ).catch(
    function(err) {
    console.log('Failed to fetch page: ', err);
    }
    );<i>
    </i>
    ``


    of course there are several Better Solutions

    I presented this solution because

    all you need to do is add a few lines of code

    to your existing project

    kiwis80 said ...

    "I'm assuming it's being treated as text only."

    your assumption was correct

    a good general rule for JavaScript programming is ...

    always use innerHTML as if it were ReadOnly,

    never use it to add anything to page

    in the above code I broke this rule
    Copy linkTweet thisAlerts:
    @daveyerwinJun 26.2020 — @DaveyErwin#1619957

    this link ...

    https://drivebyjavascript.com/kiwis80/nexteffort/

    contains the code you posted with this correction ...

    document.getElementById("next").addEventListener("click", nextNum());

    document.getElementById("prev").addEventListener("click", prevNum());

    changed to ...

    document.getElementById("next").addEventListener("click", nextNum);

    document.getElementById("prev").addEventListener("click", prevNum);

    and this code added ...
    ``<i>
    </i> function(html) {
    content.innerHTML = html;
    var forienScriptText = content.getElementsByTagName('script')[0].innerHTML;
    var forienScript=document.createTextNode(forienScriptText);
    var scr = document.createElement('script');
    scr.appendChild(forienScript);
    document.body.appendChild(scr);
    }<i>
    </i>
    ``
    ×

    Success!

    Help @kiwis spread the word by sharing this article on Twitter...

    Tweet This
    Sign in
    Forgot password?
    Sign in with TwitchSign in with GithubCreate Account
    about: ({
    version: 0.1.9 BETA 4.24,
    whats_new: community page,
    up_next: more Davinci•003 tasks,
    coming_soon: events calendar,
    social: @webDeveloperHQ
    });

    legal: ({
    terms: of use,
    privacy: policy
    });
    changelog: (
    version: 0.1.9,
    notes: added community page

    version: 0.1.8,
    notes: added Davinci•003

    version: 0.1.7,
    notes: upvote answers to bounties

    version: 0.1.6,
    notes: article editor refresh
    )...
    recent_tips: (
    tipper: @Yussuf4331,
    tipped: article
    amount: 1000 SATS,

    tipper: @darkwebsites540,
    tipped: article
    amount: 10 SATS,

    tipper: @Samric24,
    tipped: article
    amount: 1000 SATS,
    )...