【问题标题】:jQuery - changed element won't clonejQuery - 更改的元素不会克隆
【发布时间】:2012-04-23 07:10:10
【问题描述】:

我已更改元素的 html 文本,在本例中为 #main_cluster_id_reach_12

$("#main_cluster_id_reach_12").html( '400' ).effect("highlight", {color: '#2a6500'}, 60000 * 5);

这很好,但是当我尝试克隆保存它的容器时(#applications),它不包含#main_cluster_id_reach_12 的更新html,而是与页面一起加载的原始文本。这是我克隆它的方法:

var $applications = $('#applications');
var $data = $applications.clone();

我做错了什么?

编辑:这里是js和html。我正在使用 jquery 1.7.2

我想要做的是通过 ajax 每隔 10 秒更新一组集群的范围,然后用流沙按它们的范围排序 li 项目。更新没有问题,但流沙克隆了原始列表,而不是更新的列表。今天早上我一直在玩一些日志记录,看来克隆是在 ajax 更新完成之前发生的。

// quicksand sorting plugin
(function($) {
  $.fn.sorted = function(customOptions) {
    var options = {
      reversed: true,
      by: function(a) { return a.text(); }
    };
    $.extend(options, customOptions);
    $data = $(this);
    arr = $data.get();
    arr.sort(function(a, b) {
      var valA = options.by($(a));
      var valB = options.by($(b));
      if (options.reversed) {
        return (valA < valB) ? 1 : (valA > valB) ? -1 : 0;              
      } else {      
        return (valA < valB) ? -1 : (valA > valB) ? 1 : 0;  
      }
    });
    return $(arr);
  };
})(jQuery);


$(document).ready(function(){
    //loop through all reaches to update
    setInterval(function() {
        //reach
        $("[id^='main_cluster_id_reach_']").each(function(){

            //Check for reach updates

            //get cluster id first
            var cluster_id = parseInt(this.id.replace("main_cluster_id_reach_", ""));

            //get cluster reach         
            $.post("./lib/ajax/meme_cluster_update.php", { cluster_id: cluster_id }, 
                function(data) {

                //get reach - new
                var new_reach = 0;

                new_reach = parseInt(data.ItemReach, 10);

                //get reach - old
                var reach = $("#main_cluster_id_reach_" + cluster_id).html();

                // Format as American input
                reach = parseInt(reach.replace(/[^\d\.\-\ ]/g, ''));

                //compare new vs old and change cell view
                compareReach(cluster_id, reach, new_reach);

             }, "json");
        });

        // get the first collection
        var $applications = $('#applications');

        // clone applications to get a second collection
        var $data = $applications.clone();

        var $filteredData = $data.find('li[data-type=app]');

        var $sortedData = $filteredData.sorted({
            by: function (v) {
                return parseFloat($(v).find('span[data-type=size]').text());
            }
        });

        // finally, call quicksand
        $applications.quicksand($sortedData, {
            duration: 800,
            easing: 'easeInOutQuad'
        });
    }, 10000);

    //compare the reaches to update accordingly
    function compareReach(cluster_id, reach, new_reach) {
        //determine what color to change cells
        if(new_reach > reach) {
            $(".main_cluster_id_reach_" + cluster_id).html( new_reach ).effect("highlight", {color: '#2a6500'}, 60000 * 5);
        }
        else if(new_reach < reach) {
            $(".main_cluster_id_reach_" + cluster_id).html( new_reach ).effect("highlight", {color: '#990004'}, 60000 * 5);
        }
    }

html

 <div class="span-24" id='demo'>
        <ul id="applications" class="image-grid">
            <li data-id="id-210639" data-type="app" class='cluster'>
                <div class='cluster_byline'>@awkwardisco</div>
                <div class="cluster_padding">
                    <span class='cluster_headline'>Avengers on Thursday!!!</span>
                    <br>
                    <div class="cluster_stats">
                        <div class="span-2 reach">
                            <strong>REACH</strong>
                            <p id="main_cluster_id_reach_210639">26777</p>
                            <span class="main_cluster_id_reach_210639" data-type="size">26777</span>
                        </div>
                    </div>
                </div>
            </li>
        </ul>
    </div>

【问题讨论】:

  • 你能举出一个完整的例子来说明这个问题吗?
  • 您是否尝试将“withDataAndEvents”参数设置为“true”? -> .Clone(true)
  • 您使用的是什么版本的 jQuery?我使用 jQuery 1.7.2 和 jQuery UI 1.8.18 创建了一个Fiddle,它工作正常。
  • @madflow,我有。我在编辑中提到,似乎克隆可能在元素通过 ajax 脚本完成更改之前发生。
  • 你的代码使用了AJAX,所以函数不是按源码顺序执行的。 var $data = $applications.clone(); 调用可能出现在 compareReach 函数之前,因此克隆的元素具有旧值。尝试在 clone 调用之前和函数内部添加 console.log 语句,看看哪个先执行。

标签: jquery clone quicksand


【解决方案1】:

感谢大家的帮助。我在另一个有效的thread 上遇到了一个解决方案。从 js 的角度来看,它并不漂亮,甚至可能不理想,但它正在工作。我正在做的是计算通过每个循环的项目数,然后当在 ajax .post 中达到该数字时,即发出最后一个 ajax 调用完成的信号,我运行克隆和流沙操作。

setInterval(function() {
        var flag = 0; //to determine when each is complete

        var count = $("[id^='main_cluster_id_reach_']").length;

        //reach
        $("[id^='main_cluster_id_reach_']").each(function(){

            //Check for reach updates

            //get cluster id first
            var cluster_id = parseInt(this.id.replace("main_cluster_id_reach_", ""));

            //get cluster reach
            $.post("./lib/ajax/meme_cluster_update.php", { cluster_id: cluster_id }, 
                function(data) {

                //get reach - new
                var new_reach = 0;

                new_reach = parseInt(data.ItemReach, 10);

                //get reach - old
                var reach = $("#main_cluster_id_reach_" + cluster_id).html();

                // Format as American input
                reach = parseInt(reach.replace(/[^\d\.\-\ ]/g, ''));

                //compare new vs old and change cell view
                compareReach(cluster_id, reach, new_reach);

                flag++;

                //if ajax is done then sort
                if(flag == count) {
                    console.log("Flags Equal, Each Complete, Now Sort");
                    quicksandSort();
                }

             }, "json");            
        }); 
    }, 10000);

    //sort with quicksand
    function quicksandSort() {
        // get the first collection
        var $applications = $('#applications');

        // clone applications to get a second collection
        var $data = $applications.clone(true);

        var $filteredData = $data.find('li[data-type=app]');

        var $sortedData = $filteredData.sorted({
            by: function (v) {
                return parseFloat($(v).find('span[data-type=size]').text());
            }
        });

        // finally, call quicksand
        $applications.quicksand($sortedData, {
            duration: 2000,
            easing: 'easeInOutQuad'
        }); 
    }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-12-31
    • 2013-03-27
    • 2011-04-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多