2010-09-28 5 views
1

travail sur une galerie d'images, mais il se bloque sur moi (vous contrôlez en cliquant sur « gauche » et « droite ») si je clique sur les images plus de 10 fois:plantage code jquery

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

Voici le code:

$(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(); 
    } 
} }); 

quelqu'un peut-il me aider. Je ne suis pas un maître chez jquery, donc tous les conseils et commentaires sont plus que bienvenus :)

Répondre

0

Vous n'UNBIND le cas de clic de l'élément actuellement cliqué (gauche ou à droite, mais pas les deux boutons), puis réassigner nouveaux événements ..

Une solution simple à votre problème, donc, serait de changer $(this).unbind(); à $(this).unbind().siblings().unbind()

vous pouvez simplement attribuer l'événement clic à tous les divs et renifler l'action à exécuter comme vous le faites maintenant de la classe de l'élément (sans déliaison/reconsolidation) ..

De plus, vous n'avez pas à envelopper objet jquery avec le nouveau $ ..

Tous ces changements dans votre code rapporteraient

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

Merci beaucoup, qui a fait l'affaire. J'ai essayé avec plusieurs instances de la galerie, et cela a même fonctionné aussi. Tu es un génie! – askenielsen

+0

@askenielsen, heureux d'aider :) –

0

Il me semble que vous êtes des fonctions de liaison à click sans les relier plus tard. Soit vous pouvez appeler $('#gal_container > div').unbind('click', click_img) en haut de click_img, ou vous pouvez simplement appeler .live(...) une fois sur les sélecteurs CSS requis au moment de l'initialisation, ce qui vous absoudra de toute liaison à l'avenir.

+0

Essayé, mais n'a pas fonctionné. Merci quand même – askenielsen

0

Vous associez des événements, mais vous ne les reliez jamais.

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

Cliquez une fois click_img exécute une fois, l'ajout d'un gestionnaire d'événements à un img gal. Cliquez à nouveau et l'ancien gestionnaire d'événements click_img et le gestionnaire d'événements click_img nouvellement lié s'exécutent. Chacun ajoute une autre copie de click_img à la liste du gestionnaire d'événements. Vous avez maintenant quatre gestionnaires d'événements. Cliquez à nouveau et vous avez huit, et ainsi de suite ... en dix clics, vous avez un millier de gestionnaires d'événements et il n'est pas surprenant que le navigateur se bloque en essayant de les appeler tous.

Relier et relier une charge d'événements tout le temps est une douleur. Simplifions en ayant un gestionnaire d'événements pour tous les 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); 
    }); 
}); 

Si vous n'avez pas besoin de limiter les clics uniquement les divs gauche et à droite, vous pouvez perdre isadjacent et activei complètement. Il serait normal d'autoriser un clic sur n'importe quelle div dans une galerie.

(également Typiquement, vous laissez la classe gal_img sur chaque div.)