javascript loop that runs on every second element only

After completing an ajax query, the following JavaScript code is executed. All of my images are named "pic".

<script type="text/javascript>
 function done() {
     var e = document.getElementsByName("pic");
     alert(e.length);
     for (var i = 0; i < e.length; i++) {
         cvi_instant.add(e[i], { shadow: 75, shade: 10 });
     }
 }</script>

My objective is to use the library found at to add an image border to every picture.

However, it appears that the code seems to skip every other element when applying the border. Any idea why this might be happening?

EDIT: I inserted an alert within the loop and confirmed that it does iterate correctly in sequence.

for (var i = 0; i < e.length; i++)
{
    alert(i);
    cvi_instant.add(e[i], { shadow: 75, shade: 10 });
}

Answer №1

It appears that the issue is occurring only with every second picture rather than all of them.

Typically, this pattern indicates a problem with destructive iteration.

If we assume that the function cvi_instant.add is replacing the element named pic with different elements, then here's what could be happening:

getElementsByName returns a 'live' NodeList, meaning it gets updated whenever there are changes in the DOM. So if it originally had five elements and after calling cvi_instant.add, it now has only four - the first node is removed and nodes 1 through 4 shift down to positions 0 through 3.

As you loop through again, i++ increments, which means you're now accessing element 1, but this was originally element 2! You've skipped over the original element 1, causing the skipping pattern to continue until the end of the now shortened list.

When you alter a list while iterating through it, you run into such issues. In fact, if the process within the loop adds elements to the list, you might even end up in an endless loop!

A quick fix is to iterate the loop backwards. This way, starting with the last element avoids any skipping issues:

 var e= document.getElementsByName("pic");
 for (var i= e.length; i-->0;) {
     cvi_instant.add(e[i], { shadow: 75, shade: 10 });
 }

Another straightforward solution, especially when you consistently remove elements from the list in each call, is:

 var e= document.getElementsByName("pic");
 while (e.length>0) {
     cvi_instant.add(e[0], { shadow: 75, shade: 10 });
 }

The most versatile solution comes into play when your loop body can perform any action on the list, like adding new elements named pic at the beginning or removing elements from the middle. Although slightly slower, making a static copy of the list guarantees safety:

function Array_fromList(l) {
     var a= [];
     for (var i= 0; i<l.length; i++)
         a.push(l[i]);
     return a;
 }

 var e= Array_fromList(document.getElementsByName("pic"));
 for (var i= 0; i<e.length; i++) {
     cvi_instant.add(e[i], { shadow: 75, shade: 10 });
 }

Answer №2

It seems like the function cvi_instant.add() may be performing some sort of incrementing or iteration on the input values. A simpler solution to consider would be:

function complete() {
  var elements = document.getElementsByName('pic');
  for (picture in elements) { cvs_instant.add(picture, { shadow: 75, shade: 10 }); }
}

Answer №3

Greetings! I recently encountered a similar issue in my coding endeavors. It appeared that my code was skipping alternate elements, causing frustration. After some investigation, I discovered a simple solution: renaming the variable 'i' to 'k' within my loop. This alteration seemed to resolve the issue, leading me to believe that 'i' may be reserved by getElementsByTagName for internal use, inadvertently affecting external programming. In essence, it appears to be a bug in the system! :-)

Answer №4

-- UPDATE:

It seems that everything I previously stated is completely incorrect. I am leaving this here in case it resonates with anyone who had similar thoughts :) My test was done in FF3. I vaguely remember seeing this behavior in IE at some point, but that may have been many years ago (now that I think about it, probably about 7 years ago). My recollection may be faulty :)

-- ORIGINAL:

To elaborate slightly on my hypothetical theory, if it happens to be correct:

As far as I can recall, if you omit declaring a variable ('var ...'), it will use one from somewhere else.

Therefore, without actually testing it, the following code snippet:

for(var k = 0; k < 2; k++){
    f();
    alert("k: " + k);
}

function f () {
  k++;
}

Should exhibit the same effect. If my analysis proves to be accurate, TML's approach seems quite elegant from a 'defensive coding' standpoint.

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

What is the process of defining a route for a JSON response in an Express application?

I've been following an Angular tutorial on handling form submissions with promises, which I found here. My server is running on Node and I'm using Express to manage routes. However, when I submit the form and reach the line var $promise = $http. ...

How can I transform the overall value into a percentage in Vue.js or JavaScript?

Is there a way to create a progress bar in VueJS 3 with Nuxt Js by converting the total value to a percentage and displaying it as a style width value? For example, if 40% out of 100% equals 400USD out of 1000USD, can we achieve this using a function in an ...

Tips for troubleshooting my website?

After making some updates to my website, I noticed that an ajax script is no longer functioning properly. Since I hired someone else to write the code, I'm not sure how to troubleshoot it. Initially, this is what it should look like: When you select ...

Utilizing AngularJS to Retrieve Row Information Upon Button Selection

I'm currently developing an application that includes a feature allowing users to run a query from a drop-down menu and view the data in a table. Each row in the table will have a button, and when clicked, I need to capture the values of that specific ...

Calculating the number of rows in a dynamic jQuery table

I have a table structured like this: <div class="row"> <input type="button" id="btnAddGatePass" value="Add Gate Pass Requester" /> <div class="table-responsive"> <table id="gatePass" class="table table-striped table-ho ...

Consuming all available memory resources (RAM and Virtual) is the Visual Basic Compiler's main issue (vbc.exe)

I am currently working on an asp.net web application using VB in Visual Studio 2019. The project builds, compiles, and runs without any issues. When we publish the files and place them in the www root folder, everything functions perfectly. However, we ha ...

The virtual method 'android.location.Location' was called in error

I'm using WL.Device.Geo.acquirePosition(onGeoLocationSuccess, onGeoLocationFailure, options) from MobileFirst to retrieve a device's location. Initially, everything works smoothly as I successfully obtain the location. However, after clearing t ...

Collapsed ReactJS: Techniques for compressing the Material UI TreeView following expansion

My issue involves a Material UI treeView. After expanding it, an API call is made, but the node in the treeView remains open. I have attempted to use onNodeToggle without success. Below is my code: <TreeView className={classes.root1} defaultExpandI ...

Display an icon within an HTML element when the content inside it exceeds its boundaries

Looking to display a copy to clipboard icon when the content inside a div overflows I am using ngFor to iterate through four divs, and if any of those divs is overflowing, I want to show an icon specific to that respective div. <div *ngFor div of Four ...

Creating a Query String in a web URL address using the state go method in Angular State Router

On my product list page, there is a list of products. When I click on a particular product, a function is called that uses state.go. Issue with dynamic functionality: $state.go('home.product.detail', { 'productID': "redminote4", &apo ...

Opening a Bitmap file from a TIF in WinForms, but encountering issues in ASP.NET

UPDATE Solution Located: Find details below. We are in the process of developing a library that can read a TIF file from a scanner, essentially like a scantron. Our focus is on analyzing the form and extracting values from it. Currently, we have a test a ...

Tips for handling a JSON payload retrieved through a POST request

I'm currently working on a button that triggers a POST call to retrieve a json response from the server. My goal is to display this json response in a new (chrome) browser tab. Here's what I have so far using Angular: $http.post(url, data) .t ...

Guide on how to use a tooltip for a switch component in Material-UI with React

I am attempting to incorporate a tooltip around an interactive MUI switch button that changes dynamically with user input. Here is the code snippet I have implemented so far: import * as React from 'react'; import { styled } from '@mui/mater ...

Leveraging jQuery or javascript to display json data in a table with multiple columns

My goal is to convert a JSON data into an HTML table that dynamically creates columns based on the content of the JSON. However, I am facing challenges in looping through the JSON and rendering multiple columns when necessary. The desired output for the e ...

Develop a dynamic animation using gradient and opacity properties

I'm still getting the hang of HTML, JavaScript, and CSS but I recently made some changes to someone else's code to animate a gradient. The original code used background: rgb, but I switched it to background: rgba. It seems to be working fine, but ...

A step-by-step guide on deleting an element within a div using jQuery

I am attempting to delete an HTML element using JQuery like this $('#' + divId + ' .settings_class').remove('.print_settings'); This code does not result in an error or remove the specified html element, however, the selecto ...

Troubleshooting issue with Bootstrap collapse functionality failing with dynamic IDs

Having trouble creating dynamic ids for bootstrap collapsing functionality. I want each topic in an ng-repeat to collapse and display its respective question list when clicked. The issue is that when I click on a second topic, the question list data from ...

Show the total of a JavaScript calculation in a designated input box

Is there a way to show the total sum of this calculation in an input field? function calculateSum1() { var sum = 0; //loop through each textbox and add their values $("input.miles").each(function() { //only add if the value is a number ...

When JQuery deferred.done is invoked, it immediately executes any predefined function, however, it does not execute any

In my current scenario, I am facing an unusual issue as mentioned in the title. Below is the snippet of code that illustrates the problem: Scenario 1: var first = $.ajax({ // approximately a 500ms request url: myUrl, success: functio ...

Can you please explain the process of retrieving the value of an item from a drop-down menu using JavaScript?

I am currently developing a basic tax calculator that requires retrieving the value of an element from a drop-down menu (specifically, the chosen state) and then adding the income tax rate for that state to a variable for future calculations. Below is the ...