jquery 代码崩溃

发布于 2024-09-24 22:01:00 字数 2434 浏览 7 评论 0原文

正在处理图像库,但如果我单击图像超过 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 大师,所以非常欢迎所有提示和评论:)

Working on an image gallery, but it keeps crashing on me (you control it by clicking on 'left' and 'right') if i click on the images more than 10 times:

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

Here's the 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();
    }
} });

Can anyone help me out. I'm not a master at jquery, so all tips and comments are more than welcome :)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

感情废物 2024-10-01 22:01:00

您只需从当前单击的元素(左侧或右侧,但不是两个按钮)解除单击事件的绑定,然后重新分配新事件。

因此,解决您的问题的一个简单解决方案是更改 $( this).unbind();$(this).unbind().siblings().unbind()

您可以将点击事件分配给所有 div 并嗅探操作像现在从元素所具有的类中执行的那样(没有任何解除绑定/重新绑定)..

此外,您不必再次用 $ 包装 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();
    }
}

You only unbind the the click event from the currently clicked element (either left or right, but not from both buttons), and then reassign new events..

A simple solution to your problem, thus, would be to change $(this).unbind(); to $(this).unbind().siblings().unbind()

You could just assign the click event to all divs and sniff the action to perform like you do now from the class the element has (without any unbinding / rebinding) ..

Additionally you do not have to wrap jquery object with the $ again ..

All those changes in your code would yield

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();
    }
}
缘字诀 2024-10-01 22:01:00

在我看来,您将函数绑定到 click 而无需稍后取消绑定。您可以在 click_img 顶部调用 $('#gal_container > div').unbind('click', click_img),也可以只调用 .live(...) 在初始化时在所需的 CSS 选择器上使用一次,这将免除您将来的任何约束。

It looks to me like you're binding functions to click without unbinding them later. Either you can call $('#gal_container > div').unbind('click', click_img) at the top of click_img, or you can just call .live(...) once on the required CSS selectors at initialisation time, which will absolve you of any binding in the future.

时光病人 2024-10-01 22:01:00

您正在绑定事件,但永远不会解除它们的绑定。

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

如果您不需要将点击限制为仅左右 div,则可以完全失去 isadjacentactivei 。允许点击图库中的任何 div 是很正常的。

(此外,您通常会在每个 div 上保留 gal_img 类。)

You are binding events, but never unbinding them.

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

Click once and click_img executes once, adding a event handler to a gal img. Click again and both the old click_img event handler and the newly-bound click_img event handler execute. Each adds another copy of click_img to the event handler list. Now you have four event handlers. Click again and you have eight, and so on... by ten clicks you have a thousand event handlers and it is not surprising the browser grinds to a halt trying to call them all.

Binding and unbinding a load of events all the time is a pain. Let's simplify by having one event handler for all the 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);
    });
});

If you don't need to limit clicks to only the left and right divs, you can lose isadjacent and activei completely. It would be normal to allow a click on any div in a gallery.

(Also you'd typically leave the gal_img class on every div.)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文