长轮询更新DOM同时保留jQuery的累积属性

Jim*_*150 5 html javascript php jquery json

编辑:一切正常; 推动工作.唯一的问题是每次推送时#load_info div都会重置为空.我如何保留其中的原始内容div,尽管在重新推送XML文件时内容将是其自身的更新版本.

我有一个PHP脚本,用于长时间轮询XML文件并将其编码为JSON数组.它从前端调用JSON作为参数.

    $filename= dirname(__FILE__)."/people.xml";

    $lastmodif = isset( $_GET['timestamp'])? $_GET['timestamp']: 0 ;
    $currentmodif=filemtime($filename);

    while ($currentmodif <= $lastmodif) {
        usleep(10000);
        clearstatcache();
        $currentmodif =filemtime($filename);
    }

    $response = array();
    $xObj = simplexml_load_file($filename);

    // Loop for #loadMe.
    foreach($xObj as $person){
        $concat_buttons .= "<button class='mybutton' value='" . (string)$person->id . " '> " . (string)$person->fullName . "</button>";
    }

    // Loop for #toadMe.
    foreach($xObj as $person){
        $concat_info .= "<div class='div div_' data-person-id='" . (string)$person->id . "' id='" . (string)$person->id . "'><h1> " . (string)$person->job . "</h1></div>";
    }


    // Output for AJAX.
    $response['msg']                = $concat_buttons;
    $response['msg2']                = $concat_info;
    $response['timestamp']      = $currentmodif;
    echo json_encode($response);
Run Code Online (Sandbox Code Playgroud)

然后我有一个jQuery脚本用于实例化JSON对象(msg2)以将每个节点附加到一个div被调用的节点中#load_data.我的问题是为什么下面的jQuery不起作用?我的猜测是$(window).findget_person(id)函数中没有工作和/或我的函数超出了轮询的范围.需要注意的是,在我开始尝试合并show_person()get_person()函数之前,PHP和JS是100%正常工作的.按照#load_button div单击中的某个按钮的方式工作,它将切换一条信息的视图,其中一个信息的视图与id按钮的value属性匹配.show(),最初是隐藏的; 然后,如果单击另一个按钮,将隐藏旧信息.hide()并显示新数据.这是我的循环解决方案,使用长轮询来更新DOM元素,只需在开始时加载它们,但是如果在新的轮询发生时显示一条信息(var timestamp得到更新),那么内部的元素#load_info将是暂时从DOM中丢失,因此在#load_info div单击下一个按钮之前会导致空.所以我试图添加一些额外的函数来存储内部的DOM数据,var $person这样在一次民意调查之后,先前显示的内容将重新出现.可以更改或添加什么来使这个jQuery脚本按预期工作?提前致谢!

    var timestamp=null;
    function waitForMsg() {
        $.ajax({
            type: "GET",
            url: "getData.php?timestamp="+timestamp,
            async: true,
            cache: false,        
            success: function(data) {
                var json=eval('('+data+ ')');
                if (json['msg'] != "") {
                    $("#load_buttons").empty();
                    $("#load_buttons").append(json['msg']);

                    // Update any person divs that were already visible.
                    $('#load_info .person').each(function() {
                        // Grabs the ID from data-person-id set earlier.
                        var id = $(this).data('person-id');
                        show_person(id);
                    });

                }
                timestamp = json["timestamp"];
                setTimeout("waitForMsg()",1000);
            },
            error: function(XMLHttpRequest,textStatus,errorThrown) {
                setTimeout("waitForMsg()",15000);
            }                   
        });
    }

    $(document).on('click', '.mybutton', function() {
        $('#load_info').empty();
        show_person(this.value);
    });

    function show_person(id) {
        $('#person-detail-' + id).remove();
        get_person(id).appendTo('#load_info');
    }

    function get_person(id) {
        var $person = $(window).find('id:contains(id)');

        var $div = $('<div>', {
            'class': 'person',
            'data-person-id': id,
            id: id
        });

        $person.find(h1).text.appendTo($div);
        return $div;  
    }
Run Code Online (Sandbox Code Playgroud)

ama*_*048 1

我发现你的问题很难理解,但我喜欢挑战。请注意,我尚未测试任何此代码,因此需要对其进行调试。

现在,据我了解,您有一堆具有以下结构的按钮:

<div id="load_buttons">
  // repeater
  <button class="mybutton" value="$person['id']">$person['fullName']</button>
  // end repeater
</div>
Run Code Online (Sandbox Code Playgroud)

还有一堆具有这种结构的细节 div,最初是隐藏的:

<div id="load_info">
  // repeater
  <div class="div div_" data-person-id="$person['id']" id="$person['id']">
    <h1>$person['job']</h1>
  </div>
  // end repeater
</div>
Run Code Online (Sandbox Code Playgroud)

这些应该在每次民意调查中更新/附加。

您想要实现的目标:单击按钮时,会显示相关信息。我会像这样完成你的成功功能:

success: function(data) {
    var json=eval('('+data+ ')');
    var $buttons;
    var $infos;
    if (json['msg'] != "") {
      addButtons($(json['msg']));
      addInfos($(json['msg2']));
    }
    timestamp = json["timestamp"];
    setTimeout("waitForMsg()",1000);
}

addButtons = function($buttons){
  // loop through the button json data
  $buttons.each(function(){
    // look to see if the button already exists
    var existing = $('[value='+$(this).attr("value")+']').length;
    if(!existing){
      // if not, add the button and assign a click handler
      $(this).appendTo('#load_buttons').click(function(){
        //hide all the children of info
        $('#load_info').children().hide();
        //show the info based on the button value
        $('#'+$(this).val).show();
      });
    }
  });
}
addInfos = function($infos){
  //loop through the info json data
  $infos.each(function(){
    // check to see if an info exists
    var existing = $('#'+$(this).attr("id")).length;
    if(!existing){
      //if not, add the info to the list and set it to hidden
      $(this).appendTo('#load_info').hide();
    }
  });
}
Run Code Online (Sandbox Code Playgroud)