Vitaliy Vitaliy - 10 days ago 5
jQuery Question

Javascript: automatize function

Good day,

I have a piece of code that is aimed to perform action on mouse click. First I have made a function that scrolls screen on element when I perform a click on another element:

(function($) {
$.fn.goTo = function() {
$('html, body').animate({
scrollTop: $(this).offset().top + 'px'
}, 'fast');

}
})(jQuery);


than I assign this function to specific DOM elements:

$('#collapse1').on('shown.bs.collapse', function () {
$('#s1').goTo();
});

$('#collapse2').on('shown.bs.collapse', function () {
$('#s2').goTo();
});

$('#collapse3').on('shown.bs.collapse', function () {
$('#s3').goTo();
});

$('#collapse4').on('shown.bs.collapse', function () {
$('#s4').goTo();
});
etc...


"shown.bs.collapse" is actually from bootstrap collapse.js.
"This event is fired when a collapse element has been made visible to the user (will wait for CSS transitions to complete)."
The code is working but it is really not looks good. Is there the way to make some sort of cycle? Standard "for" is not working:

var collapseNumber = jQuery.makeArray(document.getElementsByClassName("panel panel-default"));

for (var i = 0; i < collapseNumber.length; i++) {

$('#collapse' + i).on('shown.bs.collapse', function () {
$('#s' + i).goTo();
});
}


created array is for getting actual number of elements, which I need to put in the cycle.

Answer

The problem you have is the infamous for loop issue where the value of i is the last value. But there is no reason to have to loop when a simple data attribute can be used.

Just use a data-attribute to select and link the things

<div data-goto="#s1">...</div>

and the JavaScript

$('[data-goto]').on('shown.bs.collapse', function () {
    var selector = $(this).data("goto");
    $(selector).goTo();  
});