skip to Main Content

I am using a for loop on a data array, for each element in an array, the element’s id is equal to the name of an img. For example: if the id of an element is 1, there should be a corresponding image in the image folder named as 1.

Problem: Both jpg and png format exist in the img folder, so I have to check if an image with a specific format exit or not, if it doesn’t, then I have to change .jpg to .png.

I am going to use it with jQuery .on('error') function, but the problem is .on('error') runs after the entire for loop, so every time when I try to get the id, I get the last element of an array.

Code :

for (var i = 0; i < organisers_data.length; i++) {
  console.log("current ID" + organisers_data[i].id);
  organ_data_id = organisers_data[i].id.replaceAll(/^0+(?!$)/g, "");

  var imgPath = '<img src="/assets/images/organisers/' + organ_data_id + '.jpg" />';

  console.log("before" + imgPath)
  $(imgPath).on('error', function(e) {
    imgPath = '<img src="/assets/images/organisers/' + organ_data_id + '.png" />';
  });

  var tableDiv = '';
  tableDiv +=
    '<div>' +
    '<a href="">' +
    imgPath +
    '</a>' +
    '</div>';

  if ($('.organisers_table')) {
    $('.organisers_table').append(tableDiv)
  }
}
}

console shows that

$(imgPath).on('error', function(e) {
    imgPath = '<img src="/assets/images/organisers/' + organ_data_id + '.png" />';
});

only take the last element id ,seems the on function work only after the for loop, but what I want is id of an element in each loop, what should I do?

2

Answers


  1. You can create the element and use the event listener to change the source of the image.

    const tbl = document.querySelector('.organisers_table');
    for (var i = 0; i < organisers_data.length; i++) {
    
      const organ_data_id = organisers_data[i].id.replaceAll(/^0+(?!$)/g, "");
    
      const wrapper = document.createElement("div");
      
      const link = document.createElement("a");
      link.href = "#";
      
      const img = document.createElement("img");
      img.src = '/assets/images/organisers/' + organ_data_id + '.jpg';
      img.addEventListener('error', function () {
        this.src = '/assets/images/organisers/' + organ_data_id + '.png';
      });
      
      
      link.appendChild(img);
      wrapper.appendChild(link);
      tbl.appendChild(wrapper);
      
    }
    
    Login or Signup to reply.
  2. function fileExists(url) {
        if(url){
            var req = new XMLHttpRequest();
            req.open('GET', url, false);
            req.send();
            return req.status==200;
        } else {
            return false;
        }
    }
    
    // ...
    
    let table_div = organisers_data.map( (organizer,index) => {
      let org = organizer.id.replaceAll(/^0+(?!$)/g, "");
      let pth = `/assets/images/organisers`
      let jpg = `${pth}/${org}.jpg`
      let png = `${pth}/${org}.png`
    
      if fileExists(jpg)
        return `<div><a href=""><img src="${jpg}" /></a></div>`
      else
        return `<div><a href=""><img src="${png}" /></a></div>`
    }).join('')
    
    1. Create a fileExists function. I borrowed this from https://stackoverflow.com/a/13989063/1152809

    2. Loop through the array like a boss, using .map instead of for.

    3. Each iteration of the array will create the same html as your code above, but now with more readability.

    4. Join the elements of the resultant array into one string into the table_div variable.

    Note: My solution uses String Literals aka Template Literals to produce strings. No need for the + mess. Basically instead of quotes, use tic marks, then insert variables or really any js inside ${}, like so:

    `some text ${some_variable} some more text.`
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search