How come JavaScript code seems to run the second part on occasion?

When working with drawing background on a canvas and adding small images on top of that background, I sometimes encounter an issue where the background is drawn over the small images. This behavior puzzles me. Can you shed some light on why this might be happening?

Here is the JavaScript code snippet for reference -

var canvasupdate = document.getElementById("myCanvas");
ctxupdate = canvasupdate.getContext("2d");
var background = new Image();
background.src = sitePath + "ATOM/chapter1/book/" + `bgimagename`;
background.onload = function() {
    ctxupdate.drawImage(background, 0, 0); // set background image 
};



var imageobj = new Array();
for (var d = 0; d < calloutImageArray.length; d++) // getting small images in array
{
    imageobj[d] = new Image();
    (function(d) {
        imageobj[d].src = sitePath + "ATOM/chapter1/book/" + calloutImageArray[d];
        imageobj[d].onload = function() {
            ctxupdate.drawImage(imageobj[d], calloutImageArrayX[d], calloutImageArrayY[d], calloutImageArrayW[d], calloutImageArrayH[d]);
        };
    })(d);
}

I noticed that in the above code, the background image code should ideally be executed first followed by the small images code. However, there are instances where the small images code executes before the background image code. Any insights on why this sequence is not consistent?

Answer №1

Images are loaded asynchronously, meaning small images may load before the background image at times. To investigate resource loading order, check the Network tab in Chrome.

A straightforward fix is to shift the loading of small images into the callback function for the load event of the background image.

Answer №2

When dealing with the onLoad function in JavaScript, it's important to understand that it runs asynchronously. This means that while JavaScript continues to run the rest of your code, it will execute the callback function once the background image has finished loading. As a result, there may be instances where the second part of your code executes before the first.

To address this issue, one solution is to place all your code inside the onload function as shown below:
var canvasupdate = document.getElementById("myCanvas"); ctxupdate = canvasupdate.getContext("2d"); var background = new Image(); background.src = sitePath + "ATOM/chapter1/book/" + `bgimagename`; background.onload = function() { ctxupdate.drawImage(background, 0, 0); // set background image var imageobj = new Array(); for (var d = 0; d < calloutImageArray.length; d++) // getting small images in array { imageobj[d] = new Image(); (function(d) { imageobj[d].src = sitePath + "ATOM/chapter1/book/" + calloutImageArray[d]; imageobj[d].onload = function() { ctxupdate.drawImage(imageobj[d], calloutImageArrayX[d], calloutImageArrayY[d], calloutImageArrayW[d], calloutImageArrayH[d]); }; })(d); } };

This approach ensures that the background image is loaded and set before proceeding to load and display the smaller images. Please note that I have not tested your specific code, but rather reorganized the logic to demonstrate why certain parts may not run as expected.

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

Obtain data from a local JSON file using the http.get() method in Angular 2

I am attempting to utilize the http.get() method in Angular 2 to load a local JSON file. I followed a suggestion from Stack Overflow that involves modifying my app.module.ts: In this example, I have imported the HttpModule and the JsonModule from @angular ...

How to pass a JavaScript variable value to a SQL query in PHP on a separate webpage?

I have 2 elements - an auto search bar and Map using mapbox-gl. I want to load the location of the user whose id is searched. I am getting the same marker (location) for every user. I am loading "get_pin.php" through xmlHttpRequest from the main page "m ...

Using Restify to Serve CSS FilesLearn how to use Restify to

Currently, I am developing a node application that requires serving static files like JavaScript and CSS. In my project structure, I have the following layout: -MyProject -backend -index.js -frontEnd -index.html -js ...

Angular 10 does not reflect changes in the array when they occur

My component receives an array of offers from an Observable. However, when the list is modified (a offer is deleted), the component's list does not update accordingly. I attempted to use ngOnChanges to resubscribe to the list and update it in my comp ...

Navigating the FormSpree redirect: Tips and tricks

I recently set up my website on Github Pages and wanted to integrate a free contact form from FormSpree. However, I encountered an issue where after submitting the form, it redirected to a different website, which was not ideal. After researching online, I ...

How to set the element in the render method in Backbone?

Currently, I am in the process of developing a web page utilizing BackboneJS. The structure of the HTML page consists of two divs acting as columns where each item is supposed to be displayed in either the first or second column. However, I am facing an is ...

Angular.js provides a solution for parsing a unique structure of JSON array containing objects

How can an angular for each loop be used to handle the json array of objects provided in the formatted data below? The key represents the id and the value represents the title. Any suggestions on how to accomplish this task? Thank you. mycode me.record ...

The Super expression in Node.js can only be null or a function

When working in my UserService class, I attempted to use the super keyword to call my base class constructor. However, I encountered an error message stating: TypeError: Super expression must either be null or a function Below is the code for my UserServi ...

Navigate to the end of a container

Is there a method to automatically scroll to the bottom of a div when the page is loaded? I have attempted several solutions without success. If you have any insights, please share them. Thank you! ...

Change HTML canvas data into Angular form data before sending it to the Laravel backend

My JavaScript code to convert a data URL to blob and send it as a form request is: var canv = document.getElementById("mainCanvas"); var dataURL = canv.toDataURL('image/jpg'); documentData = {"image": dataURLtoBlob(dataURL), "gameName": "empero ...

Automatically create index.d.ts type definitions from a TypeScript module with just a few clicks

If I have a TypeScript module named my-function.ts with the following code : export function myFunction (param: number): number { return param } When this module is compiled to JavaScript, it loses its type definitions. Is there a way to automatically ge ...

Is the `ng-model` for the AngularStrap `bs-typeahead` component not accessible in the current scope?

I am encountering a problem with the ng-model value in an element that uses AngularStrap's bs-typeahead. It seems to not be accessible within the scope, but it works fine when accessed using {{ var }} in the HTML. Here is the HTML code: <input ty ...

The Angular application is not functioning properly after refreshing the web browser

My angularJS app runs smoothly up until I refresh my web browser. Within my application, there is a JSON object retrieved during login that includes a session ID and an array. However, upon refreshing the page, the JSON object becomes empty and errors sta ...

Having trouble sending a prop to an API function from UseEffect in React with Next.js

Currently, I am utilizing the App Router within next.js. I am encountering difficulties when attempting to pass serial_num as an argument to my API function fetchImages from within the useEffect in my page.tsx file. The API function can be found in /app/ ...

Automatically populate textboxes with database information based on selected combobox item without the need to refresh the page

I would like to implement a feature where textboxes are automatically filled from a database when a user selects an option from a combo box. This can be achieved using jQuery or JavaScript in PHP. Once a user selects an element, the corresponding text sh ...

Retrieving a Mat Icon through an Angular directive

Currently facing an issue with loading the icon component from Angular Material. My goal is to incorporate a clickable icon that clears the input using a directive, as seen below: <input appClearInput></input> The main problem lies in the fac ...

The icon click function seems to be malfunctioning on Protractor

When I try to click on the icon to add a new item, nothing happens. I'm not sure if I'm targeting the element correctly. I attempted the solution provided in this post: element(by.css('[ng-click="createWL()"]')).click(); ele ...

Silent response upon click event listener

I'm having an issue with a navbar item not calling the reverseService function on click as expected. Although my IDE is indicating that the reverseService function is never used, VueJS dev tool doesn't show any problems. However, manually changi ...

"Looking to replace a character class pattern using regex in JavaScript? Here's how you can easily

I have a string: "\W\W\R\" My goal is to transform this string using regular expressions into: <span>W</span><span>W</span>\R This is the code I'm currently using: "\W\W\R".replace(/&b ...

Is it possible to bring in a `devDependency` into your code?

The Mobx DevTool's README instructs users to install it as a dev dependency, and then import it into their code. This approach raises concerns for me because devDependencies are typically reserved for tools used in the build process or managing end co ...