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

时间:2013-04-17 14:33:10

标签: jquery ajax

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

然而,当我点击“Next”或“Prev”按钮时,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

    }
);

});

9 个答案:

答案 0 :(得分:115)

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

活动处理程序

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

对于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属性为{{1}的元素上的id事件做出反应}}。理想情况下,您可以使用更接近DOM中动态元素的内容(可能是页面上始终存在的click并包含所有页面内容),因为这样可以提高效率。 / p>

但是,当您需要处理<div>时会出现问题。 JavaScript中没有实际的.hover()事件,jQuery只是将该函数提供为将事件处理程序绑定到hovermouseenter事件的便捷简写。但是,您可以使用事件委派:

mouseleave

jQuery插件

它涵盖了事件处理程序绑定。但是,这并不是你所做的全部。您还初始化了一个jQuery插件(colorbox),并且没有办法将它们委托给元素。当您加载了AJAX内容时,您将不得不再次调用这些行;最简单的方法是将它们移动到一个单独的命名函数中,然后可以在两个地方调用(在页面加载和AJAX请求$(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'); 回调中):

success

答案 1 :(得分:22)

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

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

$( document ).ajaxStop(function() {

//your code

}

为我工作:)

答案 2 :(得分: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'
                });
            }

答案 3 :(得分:3)

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

要解决此问题,您可以调用再次绑定它们的函数,也可以使用$(document).on

在此answer中设置文档上的事件处理程序。

这样就可以在文档上设置事件,任何新元素都会调用事件。

答案 4 :(得分:0)

你可以在某个地方检索数据后使用jQuery ajax的完整函数,它会在ajax完成后看到更新的元素

答案 5 :(得分:0)

您可以使用jQuery的delegate()方法,该方法根据一组特定的根元素将处理程序附加到一个或多个与选择器匹配的所有元素的事件,无论是现在还是将来。符合预期

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

使用delegate()方法后成为

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

希望这会有所帮助;)

答案 6 :(得分: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)
           
          })
        }

答案 7 :(得分:0)

这对我有用,

代替:

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

我做到了:

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

答案 8 :(得分:0)

只是一种选择。

from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from time import sleep
from selenium.common.exceptions import NoSuchElementException
import csv

driver = webdriver.Chrome("/Users/nzalle/Downloads/chromedriver")
driver.get("https://directory.bcsp.org/")
count = int(input("Number of Pages to Scrape: "))

body = driver.find_element_by_xpath("//body")
profile_count = driver.find_elements_by_xpath("//div[@align='right']/a")

while len(profile_count) < count:   # Get links up to "count"
    body.send_keys(Keys.END)
    sleep(1)
    profile_count = driver.find_elements_by_xpath("//div[@align='right']/a")

for link in profile_count:   # Calling up links
    temp = link.get_attribute('href')   # temp for
    driver.execute_script("window.open('');")    # open new tab
    driver.switch_to.window(driver.window_handles[1])   # focus new tab
    driver.get(temp)

    # Scrape Code
    Name = driver.find_element_by_xpath('/html/body/table/tbody/tr/td/table/tbody/tr/td[5]/div/table[1]/tbody/tr/td[1]/div[2]/div').text or driver.find_element_by_xpath('/html/body/table/tbody/tr/td/table/tbody/tr/td[5]/div/table[1]/tbody/tr/td[1]/div[2]/div').text

    IssuedBy = "Board of Certified Safety Professionals"

    CertificationNumber = driver.find_element_by_xpath('/html/body/table/tbody/tr/td/table/tbody/tr/td[5]/div/table[1]/tbody/tr/td[3]/table/tbody/tr[1]/td[3]/div[2]').text or driver.find_element_by_xpath('/html/body/table/tbody/tr/td/table/tbody/tr/td[5]/div/table[1]/tbody/tr/td[3]/table/tbody/tr[1]/td[3]/div[2]').text

    CertfiedSince = driver.find_element_by_xpath('/html/body/table/tbody/tr/td/table/tbody/tr/td[5]/div/table[1]/tbody/tr/td[3]/table/tbody/tr[3]/td[1]/div[2]').text or driver.find_element_by_xpath('/html/body/table/tbody/tr/td/table/tbody/tr/td[5]/div/table[1]/tbody/tr/td[3]/table/tbody/tr[3]/td[1]/div[2]')

    RecertificationCycleORExperation = driver.find_element_by_xpath('/html/body/table/tbody/tr/td/table/tbody/tr/td[5]/div/table[1]/tbody/tr/td[3]/table/tbody/tr[3]/td[3]/div[2]').text or driver.find_element_by_xpath('/html/body/table/tbody/tr/td/table/tbody/tr/td[5]/div/table[1]/tbody/tr/td[3]/table/tbody/tr[3]/td[3]/div[2]')

    try:
        AccreditedBy = driver.find_element_by_xpath('/html/body/table/tbody/tr/td/table/tbody/tr/td[5]/div/table[1]/tbody/tr/td[3]/table/tbody/tr[5]/td[3]/div[2]/a').text

    except NoSuchElementException:
        AccreditedBy = "N/A"

    try:
        Expires = driver.find_element_by_xpath('/html/body/table/tbody/tr/td/table/tbody/tr/td[5]/div/table[1]/tbody/tr/td[3]/table/tbody/tr[5]/td[1]/div[2]').text

    except NoSuchElementException:
        Expires = "N/A"

    Data = [Name + "," + IssuedBy + "," + CertificationNumber + "," + CertfiedSince + "," + RecertificationCycleORExperation + "," + Expires + "," + AccreditedBy + '\n']

    with open('data.csv', 'w', newline='') as csvfile:
        writer = csv.writer(csvfile)
        h = ["Name", "Issued By", "Certification Number", "Certified Since", "Recertification Cycle/Expiration",
             "Expires", "Accredited By"]
        writer.writerow(h)
        writer.writerow([Data] * len(h))
    driver.close()
    driver.switch_to.window(driver.window_handles[0])
driver.close()

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

$(window).on('load', _ => { // some jQuery code .. }) 保留仅在准备好DOM之后才触发的事件,而DOM不适用于AJAX动态加载的内容。通过将特定的元素定义为@Anthony Grist在其答案中解释的内容,可以在完全加载特定元素时运行函数或任何事件,也可以将加载事件绑定到窗口,如上所示。

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