关于AJAX的两个问题

时间:2013-07-27 00:13:36

标签: php jquery ajax

我创建了一个由php databasequery填充的页面(所有行都从MySQL表中读取并以HTML格式写入表中)。整个10秒jQuery AJAX请求相同的PHP脚本,并应刷新当前的表内容。然后,此函数的返回值将用于更改表HTML值。

表格中有一些按钮。当它们被点击时,它们从开启切换到关闭(反之亦然),另一个PHP文件被AJAX调用,然后AJAX通过shell命令控制433MHz无线套接字。这些10秒ajax-refresh的目的是使按钮与电插座的实际状态同步(保存在MySQL数据库中)。

$(document).ready(function(){
  $(".toggle").click(function() {
    if($(this).hasClass("ein")) {
      $(this).removeClass("ein");
      $(this).html("aus");
      $.post("various/executeCode.php", {transmitted:true, id:$(this).attr('id'),  toggle:'0'}, function(result) {
      });
    } else {
      $(this).addClass("ein");
      $(this).html("ein");
      $.post("various/executeCode.php", {transmitted:true, id:$(this).attr('id'), toggle:'1'}, function(result) {
      });
     }
  });
});


window.setInterval("reloadPage()", 5000);
function reloadPage()
  {
    $.get('various/reloadPage.php', function(data) {
      $("#content").html(data);
  });
}

$stmt = $dbh->query("SELECT * FROM `funksteckdosen`");
$row = $stmt->fetchAll(PDO::FETCH_ASSOC);
foreach($row as $r)
{  
  echo "<tr>";  
  echo "  <td>" . $r['name'] . "</td>";  
  echo "    <td><button id='" . $r['id'] . "' class='toggle" . ($r['toggle'] == 0 ? "" : " ein") . "'>"     
    . ($r['toggle'] == 0 ? "aus" : " ein") . "</button></td>";  
  echo "</tr>";
}  

现在我遇到以下问题:第一次页面被AJAX刷新时,按钮就会停止工作。 Javascript不再执行click() - 函数。这是为什么? 问题2: 表的内容将被删除并替换为新表。我可以以某种方式淡化新线条(或按钮背景颜色),而不仅仅是显示它们吗?那将是最后的接触。

我希望你理解我的解释。

2 个答案:

答案 0 :(得分:0)

点击处理程序不再起作用,因为新按钮从未连接过处理程序。当您附加这样的处理程序时:

$(".toggle").click(function() {

jQuery所做的是找到所有当前存在的 .toggle元素,并为每个元素添加该函数作为处理程序。由于后来通过AJAX调用添加了新的,因此它们不包含在该集合中,因此从未将该函数附加到它们。

jQuery解决这个问题的方式是使用the .on() function。使用的结构非常相似:

$('body').on('.toggle', 'click', function() {

这里的区别是实际上将click事件绑定到函数的元素。有了这个,click事件实际上被添加到body标记中,而不是从AJAX调用中更改。动态元素的任何不变的共同父级都可以使用,'body'document通常用作默认值,因为它们非常顶级。

当任何子元素引发click事件时,该事件将继续所有父元素。因此它最终到达了一个共同的父母,例如'body'。然后.on()函数还有第二个选择器作为其第一个参数。该选择器在调用函数之前过滤click事件的原始元素。

使用这种方法的好处包括:

  • 只有一个事件处理函数附加到单个公共父级,而不是附加到许多元素的许多元素,这可能是对大型或复杂页面的性能改进。
  • 仍在处理页面生命周期后期添加到公共父元素的子元素,因为无论何时添加它们,它们仍会将其点击事件发送给父元素。 (在您的情况下,这是直接的好处。)

至于内容的淡化,如果我理解你想要实现的效果,你可以尝试淡出已经存在的东西,删除它,添加新内容,然后淡入它。可能像这样:

$.get('various/reloadPage.php', function(data) {
    $('#content').fadeOut(400, function() {
        $("#content").html(data);
        $('#content').fadeIn();
    });
});

可能有更新的结构用相对较新的“promises”模型完成同样的事情,但实际上它的作用是淡化内容,然后包括一个回调函数,当它完成淡出时调用。该回调函数取代了HTML,然后将其淡入。根据HTML的结构,您可能需要淡出/在父元素中而不是我要定位的那个元素,但希望您能在这里得到这个想法可以调整它直到看起来正确。

答案 1 :(得分:0)

问题1:click事件处理程序绑定到初始切换类元素,但动态创建的事件未绑定。

尝试使用live()on()绑定动态创建的元素。请参阅:Event binding on dynamically created elements?

问题2:使用#content

时会替换html()

尝试使用append()将数据添加到现有元素中。使用html()将替换元素的内容。

我链接了一个hide()和一个fadeIn()来为追加设定动画。

$('#content').append(data).hide().fadeIn(1000);