且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

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

更新时间:2023-08-22 21:05:22

jQuery选择存在于DOM时执行的code,也不要动态更新选择匹配的元素。当你调用一个函数,如 .hover()添加事件处理程序(S),它只是将它们添加到这些元素。当你做一个AJAX调用,并更换页面的一部分,您删除绑定到这些事件处理程序的元素和新的元素替换它们。即使这些元素现在将匹配选择他们没有得到事件处理程序的约束,因为code要做到这一点已经执行。

事件处理程序

具体的事件处理程序(即。点击()),可以使用事件代理来解决这个问题。其基本原理是,你的事件处理程序绑定到一个静态的(存在在页面加载时,不会永远被替换),其中将包含所有的动态元素(AJAX加载)的内容。您可以在 jQuery的文档阅读更多有关事件的代表团。

有关你的点击事件处理程序,更新code是这样的:

  $(文件)。在(点击,#点击功能(){
    $('#点击)。CSS({
        背景颜色:#F00,
        色:#FFF
        光标:继承
    })文本(再次打开这个窗口,这个消息仍然会在这里。);
    返回false;
});
 

这将事件处理程序绑定到整个文档(因此将永远不会删除,直到页面卸载),这将反应点击与元素事件 ID 点击。理想情况下,你会使用的东西更贴近于DOM的动态元素(可能是一个< D​​IV> 您的网页上是永远存在的,并包含所有页面内容)因为这将提高效率一点。

当你需要处理 .hover(),但问题来了。有没有实际的悬停事件在JavaScript中,jQuery的只是提供了功能作为一种方便的简写事件处理程序绑定到的mouseenter 鼠标离开事件。你可以,但是,使用事件委派:

  $(文件)。在({
    的mouseenter:函数(){
        $(本).stop()。动画({
            宽度:xwidth * 3,
            身高:xheight * 3,
            保证金: - (xwidth / 3)
        },200); // END FUNCTION

        $(本).addClass(图像的弹出阴影');
    },
    鼠标离开:函数(){
        $(本).stop()。动画({
            宽度:xwidth,
            身高:xheight,
            保证金:0
        },200,函数(){
            $(本).removeClass(图像的弹出阴影');
        }); // END FUNCTION

    }
},在图像配-的弹出IMG');
 


jQuery插件

这涵盖了事件处理程序绑定。然而,这还不是全部,你正在做的。您还初始化一个jQuery插件(颜色框),而且也没有办法委托那些元素。你将不得不只需再次调用这些行,当你加载了AJAX的内容;最简单的方法是将这些到一个单独的命名函数,然后可以在这两个地方调用(在页面加载,并在你的AJAX请求成功回调):

 函数initialiseColorbox(){
    $(IFRAME)。颜色框({
        IFRAME:真正的,
        宽度:1000px,
        高度:500px的
    });
    $(内联)。颜色框({
        内联:真正的,
        宽:50%
    });
    $(。回调)。颜色框({
        的OnOpen:函数(){
            警报('的OnOpen:颜色框即将开启');
        },
        的onLoad:函数(){
            警报('的onLoad:颜色框已开始加载有针对性的内容');
        },
        的onComplete:函数(){
            警报('的onComplete:颜色框已经显示加载的内容');
        },
        onCleanup:函数(){
            警报('onCleanup:颜色框已经开始了密切的进程');
        },
        onClosed:函数(){
            警报('onClosed:颜色框已经完全封闭');
        }
    });
}
 

On this page I 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.

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.

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

$(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

    }
);

});

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.

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.

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

$(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 click events on an element with the id property 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.

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

$(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

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 success callback):

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