Javascript jQuery:click()使用动态内容触发两次

Javascript jQuery:click()使用动态内容触发两次,javascript,jquery,ajax,dynamic,click,Javascript,Jquery,Ajax,Dynamic,Click,我基本上是通过ajax将数据库中的内容加载到一个div中。然后,单击其中的一个内容块应该会重新加载新内容 ajax请求初始化为我在开始时调用的类中的方法: function Request(tag1, tag2, tag3) { this.tag1 = tag1, this.tag2 = tag2, this.tag3 = tag3 } Request.prototype = { ajaxCategoryRequest: function () {

我基本上是通过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,它确实会触发一个新的请求,但是这里出现了错误,它被触发了两次。因此,每个新加载的元素都会出现两次

我搜索了它,我认为这是由于ajax请求中的打印循环,每次都将click函数绑定到div。我读了很多关于.unbind(“click”)和.bind()或类似的(.off())的内容,但没有任何效果。可能还有其他解决方案吗?

用于仅触发一次函数

$("#tiles").one('click','.category',function(){
它被触发了两次

事实上,不是真的。把你的
console.log(“鼠标点击”),您每次单击只会看到它一次

动画是你的问题。对每个
.category
元素调用回调-这就是为什么
$(this.remove()
有效(因为
this
只是一个
元素)

因此,实际上您正在为已删除的每个类别启动一个新请求,这当然不是您想要的。您可以做的是将请求移出动画回调,然后它将立即启动。没有比赛条件,但是——当ajax速度超过200毫秒时——可能会出现新类别,而旧类别仍在淡出

如果要防止出现这样的小故障,需要找到一种在所有动画回调完成后启动ajax的方法。幸运的是,有一种方法正好可以做到这一点—它返回一个保证只解析一次的承诺,并且您可以为事件队列的末尾添加回调:

$("#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请求完成之前的时间,甚至可以非常轻松地并行运行动画和请求,请为两个任务都完成添加回调:

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]);
    });  
});
函数类别请求(数据){
返回$.ajax({
键入:“获取”,
url:“request2.php”,
数据:{tag1:tag1,tag2:tag2,tag3:tag3},
数据类型:“json”//自动调用$.parseJSON
});
}
函数输出数据(jdata){
//弗雷格·奥斯格本
$(“h1.question”).html(jdata[0]);
//奥斯盖本酒店
对于(var i=1;i
我是这样解决的

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

顺便说一下,您可以将jQuery中的AJAX调用压缩为
$.get(url,函数(数据){…这里的数据素材…})。倾向于少一点阻塞,更容易阅读(imo)。事件侦听器具体什么时候绑定?您在请求后会再次绑定它吗?@Bergi我是一个初学者,老实说,我不太确定,但我认为每次AJAX调用打印出一个新的“.category”div.on()都是在请求后编写的。。也许整个代码都有帮助,是的,确实有帮助。你还没有在你的帖子中提供错误的代码…@Bergi你认为错误在哪里,所以我可以把它包括在帖子中?我已经试过了,但它对我不起作用。可能是因为.click绑定到了“.category”?我对jQueryYou很陌生,可以删除
'.category'
paramWow。谢谢我尝试了第一个解决方案,它对我有效(尽管我必须将.remove()移到.promise()的回调中)。我将尝试第二种解决方案,那么您的意思是当您有
.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();
   });
});
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]);
    });  
});
$('.category').fadeOut(200).promise().done(function(){
               //start request when animation completed
               $(".category").remove();
               var nextrequest = new Request(tag1,tag2,tag3);
               nextrequest.ajaxCategoryRequest();
           });