Search code examples
javascriptfunctiondebuggingsweetalert2

Browser is assigning automatically value of a parameter of a function


I am facing a strange bug on javascript which I have tried different ways to solve it but in this case, it has beaten me. The idea of this code is to show the available gallery of photos when the user presses the element tag h5 '<h5 class="m" id="myelem">Galery of photos</h5>', then the website shows the galery with SweetAlert2 and Bootstrap.

So when I do click to the h5 element it runs the function called sweetCarousel which shows the gallery of photos. At this time I am calling the function in this way sweetCarousel.bind(this, ...) to receive the parameters, in this case, the URL from the photos. I am injecting HTML code inside the Sweetalert. As a condition the HTML inside the alert changes depending on how many photos I want to show. The interesting thing which is happening is that when I only load one photo like this:

document.getElementById("myelem").addEventListener("click", sweetCarousel.bind(this, "./img/image1.jpg"));

The browser set the parameters value on this way: img1 = "./img/image1.jpg", img2 = MouseEvent {isTrusted: true, screenX: 449, screenY: 442, clientX: 449, clientY: 339, …}, img3 = ""

So the first conditional if (img2.length == 0) { skips it and goes to the second conditional if (img3.length == 0) {. I do not know why is happening this bug. I planned to evaluate the code in the first conditional as I only passed one image as a parameter

function sweetCarousel(img1, img2 = "", img3 = "") {
  if (img2.length == 0) {
     eee = '<div class=""> <div class="carousel slide" data-ride="carousel">  <ol class="carousel-indicators"> <li data-target="#carousel-example-generic" data-slide-to="0" class="active"></li>  </ol> <div class="carousel-inner" role="listbox"> <div class="item active"> <img src="' + img1 +'"> </div> </div> <!-- Controls -->  </div></div>';
  } else if (img3.length == 0) {
     eee = '<div class=""> <div class="carousel slide" data-ride="carousel">  <ol class="carousel-indicators"> <li data-target="#carousel-example-generic" data-slide-to="0" class="active"></li> <li data-target="#carousel-example-generic" data-slide-to="1"></li> </ol> <div class="carousel-inner" role="listbox"> <div class="item active"> <img src="' + img1 +'"> </div> <div class="item"> <img src="' + img2 +'"> </div> <!-- Controls --> <a class="left carousel-control" role="button" data-slide="prev"> <span class="glyphicon glyphicon-chevron-left" aria-hidden="true"></span> <span class="sr-only">Previous</span> </a> <a class="right carousel-control" role="button" data-slide="next"> <span class="glyphicon glyphicon-chevron-right" aria-hidden="true"></span> <span class="sr-only">Next</span> </a> </div> </div>';
  } else {
     eee = '<div class=""> <div class="carousel slide" data-ride="carousel">  <ol class="carousel-indicators"> <li data-target="#carousel-example-generic" data-slide-to="0" class="active"></li> <li data-target="#carousel-example-generic" data-slide-to="1"></li> <li data-target="#carousel-example-generic" data-slide-to="2"></li> </ol> <div class="carousel-inner" role="listbox"> <div class="item active"> <img src="' + img1 +'"> </div> <div class="item"> <img src="' + img2 +'"> </div> <div class="item"> <img src="' + img3 +'"> </div> </div> <!-- Controls --> <a class="left carousel-control" role="button" data-slide="prev"> <span class="glyphicon glyphicon-chevron-left" aria-hidden="true"></span> <span class="sr-only">Previous</span> </a> <a class="right carousel-control" role="button" data-slide="next"> <span class="glyphicon glyphicon-chevron-right" aria-hidden="true"></span> <span class="sr-only">Next</span> </a> </div> </div>';
  }
  Swal.fire( {
    html: eee,
    width: '50%',
    background: "black !important",
    showCloseButton: true,
    showCancelButton: false,
    showConfirmButton: false,
    focusConfirm: false
  });
  $(".carousel").swipe({
    swipe: function(event, direction, distance, duration, fingerCount, fingerData) {

      if (direction == 'left') $(this).carousel('next');
      if (direction == 'right') $(this).carousel('prev');

    },
    allowPageScroll:"vertical"
  });
}

Solution

  • This is the expected behavior. When you provide an event listener to the addEventListener() method, the listener must implement the EventListener interface.

    So if you want to provide additional arguments to the listener, I suggest you to use closures.

    document.getElementById("trigger1").addEventListener("click", eventListener( ["./img/image1.jpg"]).bind(this));
    
    document.getElementById("trigger2").addEventListener("click", eventListener(["./img/image1.jpg","./img/image2.jpg"]).bind(this));
    
    document.getElementById("trigger3").addEventListener("click", eventListener(["./img/image1.jpg","./img/image2.jpg","./img/image3.jpg"]).bind(this));
    
    
    function eventListener(images){
        return function(event){
          console.log('images', images);
          console.log('event', event);
        }
    }
    <button id="trigger1">Trigger 1</button> 
    <button id="trigger2">Trigger 2</button> 
    <button id="trigger3">Trigger 3</button>

    And also I suggest you to pass images as an array instead of passing them as separate arguments. By using array, you can replace if/else blocks with a loop to create a more generic function. Imagine that you will want to provide 50 images in future, then you will have to create 50 if/else blocks. You can do it as followings:

    document.getElementById("trigger").addEventListener("click", eventListener(["./img/image1.jpg", "./img/image2.jpg", "./img/image3.jpg"]).bind(this));
    
    
    function eventListener(images) {
      return function(event) {
    
        const indicators = images.map(function(image, index) {
          return `
          <li 
             data-target="#carousel-example-generic" 
             data-slide-to="${index}" 
             ${index === 0 ? `class="active"` : ``}
          ></li>
          `
        })
    
        const imageItems = images.map(function(image, index) {
          return `
          <div class="item ${index === 0 ? `active` : ``}"> 
            <img src="${image}"> 
          </div>
          `
        })
    
        const carousel = `
          <div class="">
       <div class="carousel slide" data-ride="carousel">
          <ol class="carousel-indicators">
             ${indicators}
          </ol>
          <div class="carousel-inner" role="listbox">
             ${imageItems}
          </div>
          <!-- Controls --> <a class="left carousel-control" role="button" data-slide="prev"> <span class="glyphicon glyphicon-chevron-left" aria-hidden="true"></span> <span class="sr-only">Previous</span> </a> <a class="right carousel-control" role="button" data-slide="next"> <span class="glyphicon glyphicon-chevron-right" aria-hidden="true"></span> <span class="sr-only">Next</span> </a> 
       </div>
    </div>
          `
    
        console.log(carousel)
      }
    }
    <button id="trigger">Trigger</button>