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

Utilize the dropdown menu to load JSON data and dynamically update the content of a div section on a website

I have been struggling to find a way to load JSON data from a drop down menu into a div area and refresh it with new results. While I was able to display the data in the div area without the dropdown menu, I am facing difficulty in fetching the required da ...

In order to ensure that the multiselect bootstrap dropdown options drop outside of the div and prevent scroll bubbling, there are specific

I am trying to customize a bootstrap multiselect dropdown located within a div. You can find an example of what I'm working on at this link: http://jsfiddle.net/The_Outsider/8watL2L1/9/ In my design, I want the multiselect dropdown options to drop ou ...

How to Use Jquery to Perform Subtraction on Elements

Hello everyone! I am currently working on creating a nutrition label similar to this one: Example I have set up my database and now I am focusing on getting it to work with one element before moving on to the rest. Here is what my database looks like: in ...

The minimum and maximum validation functions are triggered when I am not utilizing array controls, but they do not seem to work when I use array controls

Take a look at the stack blitz example where min and max validation is triggered: https://stackblitz.com/edit/angular-mat-form-field-icrmfw However, in the following stack blitz with an array of the same controls, the validation does not seem to be worki ...

Sort through the array using a separate array in Vuejs

I am currently working with two arrays: { "products": [ { "name": "Jivi", "Hint": "45-60 IE/kg alle 5 Tage\n60 IE 1x/Woche\n30-40 IE 2 x/Woche", "frequency": ["1", "2", "8"] }, { "name": "Adynovi", ...

Angular - Javascript - Oops! The variable 'google' seems to have gone missing after reloading the page

For my website, I utilized Angular 2+ and integrated the Google Maps Api by adding the following code to my index.html file: <script async defer src="//maps.googleapis.com/maps/api/js?[myKey]&libraries=places"> </script> ...

My JavaScript functions are not compliant with the HTML5 required tag

I am currently developing input fields using javascript/jQuery, but I am facing an issue with the required attribute not functioning as expected. The form keeps submitting without displaying any message about the unfilled input field. I also use Bootstrap ...

What could be the reason my view is not updating with the use of a js.erb file in Rails 4?

I found a helpful guide on this blog to implement a toggle feature for an attribute in my database. While the toggling functionality is working fine, I'm struggling to update my view to reflect the changes. This is my first time using js.erb files so ...

Incorrectly resolving routes in the generate option of Nuxt JS's .env configuration file

Having trouble using Nuxt JS's 2.9.2 generate object to create dynamic pages as static files by referencing a URL from my .env file: nuxt.config.js require('dotenv').config(); import pkg from './package' import axios from 'a ...

jQuery custom slider with advanced previous and next navigation capability for jumping multiple steps

I am currently learning jQuery and programming in general. Instead of using a pre-built plug-in, I decided to create my own image slider/cycle from scratch to keep the code concise and improve my skills. My function goes through each li item, adding a &ap ...

Capturing user input in HTML and passing it to JavaScript

I have a good grasp on how to implement input in HTML to execute JavaScript functions that are defined in the same directory as the HTML file. For example: <input type="button" value="Submit" onclick="someFunc(500)" > When the button is clicked, th ...

Tips for using JavaScript to style an array items individually

I have currently placed the entire array within a single div, but I would like to be able to display each element of the array separately so that I can style "date", "title", and "text" individually. This is my JSON structure: [ { "date": "Example ...

When using Laravel's Response::json, a cross-domain error may still occur in the browser despite setting the header to Access-Control-Allow-Origin

I am facing a perplexing Laravel 4 issue. I have set up two methods in the same controller, which is declared to be restful. The problem arises when the ajax request comes from a different domain. The first method does not work: public function getOwnlis ...

What is the process for populating dropdown options from state?

I've been struggling to populate a select element with options based on an array in state. Despite trying various methods, the code snippet below seems to be the most detailed (I'm still getting familiar with React after taking a break for a few ...

What varieties of ajax styles are there?

Although I am still relatively new to utilizing ajax, I have found a lot of success in my endeavors so far. The majority of my ajax calls tend to follow this format: function saveQueryProf(){ var currentDate = new Date(); var date=currentDate. ...

Is there a way to customize the progress bar percentage in Ant design?

I am currently utilizing React JS and importing the Ant Design progress component (refer to https://ant.design/components/progress/). However, I am facing difficulties in dynamically editing the percentage of the progress bar using JavaScript after it has ...

I can't figure out why my SCSS isn't loading, even though I've added it to the webpack.mix.js file in my Laravel project that's set up with React.js

I'm facing a problem where my SCSS is not loading in the VideoBackground.js component of my Laravel project built with React.js, even though I have set it up correctly in the webpack.mix.js file. The file path for the videoBackground.scss file within ...

How can you make the browser window scroll horizontally when a div is clicked using jQuery?

I have an image of an arrow inside a div. The div is positioned fixed in the bottom right corner of an extremely wide page. Is there a way to utilize jQuery to scroll the window 600px to the right each time the arrow is clicked? Also, can I detect when th ...

The dilemma between installing Electron or installing Electron-Builder: which one

When it comes to installing Electron for an Electron app with React, the method can vary depending on the tutorial. Some tutorials use electron-builder while others do not, but there is little explanation as to why. First: npx create-react-app app cd app ...

Enable compatibility with high resolution screens and enable zoom functionality

My goal is to ensure my website appears consistent on all screen sizes by default, while still allowing users to zoom in and out freely. However, I've encountered challenges with using percentages or vh/vw units, as they don't scale elements prop ...