当使用ajax调用页面时,jQuery第二次不会运行。

3
我正在使用jQuery从php类加载搜索结果,当用户输入搜索词时。问题是,当用户输入搜索关键字并通过ajax在同一页面上从类文件加载结果时,jQuery不执行所需的功能。
我想做的是,当搜索结果加载到主页面上时,它只应该显示引用和作者,而不是阿拉伯语和参考资料。当用户单击“引用”时,它应该像手风琴一样工作,切换阿拉伯语和参考的div容器。
然而,虽然jQuery在从类文件加载结果方面表现出色,但它不会隐藏阿拉伯语和参考容器,也不会在用户单击引用以显示容器时运行点击事件,正如firebug所显示的那样。
index.php:
    <script type="text/javascript">
    $(function() {

                $(".bsearch")
                    .keydown(function() {
                         //create post data
                          var postData = { 
                            "search" : $(this).val()
                          };

                          //make the call
                          $.ajax({
                            type: "POST",
                            url: "quotes_in.php",
                            data: postData, //send it along with your call
                            success: function(response){
                                $("#left").html(response);
                            }
                          });

                    }),




                $("div#smore").hide();
                    //toggle the componenet with class msg_body
                $("p#s_quotes").click(function()
                    {
                      $(this).next("div#smore").slideToggle(200);
                    }),         



                });

    </script> 

 <!-- Begin Left Column -->
        <div id="left">

        </div>
<!-- End Left Column -->

Quotes_in.php:

include_once "inc/class.quotes.inc.php";
$quotes = new Quotes($db);


if (isset($_POST['search'])) 
    $quotes->searchQuotes();

格式化搜索的类文件中的函数:

   ---SQL QUERY for SEARCH---
    public function formatSearch($row, $search) 
                {


                    return "<div class=\"swrap\">"
                    . "<p id=\"s_quotes\">&nbsp;" . $cQuote . "&nbsp;</p>"
                    . "<div id=\"smore\"><p id=\"s_arabic\">" . $this->h($row['cArabic']) . "</p>"
                    . "<p id=\"s_reference\"><span class=\"source\">Source:</span> " . $this->h($row['vReference']) . "</p></div>"
                    . "<p id=\"s_author\"><b>-</b>&nbsp;" . $this->h($row['vAuthor']) . "</p></div>"; 
                }
2个回答

6

这是因为您的引用元素正在被替换,所以您需要在此处使用.live().delegate()处理程序,而不是这样:

$("p#s_quotes").click(function() {
  $(this).next("div#smore").slideToggle(200);
});         

你需要这个:
$("p#s_quotes").live('click', function() {
  $(this).next("div#smore").slideToggle(200);
});    

.click()不同,它绑定了一个事件处理程序到元素,该元素正在被替换...因此,事件处理程序也会消失,.live()document添加一个事件处理程序,该程序侦听来自p#s_quotes(可以是仅仅#s_quotes)的点击事件冒泡,并在发生时执行处理程序。

对于隐藏部分,你可以在success回调中再次调用$("#smore").hide();,或者将它们创建为隐藏的,像这样:

<div id=\"smore\" style='display: none;'>

3

在使用JQuery附加事件时需要记住的重要事情是它正在运行,对于DOM的当前状态,并不一定适用于将来添加到DOM中的任何元素。

要为尚不存在的对象附加事件(以及已经存在的项目),请使用live()函数,例如:

        $("p#s_quotes").live("click", function()
                {
                  $(this).next("div#smore").slideToggle(200);
                }),

通过使用live(),jQuery将监视DOM中添加的新元素,并且如果它们与您的选择器匹配,就会对它们应用正确的处理程序。

这是不正确的,.live() 不会监听新元素或应用处理程序,它以完全不同的方式工作,请参阅我的答案进行简要描述。 - Nick Craver
@Nick Craver - 不冒犯,但Ryan Brunner说了你说的一模一样的话,只是表达方式不够娴熟和专业,不过他也是正确的,而你也是。 - SimonDowdles
@Webfac - 不,他没有,这部分是不正确的:“jQuery将监视添加到DOM中的新元素,如果它们与您的选择器匹配,将为它们应用正确的处理程序”。我说它会向document附加一个事件处理程序,这是正确的。它不会以任何方式查找新元素并附加处理程序。 - Nick Craver
好的 - 我没有意识到这是如何在内部实现的。然而,从功能上来说,它等同于将事件处理程序附加到新元素。 - Ryan Brunner
@Ryan - 有几个原因,它并不是这样的。事件冒泡会对.live()产生不同的影响,例如在事件到达document之前停止事件的任何内容,还有几个可能很重要的区别。你所想的是.live()之前的.livequery()插件,它确实会寻找新元素并附加处理程序。 - Nick Craver
我其实并不知道liveQuery插件,我只是在描述非边缘情况下大多数功能行为。甚至jQuery.com也将live()描述为“为所有与当前选择器匹配的元素附加一个处理程序,现在或将来。”对于初学者来说,这比实际实现更容易理解live()的功能。 - Ryan Brunner

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接