关于AJAX的两个问题


Two problems regarding AJAX

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

桌子上有一些按钮。当它们被点击时,它们会从打开切换到关闭(反之亦然),然后用AJAX调用另一个PHP文件,AJAX通过shell命令控制433MHz无线套接字。这10秒ajax刷新的目的是将按钮与电气插座的实际状态(保存在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:该表的内容将被删除并替换为新的内容。我是否可以以某种方式淡入新的线条(或按钮背景色),而不仅仅是显示它们?这将是最后的润色。

我希望你能理解我的解释。

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

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

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

jQuery解决这一问题的方法是使用.on()函数。使用的结构是不是很相似:

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

这里的区别在于实际获取与函数绑定的点击事件的元素。这样,click事件实际上被添加到body标记中,这与AJAX调用没有变化。动态元素的任何不变的公共父级都可以工作,'body'document通常用作默认值,因为它们是顶级的。

当任何子元素引发单击事件时,该事件会继续向上移动所有父元素。因此,它最终到达一个共同的父级,例如'body'.on()函数还有一个第二选择器作为它的第一个参数。该选择器在调用函数之前过滤单击事件的原始元素。

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

  • 只有一个事件处理程序函数附加到单个公共父级,而不是许多附加到许多元素,这可以提高大型或复杂页面的性能
  • 在页面寿命的后期添加到公共父元素的子元素仍将被处理,因为无论何时添加,它们仍将向父元素发送单击事件。(这对你的处境来说是立竿见影的好处。)

至于内容的淡入,如果我理解你想要达到的效果,你可以尝试一些方法,比如淡出已经存在的内容,删除它,添加新内容,然后淡入。也许是这样的:

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

对于相对较新的"promise"模型,可能会有较新的结构来完成同样的事情,但本质上,这是将内容淡出,然后包括一个回调函数,以便在内容淡出结束时调用。这个回调函数替换了HTML,然后将其淡入。根据HTML的结构,你可能需要淡出/进入父元素,而不是我想要的元素,但希望你能在这里得到这个想法,并可以调整它,直到它看起来正确。

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

尝试使用live()on()来绑定动态创建的元素。请参阅:动态创建的元素上的事件绑定?

问题2:使用html()#content被替换

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

我已经链接了hide()fadeIn()来动画附加。

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