通过 AJAX 加载内容后 jQuery 不起作用

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/16062899/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-26 16:19:10  来源:igfitidea点击:

jQuery doesn't work after content is loaded via AJAX

jqueryajax

提问by Awais Imran

On this pageI have a jQuery popup window and thumbnail resizable images. If I mouse over on the thumbnails, the images are resizing perfectly. Also, when I click on the big yellow TV button "QuickBook TV" in the footer, the popup appears perfectly as I want it to.

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

However, when I click on the "Next" or "Prev" buttons, AJAX is used to load the new content and my jQuery no longer functions for the popup or thumbnail images. I have searched a number of forums looking for information on this issue, but due to having limited knowledge of jQuery I've been unable to understand what I need to do.

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

Following is the popup 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;
        });
    });

And this is the thumbnails jQuery

这是缩略图 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

    }
);

});

回答by Anthony Grist

jQuery selectors select matching elements that exist in the DOM when the code is executed, and don't dynamically update. When you call a function, such as .hover()to add event handler(s), it only adds them to those elements. When you do an AJAX call, and replace a section of your page, you're removing those elements with the event handlers bound to them and replacing them with new elements. Even if those elements would now match that selector they don't get the event handler bound because the code to do that has already executed.

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

Event handlers

事件处理程序

Specifically for event handlers (i.e. .click()) you can use event delegation to get around this. The basic principle is that you bind an event handler to a static (exists when the page loads, doesn't ever get replaced) element which will contain all of your dynamic (AJAX loaded) content. You can read more about event delegation in the jQuery documentation.

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

For your clickevent handler, the updated code would look like this:

对于您的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;
});

That would bind an event handler to the entire document (so will never get removed until the page unloads), which will react to clickevents on an element with the idproperty of click. Ideally you'd use something closer to your dynamic elements in the DOM (perhaps a <div>on your page that is always there and contains all of your page content), since that will improve the efficiency a bit.

这将事件处理程序绑定到整个文档(所以永远不会删除,直到页面卸载),将反应click事件的元件上的id财产click。理想情况下,您应该使用更接近 DOM 中的动态元素的东西(也许<div>您的页面上始终存在并包含所有页面内容),因为这会稍微提高效率。

The issue comes when you need to handle .hover(), though. There's no actual hoverevent in JavaScript, jQuery just provides that function as a convenient shorthand for binding event handlers to the mouseenterand mouseleaveevents. You can, however, use event delegation:

但是,当您需要处理 时.hover(),问题就来了。hoverJavaScript 中没有实际的事件,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 plugins

jQuery 插件

That covers the event handler bindings. However, that's not all you're doing. You also initialise a jQuery plugin (colorbox), and there's no way to delegate those to elements. You're going to have to simply call those lines again when you've loaded your AJAX content; the simplest way would be to move those into a separate named function that you can then call in both places (on page load and in your AJAX requests successcallback):

这涵盖了事件处理程序绑定。然而,这并不是你所做的全部。您还初始化了一个 jQuery 插件(colorbox),并且无法将它们委托给元素。加载 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');
        }
    });
}

回答by Angad Arora

Had the same problem before I was able to found the solution which worked for me. So if anyone in future can give it a shot and let me know if it was right since all of the solutions I was able to find were a little more complicated than this.

在我找到对我有用的解决方案之前遇到了同样的问题。因此,如果将来有人可以试一试并告诉我它是否正确,因为我能够找到的所有解决方案都比这更复杂一些。

So as said by Tamer Durgun, we will also place your code inside ajaxStop, so your code will be reinstated each time any event is completed by ajax.

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

$( document ).ajaxStop(function() {

//your code

}

Worked for me :)

为我工作:)

回答by Tamer Durgun

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

回答by Schleis

Your event handlers are being lost when you replace the content. When you set you hoverevents, jQuery is setting them on the events on the page currently. So when you replace them with ajax, the events are not associated with those elements because they are new.

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

To fix this you can either call the function that binds them again or you can instead set the event handler on the document as in this answerusing $(document).on

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

That way the event is set on the document and any new elements will get the event called.

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

回答by Tamer Durgun

You can use jQuery ajax's complete function after retrieving data form somewhere, it will see updated elements after ajax complete

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

回答by dev_dodiya

You Can User jQuery's delegate()method which Attach a handler to one or more events for all elements that match the selector, now or in the future, based on a specific set of root elements.In my case it's working as expected

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

this $(selector).click(function(e){}

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

become this after Using delegate()method

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

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

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

Hope this will help ;)

希望这会有所帮助;)

回答by JQII

I'm late to the party but I would combine two of the answers. What worked for my specific needs was to incorporate the ajaxstop within the complete

我参加聚会迟到了,但我会结合两个答案。对我的特定需求有用的是将 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)
           
          })
        }

回答by RightGeek

This worked for me,

这对我有用,

instead of:

代替:

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

I did:

我做了:

$(document).on('mouseenter', function(){
//code
});