我有一个带有无序列表的PHP页面。我有一些jQuery代码等待用户点击列表中的一个项目:
$(function() {
$('li.large_box').css('cursor', 'pointer')
.click(function() {
$('#db_sections').empty();
var show_id = this.id;
$.post('get_section_dates.php', { show_id: show_id }, function(sections) {
$('#section_dates_feedback').html(sections);
});
});
});
当用户点击其中一个项目时,jQuery代码将其id发送到一个php脚本,该脚本进行数据库查询并构建一个包含结果的下拉列表:
if (isset($_POST['show_id'])) {
$show_id = $_POST['show_id'];
$result = mysql_query("SELECT `id`,`air_date` FROM `daily_show` WHERE show_id = '".$show_id."'");
echo"<div id='dates_select'>";
echo "<select id='date_select'>";
echo "<option value='0'>Choose a date</option>";
while ($query = mysql_fetch_assoc($result))
{
$id = $query['id'];
$air_date = strtotime($query['air_date']);
$date = date("M-d-Y \(D\)",$air_date);
echo "<option value='$id'>$date</option>";
}
echo "</select>";
echo "</div>";
}
我第一次点击其中一个列表项时,一切都很快,下拉框正确显示。问题是,当我点击下一个列表项时,代码需要几秒钟来构建新的下拉列表而不是旧的下拉列表。每次点击不同的列表项都会增加构建下拉列表所需的时间,直到每次花费超过一分钟为止。
它查询的数据库表只有12条记录,通常它最多只返回1或2行。
我是PHP / jQuery的新手,并且想知道在我的代码中是否有任何明显的显而易见的事情会减慢这个过程。
感谢您查看我的问题!
答案 0 :(得分:1)
你应该考虑优化你的传输方法以及处理它的JS。
首先,您的脚本每次点击都会构建“胖”。也就是说,有过多的jQuery调用。你可以优化它:
$(function() {
//put into reference static elements
$db_sections = $('#db_sections');
$section_dates_feedback = $('#section_dates_feedback');
//delegate event to parent handler using .on()
$('the_containing_ul').on('click', 'li.large_box', function() {
$db_sections.empty();
$.post('get_section_dates.php', {
show_id: this.id
}, function(data) {
//callback
});
});
});
对于你的PHP回复,你应该至少使用JSON进行传输而不是HTML来使它变得轻松。您可以使用json_encode将PHP数组转换为JSON字符串以进行传输。
if (isset($_POST['show_id'])) {
$show_id = $_POST['show_id'];
$result = mysql_query(query_here);
$resultArray = mysql_fetch_assoc($result)
//do a little formatting before we send over
while ($resultArray){
$resultArray['air_date'] = date("M-d-Y \(D\)",strtotime($resultArray['air_date']));
}
echo json_encode($resultArray);
}
这将打印以下JSON字符串,这比打印HTML更好:
[
{"id":"1","air_date":"January 1, 12"},
{"id":"2","air_date":"January 2, 12"},
{"id":"3","air_date":"January 3, 12"},
... and so on
]
现在,在POST请求中,jQuery直观地将其转换为我们可以解析的JSON对象。您现在可以使用它来生成您的选择框。这将是回调:
function(data) {
//create a select and div, and append it to a div
$div = $('<div id="dates_select" />');
$select = $('<select id="date_select" />').appendTo($div);
//create options based on data and append to select
$.each(data,function(index,row){
$('<option />')
.attr('value',row.id)
.text(row.air_date)
.appendTo($select);
}
//put div into the feedback
$section_dates_feedback.html($div);
}
答案 1 :(得分:0)
听起来像是一个多重绑定问题。只是一个猜测,但也许你每次POST返回时都会将click功能添加到可点击项目中。因此,下次单击时,它将运行POST两次。然后三次。这每次都会添加一个新请求,每次都会添加冗余的DOM操作。
然而,在示例中看到的代码没有显示出再次点击绑定的明显迹象。所以尽管我有一个建议,但这是一个黑暗中的镜头。
(旁注:这里没有理由通过jQuery添加CSS。只需将此规则放入样式表中!我已将其从样本中删除了)
现在,我不知道你的标记,所以我打算安全地使用document
作为我建议的监听器,以帮助避免多重绑定。基本上,这里的第一个选择器理想地是一个永远不会作为Ajax调用的一部分被销毁的实际节点。它在第一页加载时呈现,然后再也不再呈现。例如,您可以使用$('#someContainer').on( /* ... */)
。我只会使用文档。
$(function() {
$(document).on('click', '.large_box', function() {
/* all the stuff that should happen on click */
});
});
现在,这是您在样本中所做的非常重要的事情,但可能不是。首次加载页面时,必须仅触发此文档就绪函数一次。一个真正的文档就绪功能,因为它是预期的。不要将它放在任何可能被解雇的函数中。
快速判断它是否被多次绑定是打开Firebug或Webkit开发人员工具......你会看到POST HTTP请求。如果一次点击多次被解雇,只需弄清楚为什么再次绑定它。