Alex Alex - 6 months ago 7
Javascript Question

JavaScript array skipping values

I have this function that loops through all of the

<img>
tags and adds their source
src
into an array. When the user clicks on the main parent div, Bootstrap's modal fades in showing the rest of the gallery.

My problem is, whenever I press the right chevron on a specific div it shows the gallery and slides them perfectly but when I click on another div, the array skips two values and displays the third one instead.

To explain my problem more briefly, lets say I have this array:

arr = [1,2,3,4,5]


When I click the next button the first time it works perfectly

1 => 2 => 3 => 4 => 5


But when I click on another div and press next:

1 => 2 => 5


Here's a working demo of what I have done till now.

HTML:

<div class="col-md-4 col-sm-4 col-lg-4 padBtm10">
<a data-toggle="modal" data-target="#exampleModal" href="#" class="modal-trigger deco-none" onclick="return false;">
<div class="card that_img radius10">
<img data-caption-title="First caption" class="card-img-top img-responsive caption" src="http://dummyimage.com/500x300/000/fff" alt="Card image cap" />
<span class="fa fa-search search fa-3x blue"></span>
<div class="redbg radiusBtm10 white card-block">
<h4 class="card-title">Lorem Ipsum</h4>
</div>
<div class="imgs-album">
<img src="http://dummyimage.com/500x300/000/fff" class="img-responsive full" data-caption-title="First caption for slider 1" />
<img src="http://dummyimage.com/500x300/ddd/fff" class="img-responsive full" data-caption-title="First caption for slider 2" />
<img src="http://dummyimage.com/500x300/aaa/fff" class="img-responsive full" data-caption-title="First caption for slider 3" />
<img src="http://dummyimage.com/500x300/ccc/000" class="img-responsive full" data-caption-title="First caption for slider 4" />
</div>
</div>
</a>
</div>


update (HTML structure for the modal)

<div class="modal breaker fade" id="exampleModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-body noPad">
<button type="button" class="close-pop close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
<div class="">
<a href="#" onclick="return false;">
<span class="fa fa-chevron-right fa-2x right white"></span>
</a>
<a href="#" onclick="return false;">
<span class="fa fa-chevron-left fa-2x left white"></span>
</a>
</div>
<div class="pop-image">
<img src="" class="img-responsive full">
</div>
<h4 class="modal_caption"></h4>
</div>
</div>
</div>
</div>


JavaScript:

(function() {
var ready = function() {
$(".that_img").hover(function() {
$(this).find("span.search").css("display", "block");
}, function() {
$(this).find("span.search").css("display", "none");
});

$(".that_img").on({
click: function() {
var img_src_arr = $(this).find(".imgs-album")
.children("img").map(function() {
return $(this).attr("src");
}).get();

var img_data_cap = $(this).find(".imgs-album")
.children("img").map(function() {
return $(this).data("caption-title");
}).get();

$(".pop-image").find("img").attr("src", img_src_arr[0]);
$(".modal_caption").html(img_data_cap[0]);
var counter = 0;
counter >= 0 ? $(".left").hide() : $(".left").show();

$(".right").on({
click: function() {
counter += 1;
if (counter == 1) {
$(".left").show()
}
var next = $(".pop-image").find("img")
.attr("src", img_src_arr[counter]);
var next_cap = $(".modal_caption")
.html(img_data_cap[counter]);
if (counter > (img_src_arr.length - 2)) {
$(".right").hide();
$(".left").show();
}
}
});
$(".left").on({
click: function() {
counter -= 1;
$(".right").show();
if (counter === 0) {
$(".right").show();
$(".left").hide();
}
$(".pop-image").find("img")
.attr("src", img_src_arr[counter]);
var prev = $(".modal_caption").html(img_data_cap[counter]);
}
});
}
});
}
$(document).ready(ready);
}).call(this);

Answer

The problem occurs because every time an image is clicked, click-handlers are added. With he first image everything seems fine because .left and .right have, at that point, a single click handler. Upon clicking another image, new click-handlers are added and now when you click a chevron, the 2 handlers are being executed resulting in your counter going up, or down, by 2 instead of 1. To prevent this from happening you will have to unbind the handlers from the object.

Change these lines, (explanation here)

$(".right").on({
$(".left").on({

to,

$(".right").off().on({
$(".left").off().on({

And change this line,

counter >= 0 ? $(".left").hide() : $(".left").show();

to,

$(".right").show()
$(".left").hide()

Edit : as mentioned by juhana unbind() is deprecated, so use off() instead.

Comments