使jquery .on函数与AJAX加载的内容一起工作

时间:2022-07-06 00:00:30

I am having trouble getting an .on 'click' function to work upon AJAX loaded content.

我在获取.on“click”函数以处理AJAX加载的内容时遇到了麻烦。

I have worked with the jquery .live before but this is the first time with .on and understand it works in the exact same way so unsure why I am having problems.

我曾经使用过jquery .live,但这是我第一次使用。on,并理解它的工作方式是完全一样的,所以我不确定为什么会有问题。

Below is the HTML that gives the element to which you click on

下面是给您单击的元素的HTML

    <h1>Press &amp; Media</h1>
    <div id="back"></div>
    <div id="overlay-content">
        <span id="edocs" class="tab"></span>
        <span id="news" class="tab"></span>
        <span id="partners" class="tab"></span>
    </div>

Below is the function that loads the AJAX content.

下面是加载AJAX内容的函数。

    $("#overlay-content").on('click','#news',function() {
        var active = 1;
        $("#loading").show();
        $("#overlay-content").fadeOut(1000, function() {
            $.get("http://<? echo ROOT; ?>includes/functions.php", { pressmediaNews: active }, function(data) {
                $("#loading").hide(400);
                $("#overlay-content").empty().append(data).fadeIn(1000);
            });
        });
    });

This should load the following HTML

这将加载以下HTML

    <div id="news-left-panel">
        <h4>News Section</h4>
        <ul>
            <li id="newsID2" class="newsYear">
                <p>2012</p>
                <ul class="newsMonths" style="display:none">
                    <li>Jan
                        <ul class="newsArticles" style="display:none">
                            <li onClick="newsID(2)">test</li>
                        </ul>
                    </li>
                    <li>Feb</li>
                    <li>Mar</li>
                </ul>
            </li>
            <li id="newsID1" class="newsYear">
                <p>2011</p>
                <ul class="newsMonths" style="display:none">
                    <li>Dec
                        <ul class="newsArticles" style="display:none">
                            <li onClick="newsID(1)">Test</li>
                        </ul>
                    </li>
                </ul>
            </li>
        </ul>
    </div>

Now the above code simply wont execute, show any errors etcetera in firebug.

现在上面的代码不能执行,在firebug中显示任何错误等等。

So I'm a bit lost as to why it wont execute, the alert() even does not execute.

所以我有点迷失了为什么它不会执行,alert()甚至没有执行。

7 个解决方案

#1


36  

First make sure you're hitting the target, try this and see if the alert shows :

首先,确保你击中了目标,试试这个,看看警报是否显示:

$(function() {
    $(document).on('click', '#news', function() {
       alert('ok');
    });
});

If the alert shows when clicking the #news element, it's ok.

如果在单击#news元素时显示警告,则可以。

Now to this line:

现在这条线:

$.get("http://<? echo ROOT; ?>includes/functions.php",

You are using the shorthand PHP opening, and that needs to be turned on, you could try

您正在使用速记PHP打开,需要打开它,您可以尝试

<?php echo ROOT; ?>

But what the frack is ROOT, never seen that before, and could not find anything in the PHP manual on ROOT, so I tried on my own server with the newest version of PHP, and got an error as 'ROOT' does not exist, instead it assumed it was a string and just echo'ed "ROOT", so your link would look like:

裂解是根,从未见过,,,找不到任何PHP手册中的根,所以我试着在自己的服务器上的最新版本PHP,和有一个错误“根”不存在,相反,它认为它是一个字符串“回声”“根”,所以你的链接看起来像:

$.get("http://ROOTincludes/functions.php",

It it's a variable you have defined somewhere yourself, it should start with a dollarsign, if it's something you've defined with define(), make sure it's set up correctly and if it's using something like $_SERVER['DOCUMENT_ROOT']; that's not always something you can access in javascript as it will normally be a folder that is higher then your webroot, and can't be accessed on the clientside but only on the serverside.

它是一个你自己定义的变量,它应该以一个dollarsign开始,如果它是你用define()定义的,确保它设置正确如果它使用$_SERVER['DOCUMENT_ROOT'];在javascript中,这并不总是可以访问的,因为它通常是一个高于webroot的文件夹,不能在客户端访问,只能在服务器端访问。

Also, the way you have written it, starting with http:// it should be a domain name. Try opening view source in you browser and find your ajax function and see what ROOT actually outputs, as the final ouput will be visible in the source, and if it's set using define() in an included config file etc. you can see that it was set up correctly.

而且,从http://它应该是一个域名开始。尝试在浏览器中打开视图源代码,并找到ajax函数,并查看根实际输出的内容,因为最终的ouput将在源代码中可见,如果它在包含的配置文件中使用define()设置,您可以看到它是正确设置的。

Your javascript would also have to be inside a PHP file for PHP to execute, or you would have to modify your server setup to run JS files thru PHP.

您的javascript也必须在PHP文件中才能执行,或者您需要修改服务器设置来运行JS文件。

In my opinion just using a path and filename is the right way to do it, try this and pay attention to the console (F12) :

在我看来,使用路径和文件名是正确的方法,请尝试并注意控制台(F12):

$(document).on('click','#news',function() {
    var active = 1;
    var XHR = $.ajax({
                   type: 'GET',
                   url : '/actualpath/includes/functions.php',
                   data: { pressmediaNews: active }
              }).done(function(data) {
                   console.log(data);
              }).fail(function(e1, e2, e3) {
                   console.log('error : '+e1+' - '+e2+' - '+e3);
              });
    $("#loading").show();
    $("#overlay-content").fadeOut(1000, function() {
        XHR.done(function(data) {
            $("#overlay-content").empty().append(data).fadeIn(1000);
            $("#loading").hide(400);
        });
    });
});

#2


10  

Use a delegate:

使用一个委托:

$('#overlay-content').on('click', '#newsID2', function() { });

This will bind the event on #overlay-content and check for bubbled events if they originated from #newsID2.

这将绑定#overlay-content上的事件,并检查冒泡事件是否源自#newsID2。


As a side-note: You have a typo in your event handler (chikdren should be children) and you should really get rid of this ugly onClick inline event.

作为一个旁注:您在事件处理程序中有一个输入错误(chikdren应该是儿童),您应该真正摆脱这个难看的onClick内联事件。

#3


4  

Should be more like:

应该更像:

$("#overlay-content").on('click', '#newsID2', function() {
    ....
});

Or in other words:

或者换句话说:

$('.wrapper').on('event', '.target', function() {
    ...
});

Where .wrapper is an element that already exists (or the document), and .target is the element(s) inside the wrapper you want to run the event on.

其中.wrapper是一个已经存在(或文档)的元素,而.target是你想要运行事件的包装器中的元素。

The live function is basically equivalent to:

活函数基本等价于:

$(document).on('event', '.target', function() { 
    ... 
});

#4


3  

http://bugs.jquery.com/ticket/11203

http://bugs.jquery.com/ticket/11203

Key sentence

关键句子

If new HTML is being injected into the page, select the elements and attach event handlers after the new HTML is placed into the page.

如果新的HTML被注入到页面中,选择元素并在新的HTML被放置到页面之后附加事件处理程序。

To work with this scenario try binding to the document object with a selector parameter:

要使用此场景,请尝试使用选择器参数绑定到文档对象:

$(document).on('click','#news',function() {...}

#5


0  

Since you said that you have previously worked with .live() could the issue here be that you're trying to bind your click on something that you append to the document before you append it?

既然您说过您以前使用过。live(),那么这里的问题是您试图在添加文档之前将单击添加到文档的内容绑定在一起吗?

When you use live, it handles this sort of stuff automatically, but when you don't use live, things generally have to exist on the page before you bind any events to them. If you add something with AJAX, you can't set up click events for those things before you've loaded them in with AJAX. When you use .live() you can do this ahead of time.

当您使用live时,它会自动处理这类内容,但是当您不使用live时,在您将任何事件绑定到它们之前,这些内容通常必须存在于页面上。如果您使用AJAX添加了一些东西,那么在将它们加载到AJAX之前,您无法为它们设置单击事件。当你使用.live()时,你可以提前做这件事。

I would do it like this:

我会这样做:

$("#overlay-content").on('click','#news',function() {
        var active = 1;
        $("#loading").show();
        $("#overlay-content").fadeOut(1000, function() {
            $.get("http://<? echo ROOT; ?>includes/functions.php", { pressmediaNews: active }, function(data) {
                $("#loading").hide(400);
                $("#overlay-content").empty().append(data).fadeIn(1000);

                //put your delegate/call/function,etc here

            });
        });
    });

#6


0  

News-left-panel

year_Month_newsID Your News's Year, Month, News ID. For example 2012_5_16, 2012_5_17 etc

year_Month_newsID您的新闻的年份、月份、新闻ID。例如2012_5_16、2012_5_17等

<div id="news-left-panel">
    <h4>News Section</h4>
    <ul>
        <li id="newsID2" class="newsYear">
            <p>2012</p>
            <ul class="newsMonths" style="display:none">
                <li>Jan
                    <ul class="newsArticles" style="display:none">
                        <li id="year_Month_newsID">test</li>
                    </ul>
                </li>
                <li>Feb</li>
                <li>Mar</li>
            </ul>
        </li>
        <li id="newsID1" class="newsYear">
            <p>2011</p>
            <ul class="newsMonths" style="display:none">
                <li>Dec
                    <ul class="newsArticles" style="display:none">
                        <li id="year_Month_newsID">Test</li>
                    </ul>
                </li>
            </ul>
        </li>
    </ul>
</div>

Jquery Function

$("#news-left-panel ul li").live("click", function(event) {
            var news=(this.id).split("_");
            var year=news[0];
            var month=news[1];
            var newsID =news[2];

            $.ajax({
                type: "POST",
                url: 'http://<? echo ROOT; ?>includes/functions.php',
                data: {
                    year: year,month:month,newsID :newsID
                },
                error: function(){
                    $('#news').html( "<p>Page Not Found!!</p>" );
                    // Here Loader animation
                },
                beforeSend: function(){
                    // Here Loader animation
                    $("#news").html('');
                },
                success: function(data) {
                    $('#news').html(data);

                }
            });
        });​

#7


0  

Are you sure your Ajax call is correct / returning the right HTML?

您确定您的Ajax调用是正确的/返回正确的HTML吗?

I replaced $.get() with setTimeout() (and simplified a bit) here: http://jsfiddle.net/q23st/

我在这里用setTimeout()替换了$.get()(并简化了一点):http://jsfiddle.net/q23st/

It seems to work, so I suspect your $.get() isn't returning what it's expected to return.

它似乎起作用了,所以我怀疑你的$.get()并没有返回它预期返回的值。

#1


36  

First make sure you're hitting the target, try this and see if the alert shows :

首先,确保你击中了目标,试试这个,看看警报是否显示:

$(function() {
    $(document).on('click', '#news', function() {
       alert('ok');
    });
});

If the alert shows when clicking the #news element, it's ok.

如果在单击#news元素时显示警告,则可以。

Now to this line:

现在这条线:

$.get("http://<? echo ROOT; ?>includes/functions.php",

You are using the shorthand PHP opening, and that needs to be turned on, you could try

您正在使用速记PHP打开,需要打开它,您可以尝试

<?php echo ROOT; ?>

But what the frack is ROOT, never seen that before, and could not find anything in the PHP manual on ROOT, so I tried on my own server with the newest version of PHP, and got an error as 'ROOT' does not exist, instead it assumed it was a string and just echo'ed "ROOT", so your link would look like:

裂解是根,从未见过,,,找不到任何PHP手册中的根,所以我试着在自己的服务器上的最新版本PHP,和有一个错误“根”不存在,相反,它认为它是一个字符串“回声”“根”,所以你的链接看起来像:

$.get("http://ROOTincludes/functions.php",

It it's a variable you have defined somewhere yourself, it should start with a dollarsign, if it's something you've defined with define(), make sure it's set up correctly and if it's using something like $_SERVER['DOCUMENT_ROOT']; that's not always something you can access in javascript as it will normally be a folder that is higher then your webroot, and can't be accessed on the clientside but only on the serverside.

它是一个你自己定义的变量,它应该以一个dollarsign开始,如果它是你用define()定义的,确保它设置正确如果它使用$_SERVER['DOCUMENT_ROOT'];在javascript中,这并不总是可以访问的,因为它通常是一个高于webroot的文件夹,不能在客户端访问,只能在服务器端访问。

Also, the way you have written it, starting with http:// it should be a domain name. Try opening view source in you browser and find your ajax function and see what ROOT actually outputs, as the final ouput will be visible in the source, and if it's set using define() in an included config file etc. you can see that it was set up correctly.

而且,从http://它应该是一个域名开始。尝试在浏览器中打开视图源代码,并找到ajax函数,并查看根实际输出的内容,因为最终的ouput将在源代码中可见,如果它在包含的配置文件中使用define()设置,您可以看到它是正确设置的。

Your javascript would also have to be inside a PHP file for PHP to execute, or you would have to modify your server setup to run JS files thru PHP.

您的javascript也必须在PHP文件中才能执行,或者您需要修改服务器设置来运行JS文件。

In my opinion just using a path and filename is the right way to do it, try this and pay attention to the console (F12) :

在我看来,使用路径和文件名是正确的方法,请尝试并注意控制台(F12):

$(document).on('click','#news',function() {
    var active = 1;
    var XHR = $.ajax({
                   type: 'GET',
                   url : '/actualpath/includes/functions.php',
                   data: { pressmediaNews: active }
              }).done(function(data) {
                   console.log(data);
              }).fail(function(e1, e2, e3) {
                   console.log('error : '+e1+' - '+e2+' - '+e3);
              });
    $("#loading").show();
    $("#overlay-content").fadeOut(1000, function() {
        XHR.done(function(data) {
            $("#overlay-content").empty().append(data).fadeIn(1000);
            $("#loading").hide(400);
        });
    });
});

#2


10  

Use a delegate:

使用一个委托:

$('#overlay-content').on('click', '#newsID2', function() { });

This will bind the event on #overlay-content and check for bubbled events if they originated from #newsID2.

这将绑定#overlay-content上的事件,并检查冒泡事件是否源自#newsID2。


As a side-note: You have a typo in your event handler (chikdren should be children) and you should really get rid of this ugly onClick inline event.

作为一个旁注:您在事件处理程序中有一个输入错误(chikdren应该是儿童),您应该真正摆脱这个难看的onClick内联事件。

#3


4  

Should be more like:

应该更像:

$("#overlay-content").on('click', '#newsID2', function() {
    ....
});

Or in other words:

或者换句话说:

$('.wrapper').on('event', '.target', function() {
    ...
});

Where .wrapper is an element that already exists (or the document), and .target is the element(s) inside the wrapper you want to run the event on.

其中.wrapper是一个已经存在(或文档)的元素,而.target是你想要运行事件的包装器中的元素。

The live function is basically equivalent to:

活函数基本等价于:

$(document).on('event', '.target', function() { 
    ... 
});

#4


3  

http://bugs.jquery.com/ticket/11203

http://bugs.jquery.com/ticket/11203

Key sentence

关键句子

If new HTML is being injected into the page, select the elements and attach event handlers after the new HTML is placed into the page.

如果新的HTML被注入到页面中,选择元素并在新的HTML被放置到页面之后附加事件处理程序。

To work with this scenario try binding to the document object with a selector parameter:

要使用此场景,请尝试使用选择器参数绑定到文档对象:

$(document).on('click','#news',function() {...}

#5


0  

Since you said that you have previously worked with .live() could the issue here be that you're trying to bind your click on something that you append to the document before you append it?

既然您说过您以前使用过。live(),那么这里的问题是您试图在添加文档之前将单击添加到文档的内容绑定在一起吗?

When you use live, it handles this sort of stuff automatically, but when you don't use live, things generally have to exist on the page before you bind any events to them. If you add something with AJAX, you can't set up click events for those things before you've loaded them in with AJAX. When you use .live() you can do this ahead of time.

当您使用live时,它会自动处理这类内容,但是当您不使用live时,在您将任何事件绑定到它们之前,这些内容通常必须存在于页面上。如果您使用AJAX添加了一些东西,那么在将它们加载到AJAX之前,您无法为它们设置单击事件。当你使用.live()时,你可以提前做这件事。

I would do it like this:

我会这样做:

$("#overlay-content").on('click','#news',function() {
        var active = 1;
        $("#loading").show();
        $("#overlay-content").fadeOut(1000, function() {
            $.get("http://<? echo ROOT; ?>includes/functions.php", { pressmediaNews: active }, function(data) {
                $("#loading").hide(400);
                $("#overlay-content").empty().append(data).fadeIn(1000);

                //put your delegate/call/function,etc here

            });
        });
    });

#6


0  

News-left-panel

year_Month_newsID Your News's Year, Month, News ID. For example 2012_5_16, 2012_5_17 etc

year_Month_newsID您的新闻的年份、月份、新闻ID。例如2012_5_16、2012_5_17等

<div id="news-left-panel">
    <h4>News Section</h4>
    <ul>
        <li id="newsID2" class="newsYear">
            <p>2012</p>
            <ul class="newsMonths" style="display:none">
                <li>Jan
                    <ul class="newsArticles" style="display:none">
                        <li id="year_Month_newsID">test</li>
                    </ul>
                </li>
                <li>Feb</li>
                <li>Mar</li>
            </ul>
        </li>
        <li id="newsID1" class="newsYear">
            <p>2011</p>
            <ul class="newsMonths" style="display:none">
                <li>Dec
                    <ul class="newsArticles" style="display:none">
                        <li id="year_Month_newsID">Test</li>
                    </ul>
                </li>
            </ul>
        </li>
    </ul>
</div>

Jquery Function

$("#news-left-panel ul li").live("click", function(event) {
            var news=(this.id).split("_");
            var year=news[0];
            var month=news[1];
            var newsID =news[2];

            $.ajax({
                type: "POST",
                url: 'http://<? echo ROOT; ?>includes/functions.php',
                data: {
                    year: year,month:month,newsID :newsID
                },
                error: function(){
                    $('#news').html( "<p>Page Not Found!!</p>" );
                    // Here Loader animation
                },
                beforeSend: function(){
                    // Here Loader animation
                    $("#news").html('');
                },
                success: function(data) {
                    $('#news').html(data);

                }
            });
        });​

#7


0  

Are you sure your Ajax call is correct / returning the right HTML?

您确定您的Ajax调用是正确的/返回正确的HTML吗?

I replaced $.get() with setTimeout() (and simplified a bit) here: http://jsfiddle.net/q23st/

我在这里用setTimeout()替换了$.get()(并简化了一点):http://jsfiddle.net/q23st/

It seems to work, so I suspect your $.get() isn't returning what it's expected to return.

它似乎起作用了,所以我怀疑你的$.get()并没有返回它预期返回的值。