The final child element is null when using lastElementChild

For my current Javascript project, I am tackling the task of dividing the page into two separate div elements. The left div is populated with randomly positioned images, and then I utilized the .cloneNode() method to duplicate this on the right side, excluding the last image element.

Up to that point, everything was functioning correctly. However, I encountered an issue when trying to attach an event handler to the final element in the left div. Despite the presence of child nodes within the div as expected, the lastElementChild() method returned null. I have included the code snippet below along with a comment pointing out the problematic section. Any assistance would be greatly appreciated!

<!DOCTYPE html>
<html>
<head>
<style>
    img {position: absolute}
    div {position: absolute; height: 500px; width: 500px}
    #right {border-left: solid black; left: 500px}
</style>

<script>

<!-- All previous sections are working flawlessly -->

    function generateFaces(){

        var theLeftSide = document.getElementById("left");

        var numberFaces = 5;

        for (i = 0; i < numberFaces; i++){
            var random_x = Math.random()*400;
            var random_y = Math.random()*400;
            var image = document.createElement("img")
            image.src = "smile.png";
            image.setAttribute("style","top: " + random_y + "px;" + "left: " + random_x + "px;");
            theLeftSide.appendChild(image);
        }

        var theRightSide = document.getElementById("right");

        leftSideImages = theLeftSide.cloneNode(true);
        theRightSide.appendChild(leftSideImages);
        theRightSide.lastChild.removeChild(theRightSide.lastChild.lastChild);
    }


</script>

</head>
<body onload = "generateFaces()">
    <h1> Game </h1>
    <p> Instructions </p>

    <div id = "right"></div>

    <div id = "left"> </div>

    <script>

    <!-- Issue arises in this portion of the script -->

    var temp = document.getElementById("left");
    console.log(temp); // displays <div> with its children <img>

    var temp2 = temp.lastElementChild;
    console.log(temp2); // returns null

    </script>

</body>

</html>

Answer №1

The onload event of the body will only trigger after the execution of the JavaScript in your 'problem script'.

The sequence of events is as follows:

  • The elements h1, p, #left, and #right are added to the DOM

  • Script #1 executes, logging the empty #left div and the lastElementChild as null.

  • The body's onload event triggers, and script #2 runs (the generateFaces() function), inserting the <img> tags into the DOM.

To resolve this issue, ensure that script #1 runs after script #2:

<body onload="handleLoad()">

and here is the corresponding JS code:

function handleLoad() {
    generateFaces()
    logStuff()
}

function logStuff() {
    var temp = document.getElementById("left");
    console.log(temp); // displays <div> with its children <img>

    var temp2 = temp.lastElementChild;
    console.log(temp2); // logs <img>
}

It might seem like the #left already has images when script #1 runs due to the asynchronous nature of the console log. Consequently, the value logged may be different than the actual content at the time of calling console.log().

You can observe this behavior by adjusting the setTimeout duration for the generateFaces() function call.

Additionally, note that the generateFaces() function creates multiple elements with the same id in the DOM, which should be rectified.

Answer №2

Your generateFaces() function is triggered when the body finishes loading. However, your second script will only run once the window has completely loaded.

This means that when the second script executes, there is no temp.lastElementChild available, resulting in a null value.

You can resolve this issue by following this code snippet:

<!DOCTYPE html>
<html> 
<head>
<style>
img {position: absolute, height: 30px; width: 30px;}
div {position: absolute; height: 500px; width: 500px}
#right {border-left: solid black; left: 500px}
</style>
</head>
<body onload="generateFaces()">
<h1> Game </h1>
<p> Instructions </p>

<div id="right"></div>

<div id="left"> </div>
<script>


function generateFaces()
{
    console.log('y');
    var theLeftSide = document.getElementById("left");

    var numberFaces = 5;

    for (i = 0; i < numberFaces; i++){
        var random_x = Math.random()*400;
        var random_y = Math.random()*400;
        var image = document.createElement("img")
        image.src = "smile.png";
        image.setAttribute("style","top: " + random_y + "px;" + "left: " + random_x + "px;");
        theLeftSide.appendChild(image);
    }

    var theRightSide = document.getElementById("right");

    leftSideImages = theLeftSide.cloneNode(true);
    theRightSide.appendChild(leftSideImages);

    theRightSide.lastChild.removeChild(theRightSide.lastChild.lastChild);

    loaded();

}

<script>

function loaded() {

var temp = document.getElementById("left");
console.log(temp); 

var temp2 = temp.lastElementChild;
console.log(temp2); 

}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Issue with passing parameter values in MVC Html.ActionLink

Currently, I am experimenting with MVC for a demonstration and have managed to put together some components. However, I am encountering difficulties with an Html.ActionLink. The goal is to display a series of dropdown lists to the user that must be selecte ...

React state not being updated by setState method

Here's the situation: let total = newDealersDeckTotal.reduce(function(a, b) { return a + b; }, 0); console.log(total, 'tittal'); //displays correct total setTimeout(() => { this.setState({ dealersOverallTotal: total }); }, 10); cons ...

Tips on verifying the count with sequelize and generating a Boolean outcome if the count is greater than zero

I'm currently working with Nodejs and I have a query that retrieves a count. I need to check if the count > 0 in order to return true, otherwise false. However, I am facing difficulties handling this in Nodejs. Below is the code snippet I am strugg ...

Having issues retrieving a JSON array in PHP with the json_decode function

Can someone assist me with passing and returning an array to a PHP script? I have successfully tested the json_encode portion, but I am facing issues with the json_decode on the PHP side. Javascript scid_list = []; $('.filter_on').each ...

Having trouble with passing the callback for nested mysql queries in Async.waterfall?

I am facing an issue with my nested MySQL queries where async.waterfall is not working as expected. The second step of the waterfall is failing to append its result to the array: async.waterfall([ function(callback) { connection.query(query, function( ...

Guide on how to streamline JSON output from aggregation result

I have written a NodeJs api using mongo db aggregation to obtain some output. However, the result I received is not what I expected. Can anyone help me figure out how to get the desired output? app.get('/polute', function (req, res) { Light. ...

403 Malicious Path Middleware Error in Express.js

Encountering an error when sending a post request to my server, but only on the production server - whereas the staging server is functioning properly. Both servers are hosted on AWS Ubuntu instances. Investigating the stack trace, it appears that the err ...

What is the best way to incorporate the .top offset into a div's height calculation?

Looking to enhance the aesthetic of this blog by adjusting the height of the #content div to match that of the last article. This will allow the background image to repeat seamlessly along the vertical axis. I attempted the following code: $(document).re ...

Initiating a conversation from deep within a conversation using JQuery Mobile

I've been attempting to open a Dialog from within another Dialog, but so far no success. Take a look at the HTML code below: <a href="#popupDialog" data-rel="popup" data-position-to="window" data-role="button" data-inline="true" data-transition=" ...

Angular JavaScript Object Notation structure

I am a beginner in AngularJS and I'm attempting to create formatted JSON based on the values of table rows (tr) and cells (td). The table rows are generated automatically. When the form is submitted, I try to create the JSON values. Once the form is ...

What is the best way to encapsulate a function that uses `this.item.findElement()` from Selenium in a separate file?

I'm currently working on setting up a Selenium Webdriver and Cucumber.js test environment using Node.js. In the homePageSteps.js file, I have a check to verify if a banner exists on a page: Then('there should be a banner', async function() ...

Leveraging Javascript to generate universal HTML content for various Javascript files

Present Situation: I have a timesheet feature that enables users to input their leave, TOIL, and sick days along with the respective hours. Additionally, there is a table that dynamically adds a new row every time the plus button is clicked using the foll ...

Can you provide me with the URL for the jQuery post function?

Could someone please clarify which URL I should use in the $.post call to the server for a node.js file? Most tutorials demonstrate with PHP files, but I'm unsure about calling node.js files. Should I post it to the app.js file or the route file? Thi ...

Retrieving information from a JSON source to populate a data table

Hello fellow developers... I'm currently facing an issue while trying to dynamically populate a data table with information fetched through a fetch request and stored in a Vuex instance variable. Here is the relevant code snippet: <script> impo ...

Guide to smoothly scroll to a specific Label using GSAP's scrollTrigger and scrubbing within a Timeline

Currently facing an issue with a scrollTrigger Timeline where I need a button to scroll to a specific position. I attempted using seek but it did not work, and even the ScrollTo plugin lacks support for this functionality. The Timeline created using gsap ...

Creating a flexible parent tag for grouping child elements using Angular 2

My Objective I am determined to develop an Angular 2 button component that can dynamically render as either an <a /> tag or an <input /> tag based on the value of a property called type. Furthermore, this button component should be able to acc ...

Issue with Ionic displaying data from AngularJS $http.get request

Having just started learning AngularJS, I have followed tutorials on YouTube and read the documentation, but I am struggling to display data from an API using the $http.get() request. Here is my JavaScript and HTML code: var exampleApp= angular.modul ...

Incorporating a dynamic URL within a script tag with AngularJs

I am currently integrating a payment gateway into my Single Page Application (SPA) using AngularJS. The issue I'm facing is that the payment gateway requires me to include a script with a specific ID for the payment process to work correctly. This i ...

Can VueJS 1 and 2 be integrated within the same package.json configuration?

At the moment, my JavaScript files are using VueJS 1. However, I am preparing to work on a new section of the system and want to switch to VueJS 2. ...

Switch the website title as soon as the user looks away from the tab

How can I capture the user's attention and bring them back to my website when they are on a different tab? I really like the effect used on sephora.pl where an alert pops up with the message 'What are you waiting for?' when you switch tabs. ...