What is the most efficient way to use a for loop with JavaScript querySelectorAll to move multiple images?

I'm trying to move multiple images by defining each one with a for loop. Below is the code I have:

var elem = document.querySelectorAll(".yikama");
var el;
for (i = 0; i < elem.length; i++) {
    var el = elem[i]
    el.addEventListener("mousedown", start)
    
    function start() {
        addEventListener("mousemove", move)
    }

    function move(b) {
        b = b || event;
        el.style.left = b.pageX - 290 + "px";
        el.style.top = b.pageY - 190 + "px";
    }
    
    el.addEventListener("mouseup", function () {
        removeEventListener("mousemove", move);
    })   
}

However, I encountered an error: Uncaught TypeError: Cannot read property 'addEventListener' of undefined at line 1:141. How can I resolve this issue?

Answer №1

You've made a couple of errors in your code. Firstly, you need a condition in the for loop's second statement like i == elem.length or i === elem.length. The correct condition to use is i < elem.length. Also, be careful with this assignment (i = elem.length) as it will not work correctly and can lead to an infinite loop.

The second mistake is that you haven't assigned the move event to any element. Make sure to use el.addEventListener and el.removeEventListener within the start and mouseup events respectively.

Instead of using var el, switch to let el to avoid any potential closure issues. And remember to include b.preventDefault(); inside the move function.

Here is a revised version of your code:

var elem = document.querySelectorAll(".yikama");
for (let i = 0; i < elem.length; i++) {
    let el = elem[i];
    el.addEventListener("mousedown", start);
    
    function start() {
        el.addEventListener("mousemove", move);
    }

    function move(b) {
        b.preventDefault();
        b = b || event;
        el.style.left = b.pageX - 290 + "px";
        el.style.top = b.pageY - 190 + "px";
    }

    el.addEventListener("mouseup", function () {
        el.removeEventListener("mousemove", move);
    });
}

Answer №2

To move an image using style.left and style.top, it is necessary to apply a specific position to the image element.

Additionally, including preventDefault in the mousemove event is crucial to ensure that the mouseup event can be properly triggered following the mousemove event.

This precaution is essential because the browser itself handles dragging and dropping of native images; hence, using preventDefault helps avoid any default behavior interference.

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<style>
    .yikama{
        position: relative;
    }
</style>
<body>
    <img class="yikama"
        src="/xx/xx" alt="" />
</body>
<script>
    var elem = document.querySelectorAll(".yikama");
    var el;
    for (let i = 0; i < elem.length; i++) {
        var el = elem[i]
        el.addEventListener("mousedown", start)
        function start() {
            el.addEventListener("mousemove", move)
        }

        function move(b) {
            b.preventDefault()
            b = b;
            el.style.left = b.pageX - 290 + "px";
            el.style.top = b.pageY - 190 + "px";
        }
        el.addEventListener("mouseup", function () {
            el.removeEventListener("mousemove", move)
        })
    }
</script>

</html>

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

Exploring the animation potential of HTML5 canvas and Javascript through utilizing putImageData with animated gifs

I am interested in modifying the image data of each frame in an animated gif while it is playing in a web browser, using HTML5 canvas and Javascript. For instance, I would like to convert every frame to grayscale dynamically as the gif plays. Is this achie ...

Tips on adding a tooltip to the react-bootstrap tab element

How can I add a tooltip to the tabs in my React application using Bootstrap tabs? I have three tabs and I want a tooltip to appear when hovering over each tab. import { Tabs,Tab} from "react-bootstrap"; // inside return <Tabs variant="pills" ...

Parsing error: 'Unexpected token' found in JSON while attempting to access an external file

Currently working on implementing backbone for a new project along with underscore, requirejs, jquery, and bootstrap. Things are progressing smoothly as I aim to include static survey question data into one of the data models. { "defaultOptions": { ...

Retrieve a value using the jQuery each() method

Hello, I am a beginner in JavaScript and I need help with extracting values from JSON and adding them to an array. My goal is to be able to parse this array using another function later on. However, I'm struggling with returning the array after adding ...

Is it possible to extract only the time from a date and time using angular-moment library?

I am trying to display only the time from a date. My code looks like this: $scope.sample_time = "September 14th 2017, 1:00:00 pm"; What I want in my view is to show just the time, for example 1:00 pm. I attempted to use angular-moment, with something li ...

What is the best way to create an index for a user-provided value in a textbox

Looking for guidance on how to set an index to user-provided values in a textbox, append them to a table in a new row, and display that index in the first column of every row. I am unfamiliar with this type of functionality. $(document).ready(function() ...

The animated loading image is taking an eternity to actually load

My website is loaded with heavy front-end features and I'm using a loading gif to help with the loading process. However, I've noticed that in Safari, there is a delay before the gif loads after the background does, which takes away from the inte ...

Maintain GoogleMaps map object across different views in AngularJS

I have made the decision to utilize the AngularUI Map plugin for displaying Google Maps within a specific view. Here is how the template is structured: <div id="map"> <div ui-map="map" ui-options="mapOptions" id="map-canvas" ui-event="{&apo ...

Refresh the dataTable following the form submission within the colorbox

On my page test.php, I am using jQuery DataTables to fetch data. There is a button labeled "Add Note" that opens an ajax form inside colorbox. The form submission process is functioning correctly, but I am looking for a way to refresh the DataTables when a ...

Encountering a fresh issue after updating to TS version 4.4.3 while accessing properties of the top "Object may be 'null'."

After upgrading my project to TypeScript 4.4.3 from 3.9.9, I encountered a change in the type declarations for the top property. My project utilizes "strictNullChecks": true, in its configuration file tsconfig.json, and is browser-based rather t ...

Utilizing the loop counter within an Array

Currently, I am attempting to iterate through numbers 1 to 21 and then utilize those numbers in order to obtain an Array of Strings like ['e1.wkh',...'e21.wkh']. However, at the moment I am only receiving the value ['e21.wkh'] ...

Cross-origin resource sharing in Express.js servers

Encountering a minor issue with the connection setup between my Express.js API and React client. The Express API is running on http://localhost:3001, while React is hosted at http://exampleip:3000 (both on the same Windows server). To address Cross-Origi ...

Reverse a filter within an ng-repeat loop - AngularJS

I have a question that I haven't found the answer to yet. Here is the issue I'm facing: The JSON data I am working with has this structure: [{ "batch_queue_name": "Batch One", "start_date": "12/01/2016 10:18 P.M.", "end_date": "12/03/2016 ...

Can you explain the significance of this specific form of variable declaration?

Have you ever been in a situation where you receive some code that actually works, but you're not sure how it's working? For example, what exactly does this declaration method accomplish? const { actions: { createRole, updateRole } = {} } = prop ...

Change the content of an ion-card in Ionic2 dynamically

After fetching a list of books from the backend API provider, I am presented with sample data that looks like this: { "success":true, "books":[ { "id":1000, "book_code":"CC219102", "read_status":"completed", ...

Issues with TypeScript arise when transferring arguments between functions

Encountering a TypeScript error due to this pattern: Error message: 'Argument of type '(string | number)[]' is not assignable to parameter of type 'string[] | number[]' function foo(value: string | number) { return bar([va ...

Encountering a "403 Forbidden" error upon deployment to the server due to

Situation: I am developing a website using Spring web MVC, JSP, and HTML/JavaScript. One of the features I have implemented is a search function that communicates with imdbapi.org to retrieve movie/TV show information in JSON format via AJAX. The JSON resp ...

Updating .babelrc to include the paths of JavaScript files for transpilation

Using Babel, I successfully transpiled ES6 JavaScript to ES5 for the project found at I'm currently stuck on updating my .babelrc file in order to automatically transpile a specific ES6 file to a particular ES5 file. Can someone guide me on what cod ...

Building and executing an Angular 2 program on the Windows platform: Step-by-step guide

After successfully installing npm and related packages including TypeScript and Angular 2, I am encountering difficulties running Angular 2 in my browser on a Windows platform. Can someone provide a step-by-step guide to help me create and run Angular 2 ...

Exploring the concept of template inheritance in Vue.js

Is there a way to implement template inheritance similar to Jade’s extends file.jade? I understand that composition can achieve the same result, but for components like the footer and header which are present on most pages except a few (e.g. login page), ...