аварийный код JQuery - PullRequest
       3

аварийный код JQuery

1 голос
/ 28 сентября 2010

Работа над галереей изображений, но она продолжает падать на меня (вы управляете им, нажимая «влево» и «вправо»), если я нажимаю на изображения более 10 раз:

http://korrektur.adnuvo.com/hejven/index_test2.html

Вот код:

$(document).ready(function(){

/*''''''''''' WORKING COPY !!!!! V2 '''''''''''*/
var gal_prev = null;
var gal_next = null;

var click_img = function() {
    console.profile();

    $(this).unbind();

    if($(this).attr('class') == 'gal_right') {
        /* IF RIGHT */
        /*$('#test').append('Im right. ');*/
        get_pos($(this));

        $(this).siblings('.gal_left').removeClass().addClass('gal_img');
        $(this).siblings('.gal_right').removeClass().addClass('gal_img');
        $(this).removeClass().addClass('gal_active');

        $(gal_prev).removeClass().addClass('gal_left');
        $(gal_prev).bind('click',click_img);

        $(gal_next).removeClass().addClass('gal_right');
        $(gal_next).bind('click',click_img);
    } else {
        /* IF LEFT */
        /*$('#test').append('Im left. ');*/

        get_pos($(this));

        /*$(this).parent().children().removeClass().addClass('gal_img');*/
        $(this).siblings('.gal_left').removeClass().addClass('gal_img');
        $(this).siblings('.gal_right').removeClass().addClass('gal_img');
        $(this).removeClass().addClass('gal_active');

        $(gal_prev).removeClass().addClass('gal_left');
        $(gal_prev).bind('click',click_img);

        $(gal_next).removeClass().addClass('gal_right');
        $(gal_next).bind('click',click_img);
    }

    console.profileEnd();
}

/* BIND ACTIONS TO IMAGES */
$('#img2').bind('click',click_img);
$('#img5').bind('click',click_img);

/* GET POSITION */
var get_pos = function(gal_clicked) {
    if(($(gal_clicked).next().length != 0) && ($(gal_clicked).prev().length != 0)) {
        /*$('#test').append('Im in the middle somewhere. ');*/
        gal_prev = $(gal_clicked).prev();
        gal_next = $(gal_clicked).next();
    } else if($(gal_clicked).prev().length != 0) {
        /*$('#test').append('Im last. ');*/
        gal_prev = $(gal_clicked).prev();
        gal_next = $(gal_clicked).parent().find('div:first');
    } else {
        /*$('#test').append('Im first. ');*/
        gal_prev = $(gal_clicked).parent().find('div:last');
        gal_next = $(gal_clicked).next();
    }
} });

Может кто-нибудь помочь мне.Я не мастер JQuery, поэтому все советы и комментарии приветствуются:)

Ответы [ 3 ]

0 голосов
/ 28 сентября 2010

Вы связываете события, но никогда не отменяете их.

var click_img = function() {
    ...
    $(gal_prev).bind('click',click_img);
    $(gal_next).bind('click',click_img);
    ...
}

Нажмите один раз, и click_img выполнится один раз, добавив обработчик события в gal img. Нажмите еще раз, и оба старых обработчика событий click_img и вновь связанный обработчик событий click_img будут выполнены. Каждый добавляет другую копию click_img в список обработчиков событий. Теперь у вас есть четыре обработчика событий. Нажмите еще раз, и у вас будет восемь, и так далее ... на десять кликов у вас есть тысяча обработчиков событий, и неудивительно, что браузер останавливается, пытаясь вызвать их всех.

Связывание и открепление множества событий - это боль. Давайте упростим наличие одного обработчика событий для всех imgs:

var divs= $('#gal_container>div');
var activei= 0;
divs.click(function() {

    // Find div number and number of left and right div
    // only allow click if the left or right div was clicked
    //
    var divi= divs.index(this);
    var nexti= (divi-1+divs.length)%divs.length;
    var previ= (divi+1)%divs.length;
    var isadjacent= activei===nexti || activei===previ;
    activei= divi;
    if (!isadjacent) return;

    // Set classes on each div to reflect new state
    //
    divs.each(function(i) {
        $(this).toggleClass('gal_active', i===divi);
        $(this).toggleClass('gal_left', i===previ);
        $(this).toggleClass('gal_right', i===nexti);
        $(this).toggleClass('gal_img', i!==nexti && i!==previ && i!==divi);
    });
});

Если вам не нужно ограничивать клики только левым и правым делением, вы можете потерять isadjacent и activei полностью. Было бы нормально разрешить клик по любому элементу в галерее.

(Также вы обычно оставляете класс gal_img при каждом делении.)

0 голосов
/ 28 сентября 2010

Вы открепляете событие click только от выбранного в данный момент элемента (либо левой или правой, но не от обеих кнопок), а затем переназначаете новые события.

Простое решение вашей проблемы, таким образом,можно было бы изменить $(this).unbind(); на $(this).unbind().siblings().unbind()

Вы можете просто назначить событие click всем элементам div и прослушать действие для выполнения, как вы делаете сейчас, из класса элемента ( без каких-либо привязок)/ rebinding ) ..

Кроме того, вам не нужно снова оборачивать объект jquery символом $ ..

Все эти изменения в вашем коде приведут к

var gal_prev = null;
var gal_next = null;

var click_img = function() {
    console.profile();
    if($(this).attr('class') == 'gal_right') {
        /* IF RIGHT */
        /*$('#test').append('Im right. ');*/
        get_pos($(this));

        $(this).siblings('.gal_left').removeClass().addClass('gal_img');
        $(this).siblings('.gal_right').removeClass().addClass('gal_img');
        $(this).removeClass().addClass('gal_active');

        gal_prev.removeClass().addClass('gal_left');

        gal_next.removeClass().addClass('gal_right');
    } else if($(this).attr('class') == 'gal_left'){
        /* IF LEFT */
        /*$('#test').append('Im left. ');*/

        get_pos($(this));

        /*$(this).parent().children().removeClass().addClass('gal_img');*/
        $(this).siblings('.gal_left').removeClass().addClass('gal_img');
        $(this).siblings('.gal_right').removeClass().addClass('gal_img');
        $(this).removeClass().addClass('gal_active');

        gal_prev.removeClass().addClass('gal_left');

        gal_next.removeClass().addClass('gal_right');
    }
    console.profileEnd();
}

/* BIND ACTIONS TO IMAGES */
$('.gal_container div').bind('click',click_img);

/* GET POSITION */
var get_pos = function(gal_clicked) {
    if((gal_clicked.next().length != 0) && (gal_clicked.prev().length != 0)) {
        /*$('#test').append('Im in the middle somewhere. ');*/
        gal_prev = gal_clicked.prev();
        gal_next = gal_clicked.next();
    } else if(gal_clicked.prev().length != 0) {
        /*$('#test').append('Im last. ');*/
        gal_prev = gal_clicked.prev();
        gal_next = gal_clicked.parent().find('div:first');
    } else {
        /*$('#test').append('Im first. ');*/
        gal_prev = gal_clicked.parent().find('div:last');
        gal_next = gal_clicked.next();
    }
}
0 голосов
/ 28 сентября 2010

Мне кажется, что вы привязываете функции к click, не отменяя их позже.Либо вы можете вызвать $('#gal_container > div').unbind('click', click_img) в верхней части click_img, либо вы можете просто вызвать .live(...) один раз для требуемых селекторов CSS во время инициализации, что освободит вас от любой привязки в будущем.

...