【问题标题】:jQuery click being fired twicejQuery点击被触发两次
【发布时间】:2010-10-24 19:11:46
【问题描述】:

代码:

$(".box-collapse").live("click",function(){
    if(updating()) return false;
    var b = $(this).parent().parent();
    b.find(".album-div").stop(true,false).slideToggle();
    $.ajax({
        url: addNonce($(this).attr("href")),
        success:function(data){
            c = b.attr("id");
            var resp = $('<div />').html(data);
            var col = $("#"+c+" .box-collapse");
            var ncol = resp.find("#"+c+" .box-collapse");
            col.html(ncol.html());
            col.attr('href',ncol.attr('href'));
            resp.remove();
            clearUpdate(data);
            wait = false;
        }
    });
    return false;
});

此点击被触发了两次。

会发生什么:

  • 点击折叠,它会发送一个 响应以保存崩溃。
  • 再次点击展开,它会发送一个 请求保存展开。
  • 再次单击以折叠它是 触发两次(使其展开,但保存折叠)。
  • 再次点击,它会触发 4 次。

它只会在第二次点击后开始多次触发。这让我很困惑。

如果我删除数据服务,它不会触发两次。我在服务上做错了什么? (即我只在success中留下wait = false

我在此调用中使用的其他函数:

function updating(){
    if(!wait) {
        $("#loading").html('Updating...');
        wait = true;
        return false;
    }
    else {
        $("#loading").html('Slow down...');
        return true;
    }
}

function clearUpdate(data){
    var resp = $('<div />').html(data);
    //alert(resp.find("#nonce").val() + " "+$("#nonce").val());
    $("#loading").html(resp.find("#loading").html());
    if(typeof(resp.find("#nonce").val()) == 'undefined'){
        alert(data);
        $("#loading").html("Fatal error. Your session could have ended. <a href='javascript:location.reload()'>Refresh</a>");
        resp.remove();
        return false;
    }
    else if(resp.find("#errorcode_").val() == "refresh"){
        location.reload();
    }
    resp.find(".image-box").each(function(){
        $("#"+$(this).attr("id")).find(".image-count").html($(this).find(".image-count").html());
    });
    $("#nonce").val(resp.find("#nonce").val());
    wait = false;
    resp.remove();
}

wait 标志防止在最后一个请求得到服务之前发送请求。我这样做是因为我跟踪一个随机数,并且我必须在每次请求后获得一个新的随机数。

同样,如果我删除数据服务,它工作正常。但我需要服务数据以获取新的随机数。

另外,我没有看到它在任何地方崩溃。任何帮助都会很棒。如果需要,我会发布任何其他功能。我的完整脚本非常大。

这是 .box-collapse 父级的 HTML:

    <div class='box image-box album-marker-visible image-box-w-20 image-box-list-0' id='portrait'>
    <h2 class='box-header image-box-header'>
    <input type='checkbox' name='albums[portrait]'>
    <span class='image-box-header-move'>
    <span class='image-album-number'>1</span>. Portrait <input type='hidden' class='image-album-anchor' value='portrait'>
    <input type='hidden' class='image-album-portfolio' value='1'>
    <span class='image-count'>(20)</span>
    <span class='box-mover'>Move to: <a href='images?n=bridals,weddings,engagement,portrait&port=2&nonce=I8FX2BH841' title='Move to Wedding Portfolio'>Wedding Portfolio</a>&nbsp;Move: <a href='images?n=story,portrait,capture,press,concerts&port=1&nonce=I8FX2BH841'>down</a></span></span>
<span class='album-marker'>&nbsp;|&nbsp;<a href='images?ia=3&action=hide&nonce=I8FX2BH841' title='Mark album as hide' class='album-mark-hide album-mark'>hide</a></span>
<a class='box-mover-show box-collapse' href='images?expand=portrait&nonce=I8FX2BH841' title='Expand Portrait'>expand</a></h2> 

.box 有多个实例,我没有在 h2 标记之后显示内容(这就是我的 div 没有关闭的原因)。

根据要求,这是应该发生的事情的分步过程:

  • 我在 .box-collapse 实例上单击折叠。它发送它的href
  • jQuery 切换它的幻灯片。
  • 在回电时,我从刚刚单击的链接中获得了新的 href。它应该已将查询字符串从 expand=an_album 更改为 collapse=an_album 或反之亦然。我还将状态从“展开”更改为“折叠”。我正在根据我刚刚单击的包含 .box 的 ID 搜索响应。我得到了正确的响应(折叠将变为展开),但 jQuery slideToggles 两次。
  • clearUpdate() 中,我根据收到的数据更新我的随机数。如果我没有收到随机数,我就会死。我还更新了每个 .box 的图像计数。

我在成功中设置了一个警报,第一次点击时,我得到一个警报。再次点击,我得到一个警报。点击 三次 次,我收到 两个 警报。第四次,4 个警报。

我在我的clearUpdate() 中也做了alert($(".box-collapse").length); 并且大小没有改变。

错误在于成功函数和/或 clearUpdate。由于我收到的 HTML 与我已经收到的完全相同(减去上面的更改),我是否有可能重新解析 javascript 并重新绑定点击?但这似乎不可行,因为我应该在第一次点击后多次触发。 更新 我在$(document).ready() 中添加了一个警报,每次收到回复时都会收到警报。所以它正在重新解析javascript并重新绑定点击。我的直接解决方法是将其更改为:$(".box-collapse").die("click").live("click",function()),但我将添加一个查询以禁用 javascript 标头。

感谢您的帮助!

【问题讨论】:

  • 你能显示与此点击事件相关的 HTML 吗?
  • 你真的需要直播吗?您的 .box-collapse 是如何添加的?
  • 嗯,HTML 是页面的确切内容,所以有很多。有什么特别想看的吗?我还没有公开它,否则我会让你探索它。
  • @sunn0.忘了提一下,如果我删除了 live 并点击一下,它会在第一次点击后立即触发两次。
  • 我们需要查看 .box-collapse 周围的整体标记(直接父级和子级)

标签: javascript jquery onclick


【解决方案1】:

如果数据包含 .box-collapse 类,这很可能会创建第二次点击事件

var resp = $('<div />').html(data);

你真的需要类选择器吗?标识符应该是唯一的 这使得 b.html() == $("#"+c+" .box-collapse").html() 和 b == col[0]

var col = $("#"+c+" .box-collapse");

这令人担忧。这意味着在 resp 中存在一个与 b 中具有相同 id 的元素。 从实时切换到点击很可能是点击事件的原因 发生两次。

var ncol = resp.find("#"+c+" .box-collapse");

对.box-collapse的内容或数据知之甚少,无法理解

col.html(ncol.html());
col.attr('href',ncol.attr('href'));

现在我想我终于明白了。

更改数据以包含 JSON 对象或更简单的 HTML 结构,它应该像这样工作。

好例子

 data == { "innerText":"expand", "url":"images?expand=portrait&nonce=I8FX2BH841" }

 col.html(data.innerText);
 col.attr('href', data.url);

不好的例子

服务器响应:

data == <span class="innerText">expand</span><span class="url">images?expand=portrait&nonce=I8FX2BH841</span>

var div = $("<div />").html(data);
col.html(div.find(".innerText").html());
col.attr(div.find(".url").html());

并调整 clearUpdate 功能

【讨论】:

  • 感谢您的评论。你是对的,我想将响应更改为 JSON,但为了开始测试,我只是将响应保留为 HTML。当我期望我已经拥有的东西得到回应时,它让我更容易测试。很好的 id,你是对的。当我收到回复时,我从来没有想过拥有一个非唯一的 ID。感谢您的意见,我会尽快更改。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-08-20
  • 1970-01-01
  • 1970-01-01
  • 2018-01-18
相关资源
最近更新 更多