克隆元素并在jquery循环内修改永远执行

时间:2018-03-21 14:59:55

标签: javascript jquery

我尝试克隆一个元素,然后根据json请求中的结果通过jquery修改其文本。但是,克隆将在每个循环内永久执行并导致浏览器崩溃。我不知道为什么,因为我之前没有使用过这个jquery功能,所以请原谅我缺乏理解......

无论如何这里是我的代码

jQuery的:

function buildFriendStatus() {
     $.getJSON('/members/feed/get-friend-status', function(data) {
        $.each(data, function(i, item) {
            var clone = $('.w3-container.w3-card-2.w3-white.w3-round.w3-margin').clone();

            clone.find('h4').html(data[i].username);
            clone.find('p').html(data[i].status);
            clone.find('img').attr('src', data[i].images);

            clone.insertAfter('.w3-container.w3-card-2.w3-white.w3-round.w3-margin.user-status');
        }); 
    }).fail(function(response) {
        console.log(response.fail);
    }); 
}

setInterval(function() {
    buildFriendStatus();
}, 1000);

和html元素

<!-- friends activity feed -->
<script type="text/javascript">
    buildSelfStatus();
    buildFriendStatus();
</script>

<!-- always have this first (sticky) for the user status -->
<div class="w3-container w3-card-2 w3-white w3-round w3-margin user-status">
    <h4></h4>

    <p></p>

    <div class="w3-row-padding" style="margin: 0 -16px;">
        <div class="w3-half">
            <img src="" style="width: 100%; height: 200px;" alt="<?php echo $this->identity() . "'s image"; ?>" class="w3-margin-bottom w3-round w3-border">
        </div>
    </div>
</div>

<!-- element I am cloning -->
<div class="w3-container w3-card-2 w3-white w3-round w3-margin">
    <h4></h4>

    <p></p>

    <div class="w3-row-padding" style="margin: 0 -16px">
        <div class="w3-half">
            <img src="" style="width: 100%; height: 200px;" alt="<?php echo "Image"; ?>" class="w3-margin-bottom w3-round w3-border">
        </div>
    </div>

    <button type="button" class="w3-btn w3-theme-d1 w3-margin-bottom">
        <i class="fa fa-thumbs-up"></i> Like
    </button>
    <button type="button" class="w3-btn w3-theme-d2 w3-margin-bottom">
        <i class="fa fa-comment"></i> Comment
    </button>
</div>

基本上我正在做或正在尝试做的是克隆现有元素并将$.getJSON请求中的所有文本放入其中。然而,一遍又一遍,这是一回事。

问题的屏幕截图 - enter image description here

它不断地插入一遍又一遍。我想要做的是使用clone来克隆元素,然后使用返回的数据修改它,尽管我可能做错了。

任何帮助都将不胜感激。

由于

更新

json string:

{
  "feed": {
    "username": "Timmy",
    "status": ["this is jimmy, test"],
    "images": ["\/images\/profile\/timmy\/status\/boned.jpg"]
  }
}

1 个答案:

答案 0 :(得分:2)

.clone() documentation says

  

描述:创建匹配元素 S

的深层副本

这意味着clone()将复制与提供的选择器匹配的 EVERY 元素。

选择的是,选择器在第一轮匹配单个元素,但是一旦将克隆添加到DOM,第二个调用(之后1秒)现在将匹配2个元素(原始+第一个克隆),所以上。

因此,请使用.last()将匹配限制为单个元素。

替换此行

var clone = $('.w3-container.w3-card-2.w3-white.w3-round.w3-margin').clone();

var clone = $('.w3-container.w3-card-2.w3-white.w3-round.w3-margin').last().clone();

将阻止多项式增长插入。

注意:

jQuery.each() documentation says

  

具有length属性的数组和类似数组的对象(例如函数的参数对象)由数字索引迭代,从0到length-1。其他对象通过其命名属性进行迭代。

因此无论是数组还是对象,数据操作都是相同的。

也就是说,如果你知道你正在操纵一个数组,那么选择内置方法forEach而不是 jQuery polyfil。

演示

使用 jQuery.each 方法,(我已用简单超时替换了AJAX调用)

// Cache element (jquery) reference
let $injectAfter = $('.w3-container.w3-card-2.w3-white.w3-round.w3-margin.user-status')
// Stub data - According to your PHP script output
, jsonData = {
    feed1: {
      username: "Timmy",
      status: ["this is jimmy, test"],
      images: ["/images/profile/timmy/status/boned.jpg"]
    },
    feed2: {
      username: "Chuck",
      status: ["Chuck, test"],
      images: ["/images/profile/timmy/status/boned.jpg"]
    }
 }
;

function buildFriendStatus() {
  $.each(jsonData, function(key, item) {
    let clone = $('.w3-container.w3-card-2.w3-white.w3-round.w3-margin').last().clone();
    clone.find('h4').html(item.username);
    // Status is an array
    // Change as you see fit, we only take the first element here.
    clone.find('p').html(item.status[0]);
    // Further clone changes here
    // …
    // Finally, append the node into the DOM
    clone.removeClass('hide-me').insertAfter($injectAfter);
  });
}

// Only meant to enhance demo
countdown(10000);
setInterval(function() {
    buildFriendStatus();
    countdown(null);
}, 10000);


// Helpers
function countdown(x) {
   x && (countdown.v = (x/1000)+1, countdown.cd = countdown.v);
   x === null && (countdown.cd = countdown.v);
   (countdown.cd-1 > 0)  && --countdown.cd;
   document.querySelector('#counter').textContent = `Call to server in ${countdown.cd}s`;
   countdown.cd && (clearTimeout(countdown.t), (countdown.t = setTimeout(countdown, 1000)));
}
.user-status .w3-half{border-radius: 5px; border: 1px solid black;padding: 3px}
.hide-me{display: none}
<link href="https://use.fontawesome.com/releases/v5.0.8/css/all.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p id="counter"></p>

<div class="w3-container w3-card-2 w3-white w3-round w3-margin user-status">
  <h4></h4>
  <p></p>
  <div class="w3-row-padding">
    <div class="w3-half">
      Block ".user-status"
      <!-- img src="" class="w3-margin-bottom w3-round w3-border" -->
    </div>
  </div>
</div>

<div class="w3-container w3-card-2 w3-white w3-round w3-margin hide-me">
  <h4></h4>
  <p></p>
  <div class="w3-row-padding">
    <div class="w3-half">
      <!-- img src="" class="w3-margin-bottom w3-round w3-border" -->
    </div>
  </div>

  <button type="button" class="w3-btn w3-theme-d1 w3-margin-bottom">
        <i class="fa fa-thumbs-up"></i> Like
  </button>
  <button type="button" class="w3-btn w3-theme-d2 w3-margin-bottom">
        <i class="fa fa-comment"></i> Comment
    </button>
</div>