jQuery:click()带有动态内容两次触发



我基本上是通过AJAX从数据库中加载内容到DIV。然后,单击这些内容件应重新加载新内容。

AJAX请求在我一开始称为类中的方法中初始化为一种方法:

function Request(tag1, tag2, tag3) {
    this.tag1 = tag1,
    this.tag2 = tag2,
    this.tag3 = tag3
}
Request.prototype = {
    ajaxCategoryRequest: function () {
        $.ajax({
            type: "GET",
            url: "request2.php",
            data: "tag1=" + this.tag1 + "&tag2=" + this.tag2 + "&tag3=" + this.tag3,
            success: function (data) {
                var jdata = $.parseJSON(data);
                //Frage ausgeben
                $("h1.question").html(jdata[0]);
                //Tiles ausgeben
                for (var i = 1; i < jdata.length; i++) {
                    $("#tiles").append(
                        '<div class="category" id="' + jdata[i].type + '" data-owntag="' + jdata[i].owntag + '" data-description="' + jdata[i].description + '"><img src="' + jdata[i].imageurl + '" alt="' + jdata[i].name + '"/><div class="ctitle">' + jdata[i].name + '</div></div>'
                    );
                }
            }
        });
    }
};
var searchtype = new Request("", "", "");
searchtype.ajaxCategoryRequest();

然后单击以上创建的DIV之一,应启动一个新请求:

    $("#tiles").on('click', '.category', function () {
        var tag1 = "newtag";
        var tag2 = "newtag";
        var tag3 = "newtag";
        //remove old content
        $('.category').remove();
        //start new request
        var nextrequest = new Request(tag1, tag2, tag3);
        nextrequest.ajaxCategoryRequest();
    });
});

基本上所有内容都在工作,内容已加载,如果我单击DIV,它确实会触发新的请求,但是这是错误的,它触发了两次。因此,每个新的加载元素都出现了两次。

我搜索了它,我认为这是由于Ajax请求中的打印环,每次将点击函数绑定到DIV。我读了很多有关.unbind(" click")和.bind()或类似(.off())的信息,但对我没有任何作用。也许还有另一个解决此问题的解决方案?

它触发了两次

实际上不是。将您的console.log("Mouseclick");放在单击侦听器的第一行中,您只会看到一次。

$("#tiles").on('click','.category',function(e){
   // …
   //remove old elements
   $('.category').fadeOut(200,function(){
       console.log("Mouseclick");
       $(this).remove();
       //start request when animation completed
       var nextrequest = new Request(tag1,tag2,tag3);
       nextrequest.ajaxCategoryRequest();
   });
});

动画是您的问题。.category元素的每个调用fadeOut的回调 - 这就是为什么您的$(this).remove()工作(因为this只是一个<div>元素)。

因此,您实际上是在为您删除的每个类别开始一个新请求,这当然不是您想要的。您能做的就是将请求从动画回调中移出,然后立即开始。没有种族条件,但是 - 当Ajax比200毫秒快的速度快时 - 可能会出现新类别时出现的旧类别时仍在淡出。

如果您想防止这样的小故障,则需要找到所有动画回调完成后解雇Ajax的方法。幸运的是,有一个.promise方法可以做到这一点 - 它返回了一个保证只能解决一次的承诺,您可以在事件队列的结束时添加回调:

$("#tiles").on('click','.category',function(e){
   console.log("Mouseclick");
   // …
   // remove old elements
   $('.category').fadeOut(200,function(){
       $(this).remove();
   }).promise().done(function() {
       // start request once when all animations completed
       var nextrequest = new Request(tag1,tag2,tag3);
       nextrequest.ajaxCategoryRequest();
   });
});

如果要缩短时间直到AJAX请求完成,并承诺您甚至可以轻松地运行动画,并且请求非常轻松,请添加when的回调,这两个任务都完成了:

function categoryRequest(data) {
    return $.ajax({
        type: "GET",
        url: "request2.php",
        data: {tag1: tag1, tag2: tag2, tag3: tag3},
        dataType: "json" // invokes $.parseJSON automatically
    });
}
function outputData(jdata) {
    //Frage ausgeben
    $("h1.question").html(jdata[0]);
    //Tiles ausgeben
    for (var i = 1; i < jdata.length; i++) {
         $("#tiles").append(
             '<div class="category" id="' + jdata[i].type + '" data-owntag="' + jdata[i].owntag + '" data-description="' + jdata[i].description + '"><img src="' + jdata[i].imageurl + '" alt="' + jdata[i].name + '"/><div class="ctitle">' + jdata[i].name + '</div></div>'
         );
    }
}
//Erster Aufruf
categoryRequest("", "", "").done(outputData);
// Weitere Aufrufe bei click
$("#tiles").on('click','.category',function(e){
    console.log("Mouseclick");
    //define next request variables (tags)
    var stage = $(this).attr('id');
    var owntag = $(this).data("owntag");
    var tag1 = "", tag2 = "", tag3 = ""; 
    if (stage == 'searchtype')
        tag1 = owntag;
    else if (stage == 'category')
        tag2 = owntag;
    else if (stage == 'subcategory')
         tag3 = owntag;
    else
         console.log("No valid (stage)type defined");
    var removed = $('.category').fadeOut(200,function(){
        $(this).remove();
    }).promise();
    var request = categoryRequest(tag1,tag2,tag3);
    $.when(request, removed).done(function(requestResults) {
        outputData(requestResults[0]);
    });  
});

使用一种方法仅一次触发该函数。

$("#tiles").one('click','.category',function(){
$("#tiles").off('click').on('click','.category',function(){

我像这样解决了

$('.category').fadeOut(200).promise().done(function(){
               //start request when animation completed
               $(".category").remove();
               var nextrequest = new Request(tag1,tag2,tag3);
               nextrequest.ajaxCategoryRequest();
           });

最新更新