/    Sign up×
Community /Pin to ProfileBookmark

Query SelectorAll On fetch loaded content

I had a JS file which applied a querySelector method as below. It worked as a stand alone page with a linked JS file.

I’m now loading the content via a fetch method. How can I get the JS side of it to work.

I’ve tried making the JS part of the file being retrieved via fetch and putting it on the parent page. I get no errors and it doesn’t work.

[code]
document.querySelectorAll(“.drop-zone__input”).forEach(inputElement =>{

var dropZoneElement = inputElement.closest(“.drop-zone”);

dropZoneElement.addEventListener(“click”, e =>{
inputElement.click();
})
[/code]


to post a comment
JavaScript

12 Comments(s)

Copy linkTweet thisAlerts:
@SempervivumAug 13.2021 — Do I understand this correctly? None of the input elements is being clicked? You execute the javascript you posted

at page load and load the HTML containing the input elements afterwards? If so, this is a common issue: When the JS is executed none of the inputs is existing yet, the nodelist of .drop-zone__input is empty.

If this is correct you can fix it by doing things the other way round: Get the inputs inside the event listener for the dropZoneElement:
``<i>
</i> dropZoneElement.addEventListener("click", e =&gt;{
document.querySelectorAll(".drop-zone__input").forEach(inputElement =&gt;{
inputElement.click();
});
});<i>
</i>
``

Or execute the JS you posted after the content has been loaded, in the .then callback of fetch.

If I understood wrong, please explain more detailed what the purpose of this code is.
Copy linkTweet thisAlerts:
@kiwisauthorAug 13.2021 — @Sempervivum#1635516

No I think you've captured my issue. It's not my code, but below is the full version.

Sounds like it would be easier to do this on the call back function.

Is there a way of doing this without pasting this function inside this?

<i>
</i>}).then(function (html) {
// This is the HTML from our response as a text string
document.getElementById("bodyView").innerHTML = html;

I assume wrapping this in a function is the way to go?


<i>
</i>
document.querySelectorAll(".drop-zone__input").forEach(inputElement =&gt;{

var dropZoneElement = inputElement.closest(".drop-zone");

dropZoneElement.addEventListener("click", e =&gt;{
inputElement.click();
})

inputElement.addEventListener("change", e=&gt;{
if (inputElement.files.length){
updateThumbnail(dropZoneElement, inputElement.files[0])
}

<i> </i>dropZoneElement.classList.remove("drop-zone--over");
})

dropZoneElement.addEventListener("dragover", e=&gt;{
e.preventDefault();
dropZoneElement.classList.add("drop-zone--over");
})

var dropZoneElement = inputElement.closest(".drop-zone");

["dragleave", "dragend"].forEach(type =&gt;{
dropZoneElement.addEventListener(type, e =&gt;{
dropZoneElement.classList.remove("drop-zone--over");
})
})


dropZoneElement.addEventListener("drop", e =&gt;{
<br/>
<i> </i>e.preventDefault();


<i> </i>/*console.log(e.dataTransfer.files);*/
<i> </i>if (e.dataTransfer.files[0].type.startsWith("image/")) {

<i> </i> /* Is a Image */
<i> </i> if (e.dataTransfer.files.length){
<i> </i> inputElement.files = e.dataTransfer.files;
<i> </i> updateThumbnail(dropZoneElement, e.dataTransfer.files[0]);
<i> </i> }
<i> </i> dropZoneElement.classList.remove("drop-zone--over");

<i> </i>} else {
<i> </i> /* Not a Image */
<i> </i> dropZoneElement.querySelector(".drop-zone__prompt").innerHTML = "Not a image file";
<i> </i>}

})

})
Copy linkTweet thisAlerts:
@SempervivumAug 14.2021 — @kiwis80#1635517
>I assume wrapping this in a function is the way to go?

Yes, I agree.
Copy linkTweet thisAlerts:
@kiwisauthorAug 14.2021 — So on the same scenario, I have a span tag with an onclick="myFunction();" attribute.

I've tried in the same place and in the fetched page, I keep getting this error

VM4775 index.php:1 Uncaught ReferenceError: myFunction is not defined

at HTMLSpanElement.onclick (VM4775 index.php:1)
Copy linkTweet thisAlerts:
@SempervivumAug 14.2021 — Two reasons come across my mind:
  • - An error is thrown so that the javascript is aborted and the function remains undefined. In this case the console should tell you.

  • - The function is not defined globally but in some wrapper, e. g. a handler for DOM-ready or page loaded.
  • Copy linkTweet thisAlerts:
    @kiwisauthorAug 16.2021 — So my design was going to be to load all my content via fetch methods.

    But some user functions on the site will be, loaded from loaded content. For example. A user clinks on link on my page. Hard coded on there.

    That loads a form via fetch. User input adds more content, a DIV for example. Clicking that clears everything and loads another form via fetch. That form needs to be submitted via fetch.

    I've got it working by loading all functions after the previous one is loaded and adding Event Listeners.

    Is there a way of doing this so that my final form submit doesn't have to be nested inside the fetch response that loads it? which is inside the the previous one etc.

    The Javascript is becoming complicated that's all.
    Copy linkTweet thisAlerts:
    @kiwisauthorAug 16.2021 — Thinking aloud here. My site contains a index.php page. This has a number of parent links such as 'Users'

    I also have a 'pages' folder. Clicking my parent links loads .php pages from within my pages folder via fetch. For example. UserList.php which is a page that has a form, you can search for users and results displayed on that page.

    Clicking a user will load UserEdit.php page.

    On my index.php page, using fetch I display the UserList.php page.

    Could I somehow, load all my code into a particular block and load it all via an event listener when the relevant page is loaded.

    So when

    <i>
    </i>
    fetch('pages/UserList.php').then(function (response) {
    return response.text();
    }).then(function (html) {
    document.getElementById("bodyContainer").innerHTML = html;
    // SOMEHOW INVOKE A LISTENER HERE
    })


    Or even do it in the index.php page?
    Copy linkTweet thisAlerts:
    @SempervivumAug 16.2021 — Check if taking advantage of event bubbling can help you:
    ```
    // Add one event listener for the whole document:
    document.addEventListener('click'. event => {
    // The element having been clicked is now
    // available as event.target.
    // We can code a switch over this and perform
    // the corresponding action:
    // switch (event.id) { this was wrong
    switch (event.target.id) {
    case 'elem1':
    // Actions for elem1 here
    break;
    case 'another-elem':
    // Actions for that element here
    break;
    case 'one-more-elem':
    // and so on
    }
    });
    Copy linkTweet thisAlerts:
    @kiwisauthorAug 16.2021 — @Sempervivum#1635555

    How does this work for keyup, submit mouseover events?
    Copy linkTweet thisAlerts:
    @SempervivumAug 16.2021 — First of all, there was an error in my code above: `switch (event.id)</C> instead of <C>switch (event.target.id)</C>. I corrected it.

    <QUOTE><i>&gt;</i>How does this work for keyup, submit mouseover events?</QUOTE>

    It works the same way: For keyup event.target is the element having focus. For mouseover it's the element the mouse is entering and for submit it's the form being submitted. Give it a try:
    <CODE>
    `<i>
    </i> &lt;form id="my-test-form"&gt;
    &lt;input id="input1"&gt;
    &lt;input id="input2"&gt;
    &lt;input type="submit"&gt;
    &lt;/form&gt;

    &lt;script&gt;
    document.addEventListener('submit', event =&gt; {
    console.log(event.target);
    event.preventDefault();
    });
    document.addEventListener('mouseover', event =&gt; {
    console.log(event.target);
    });
    document.addEventListener('keyup', event =&gt; {
    console.log(event.target);
    });
    &lt;/script&gt;<i>
    </i>
    ``
    Copy linkTweet thisAlerts:
    @kiwisauthorAug 16.2021 — @Sempervivum#1635576

    Yeah very cool. I've got it working. Much tidier.

    One question though, When I load content such as a list item. I have an ID for my parent UL tag. But each LI tag has a class and unique ID.

    I want to do something when a specific LI is clicked, I can code into each ID into my JS file

    I tried event.target.className but the <span> tags adding formatting to my list are what's being clicked.
    Copy linkTweet thisAlerts:
    @SempervivumAug 17.2021 — Fortunately there is a function `closest</C> that can find the parent li:<br/>
    <C>
    event.target.closest('li')`
    ×

    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.26,
    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,
    )...