jQuery does not run the second time when a page is called via ajax
I am using jQuery to load the search results from a php class when the user enters a search term. The problem is that jQuery runs and executes the functions as required the first time round on the main page, but when the user enters a search keyword and the results are loaded from the class file on the same page via ajax, jQuery does not execute the function required.
What I want to do is, when the search results are loaded on the main page, it should only show the Quote and the author, not the arabic and reference. When the user clicks on the Quote, it should act like an accordian, toggling the div container of arabic and reference.
However, while jQuery works great loa开发者_JAVA技巧ding the results from the class file, it doesn't execute to hide the container of arabic and reference when it's loads the search results nor does it run the click event when the user clicks on the Quote to show the container, as firebug shows.
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();
The function in the class file which formats the search:
---SQL QUERY for SEARCH---
public function formatSearch($row, $search)
{
return "<div class=\"swrap\">"
. "<p id=\"s_quotes\"> " . $cQuote . " </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> " . $this->h($row['vAuthor']) . "</p></div>";
}
It's becasue your quote elements are being replaced, so you need to use .live()
or .delegate()
handler here, instead of this:
$("p#s_quotes").click(function() {
$(this).next("div#smore").slideToggle(200);
});
You need this:
$("p#s_quotes").live('click', function() {
$(this).next("div#smore").slideToggle(200);
});
Unlike .click()
which binds an event handler to the element, which is getting replaced...and so the event handler vanishes too, .live()
adds an event handler to document
which listens for a click from p#s_quotes
(this can be just #s_quotes
) to bubble up, and executes the handler if that happens.
For the hiding portion, either call $("#smore").hide();
again in your success
callback, or create them hidden, like this:
<div id=\"smore\" style='display: none;'>
The important thing to remember when you attach events on JQuery is that it is running at that moment, for the current state of the DOM, and will not necessarily apply for any elements that are added to the DOM in the future.
To attach events to objects that may not exist yet (along with items that already do exist, use the live()
function, like so:
$("p#s_quotes").live("click", function()
{
$(this).next("div#smore").slideToggle(200);
}),
By using live()
, jQuery will monitor for new elements as they are added to the DOM, and if they match your selectors, will apply the correct handler to them.
精彩评论