66

这个页面上,我有一个 jQuery 弹出窗口和可调整大小的缩略图。如果我将鼠标悬停在缩略图上,图像会完美调整大小。此外,当我单击页脚中的黄色大电视按钮“QuickBook TV”时,弹出窗口会完全按照我的意愿显示。

但是,当我单击“下一步”或“上一个”按钮时,AJAX 用于加载新内容,而我的 jQuery 不再适用于弹出或缩略图。我已经搜索了许多论坛以查找有关此问题的信息,但由于对 jQuery 的了解有限,我无法理解我需要做什么。

以下是弹出的jQuery

$(document).ready(function() {

        $(".iframe").colorbox({ iframe: true, width: "1000px", height: "500px" });
        $(".inline").colorbox({ inline: true, width: "50%" });
        $(".callbacks").colorbox({
            onOpen: function() { alert('onOpen: colorbox is about to open'); },
            onLoad: function() { alert('onLoad: colorbox has started to load the targeted content'); },
            onComplete: function() { alert('onComplete: colorbox has displayed the loaded content'); },
            onCleanup: function() { alert('onCleanup: colorbox has begun the close process'); },
            onClosed: function() { alert('onClosed: colorbox has completely closed'); }
        });

        //Example of preserving a JavaScript event for inline calls.
        $("#click").click(function() {
            $('#click').css({ "background-color": "#f00", "color": "#fff", "cursor": "inherit" }).text("Open this window again and this message will still be here.");
            return false;
        });
    });

这是缩略图 jQuery

$(function() {

var xwidth = ($('.image-popout img').width())/1;
var xheight = ($('.image-popout img').height())/1;

$('.image-popout img').css(
        {'width': xwidth, 'height': xheight}
); //By default set the width and height of the image.

$('.image-popout img').parent().css(
        {'width': xwidth, 'height': xheight}
);

$('.image-popout img').hover(
    function() {
        $(this).stop().animate( {
            width   : xwidth * 3,
            height  : xheight * 3,
            margin : -(xwidth/3)
            }, 200
        ); //END FUNCTION

        $(this).addClass('image-popout-shadow');

    }, //END HOVER IN
    function() {
        $(this).stop().animate( {
            width   : xwidth,
            height  : xheight,
            margin : 0
            }, 200, function() {
                $(this).removeClass('image-popout-shadow');
    }); //END FUNCTION

    }
);

});
4

9 回答 9

126

jQuery 选择器在代码执行时选择存在于 DOM 中的匹配元素,并且不会动态更新。当您调用一个函数时,例如.hover()添加事件处理程序,它只会将它们添加到这些元素中。当您执行 AJAX 调用并替换页面的一部分时,您将删除那些绑定了事件处理程序的元素并用新元素替换它们。即使这些元素现在与该选择器匹配,它们也不会绑定事件处理程序,因为执行此操作的代码已经执行。

事件处理程序

特别是对于事件处理程序(即.click()),您可以使用事件委托来解决这个问题。基本原则是将事件处理程序绑定到静态(页面加载时存在,永远不会被替换)元素,该元素将包含所有动态(AJAX 加载)内容。您可以在jQuery 文档中阅读有关事件委托的更多信息。

对于您的click事件处理程序,更新后的代码如下所示:

$(document).on('click', "#click", function () {
    $('#click').css({
        "background-color": "#f00",
        "color": "#fff",
        "cursor": "inherit"
    }).text("Open this window again and this message will still be here.");
    return false;
});

这会将事件处理程序绑定到整个文档(因此在页面卸载之前永远不会被删除),它将对click具有. 理想情况下,您会在 DOM 中使用更接近动态元素的东西(可能在您的页面上始终存在并包含您的所有页面内容),因为这会稍微提高效率。idclick<div>

但是,当您需要处理时,问题就来了.hover()。JavaScript 中没有实际的hover事件,jQuery 只是提供该函数作为将事件处理程序绑定到mouseentermouseleave事件的便捷简写。但是,您可以使用事件委托:

$(document).on({
    mouseenter: function () {
        $(this).stop().animate({
            width: xwidth * 3,
            height: xheight * 3,
            margin: -(xwidth / 3)
        }, 200); //END FUNCTION

        $(this).addClass('image-popout-shadow');
    },
    mouseleave: function () {
        $(this).stop().animate({
            width: xwidth,
            height: xheight,
            margin: 0
        }, 200, function () {
            $(this).removeClass('image-popout-shadow');
        }); //END FUNCTION

    }
}, '.image-popout img');

jQuery 插件

这涵盖了事件处理程序绑定。然而,这并不是你所做的全部。您还初始化了一个 jQuery 插件(颜色框),并且无法将它们委托给元素。加载 AJAX 内容后,您将不得不再次调用这些行;最简单的方法是将它们移动到一个单独的命名函数中,然后您可以在两个地方调用(在页面加载和 AJAX 请求success回调中):

function initialiseColorbox() {
    $(".iframe").colorbox({
        iframe: true,
        width: "1000px",
        height: "500px"
    });
    $(".inline").colorbox({
        inline: true,
        width: "50%"
    });
    $(".callbacks").colorbox({
        onOpen: function () {
            alert('onOpen: colorbox is about to open');
        },
        onLoad: function () {
            alert('onLoad: colorbox has started to load the targeted content');
        },
        onComplete: function () {
            alert('onComplete: colorbox has displayed the loaded content');
        },
        onCleanup: function () {
            alert('onCleanup: colorbox has begun the close process');
        },
        onClosed: function () {
            alert('onClosed: colorbox has completely closed');
        }
    });
}
于 2013-04-17T14:46:59.273 回答
29

在我找到适合我的解决方案之前遇到了同样的问题。因此,如果将来有人可以试一试,让我知道它是否正确,因为我能找到的所有解决方案都比这复杂一点。

正如 Tamer Durgun 所说,我们还将您的代码放在 ajaxStop 中,因此每次 ajax 完成任何事件时都会恢复您的代码。

$( document ).ajaxStop(function() {

//your code

}

为我工作:)

于 2016-05-08T07:18:37.607 回答
4
// EXAMPLE FOR JQUERY AJAX COMPLETE FUNC.
$.ajax({
    // get a form template first
    url: "../FPFU/templates/yeni-workout-form.html",
    type: "get",
    success: function(data){
        // insert this template into your container
        $(".content").html(data);
    },
    error: function(){
        alert_fail.removeClass("gizle");
        alert_fail.addClass("goster");
        alert_fail.html("Template getirilemedi.");
    },
    complete: function(){
        // after all done you can manupulate here your new content
        // tinymce yükleme
        tinymce.init({
            selector: '#workout-aciklama'
        });
    }
于 2016-03-30T07:49:20.610 回答
3

替换内容时,您的事件处理程序将丢失。当您设置hover事件时,jQuery 正在将它们设置在当前页面上的事件上。因此,当您将它们替换为 ajax 时,这些事件不会与这些元素相关联,因为它们是新的。

要解决此问题,您可以调用再次绑定它们的函数,也可以改为在文档上设置事件处理程序,如本答案中使用 $(document).on

这样,在文档上设置了事件,并且任何新元素都将调用该事件。

于 2013-04-17T14:42:38.780 回答
1

您可以使用 jQuery 的delegate()方法,该方法基于一组特定的根元素,将处理程序附加到现在或将来与选择器匹配的所有元素的一个或多个事件。在我的情况下,它按预期工作

这个$(selector).click(function(e){}

使用delegate()方法后变成这个

$( "body" ).delegate( "selector", "click", function(e) {}

希望这会有所帮助;)

于 2018-07-12T08:52:16.047 回答
0

只是一种选择。

$(window).on('load', _ => {
    // some jQuery code ..
})

这会将任何委托处理程序绑定到窗口。一旦窗口完全加载,它将触发,包括所有图形/包含/挂钩/请求,而不仅仅是 DOM。

$(document).ready(_ => ...保留仅在 DOM 准备好后触发的事件,这不适用于 AJAX 动态加载的内容。您可以在特定元素完全加载时运行函数或任何事件,方法是将其定义为@Anthony Grist 在他的答案中解释的,或者将加载事件绑定到窗口,如上所示。

https://api.jquery.com/load-event/
https://api.jquery.com/on/#on-events-selector-data-handler

于 2020-06-16T22:37:30.267 回答
0

我迟到了,但我会把两个答案结合起来。满足我特定需求的方法是将 ajaxstop 合并到完整的

complete: function () {
     $( document ).ajaxStop(function() {
         //now that all have been added to the dom, you can put in some code for your needs.
         console.log($(".subareafilterActive").get().length)

     })
}
于 2019-06-28T16:19:02.973 回答
0

您可以在某处检索数据表单后使用jQuery ajax的完整功能,它会在ajax完成后看到更新的元素

于 2016-03-28T14:03:54.913 回答
0

这对我有用,

代替:

$(document).ready(function(){
//code
});

我做了:

$(document).on('mouseenter', function(){
//code
});
于 2019-10-27T16:18:03.507 回答