动态替换大型列表的内容

时间:2014-03-21 15:32:03

标签: javascript

我正在尝试渲染元素的子元素(如果元素在视图中)或删除内容(如果不在视图中,如下面的滚动事件,如下所示

    list.addEventListener('scroll', function () {
        var elements = document.querySelectorAll('.aBox');
        var toBe = counter - 1 - elements.length;
        for (var i = 0; i < elements.length; i++) {
            var inView = visibleY(elements[i]),
                ele = elements[i].querySelector('.item');
            if (inView === false && ele) {
                console.log("Not in visible, keeping it none");
                var height = elements[i].clientHeight;
                elements[i].style.height = height + "px";
                elements[i].innerHTML = "";
            } else if(!ele){
                console.log('Placing the content');
                var minArray = arr[toBe + 1 + i],
                    str = "";
                for (var j = 0; j < minArray.length; j++) {
                    str += "<div class='item'>" + minArray[j] + "</div>";
                }
                elements[i].innerHTML = str;
            }
        }
    });

看起来很有效,但是如果我看看DOM,那就不能按预期工作了。有人请帮助我找到问题fiddle

更新

 function updateData(callback) {
        var elements = document.querySelectorAll('.aBox');
        elements = Array.prototype.slice.call(elements);
        var toBe = counter - 1 - elements.length;
        async.each(elements, function (element, cb) {
            var inView = $(element).is_on_screen(),
                ele = element.querySelector('.item');
            if (inView == false && ele) {
                console.log("Not in visible, keeping it none");
                var height = element.clientHeight;
                element.style.height = height + "px";
                element.innerHTML = "";
            } else if (!ele && inView) {
                console.log('Placing the content');
                var minArray = arr[toBe + 1 + i],
                    str = "";
                if (typeof minArray === "object") {
                    for (var j = 0; j < minArray.length; j++) {
                        str += "<div class='item'>" + minArray[j] + "</div>";
                    }
                    element.innerHTML = str;
                }
            }
            cb();
        }, function () {
            callback()
        });
    }

Fiddle

1 个答案:

答案 0 :(得分:2)

嗨,我已经解决了这个问题。在此处发布,这样对于想要使用移动设备进行虚拟滚动显示非常大的列表的人来说会更有帮助

  var arr = new Array(10000);
    for (var i = 0; i < arr.length; i++) {
        arr[i] = "Hello Dudes..." + i;
    }

    Array.prototype.chunk = function (chunkSize) {
        var array = this;
        return [].concat.apply([],
        array.map(function (elem, i) {
            return i % chunkSize ? [] : [array.slice(i, i + chunkSize)];
        }));
    }

    arr = arr.chunk(50);

    var list = document.getElementById('longList');
    var button = document.getElementById('loadMore');

    var counter = arr.length,
        aBoxLen = 1;

    function appendBox() {
        var div = document.createElement('div'),
            str = "";
        div.className = "aBox";
        var minArray = arr[counter - aBoxLen];
        for (var i = 0; i < minArray.length; i++) {
            str += "<div class='item'>" + minArray[i] + "</div>";
        }
        div.innerHTML = str;
        div.setAttribute('index', counter - aBoxLen);
        var box = document.querySelector('.aBox');
        if (box) {
            list.insertBefore(div, box);
        } else {
            list.appendChild(div);
        }
        aBoxLen += 1;
    }

    appendBox();

    button.addEventListener('click', function () {
        appendBox();
    });

    $.fn.is_on_screen = function () {

        var win = $(window);

        var viewport = {
            top: win.scrollTop(),
            left: win.scrollLeft()
        };
        viewport.right = viewport.left + win.width();
        viewport.bottom = viewport.top + win.height();

        var bounds = this.offset();
        bounds.right = bounds.left + this.outerWidth();
        bounds.bottom = bounds.top + this.outerHeight();

        return (!(viewport.right < bounds.left || viewport.left > bounds.right || viewport.bottom < bounds.top || viewport.top > bounds.bottom));

    };




    function updateData(callback) {
        var elements = document.querySelectorAll('.aBox');
        elements = Array.prototype.slice.call(elements);
        var toBe = counter - 1 - elements.length;
        async.each(elements, function (element, cb) {
            var inView = $(element).is_on_screen(),
                ele = element.querySelector('.item');
            if (inView == false && ele) {
                console.log("Not in visible, keeping it none");
                var height = element.clientHeight;
                element.style.height = height + "px";
                element.innerHTML = "";
            } else if (!ele && inView) {
                console.log('Placing the content');
                console.log(element.getAttribute('index'));
                var minArray = arr[element.getAttribute('index')],
                    str = "";
                for (var j = 0; j < minArray.length; j++) {
                    str += "<div class='item'>" + minArray[j] + "</div>";
                }
                element.innerHTML = str;

            }
            cb();
        }, function () {
            // callback()
        });
    }


    var delay = false;
    var timeout = null;

    list.addEventListener('touchmove', function () {
        clearTimeout(timeout);
        timeout = setTimeout(function () {
            updateData();
        }
        }, delay);
    });

这些解决方案都不是专为移动设备设计的,所以我已经实现了这一点。

我认为这有很大的改进空间。如果有人想要改进它,请随时使用

Demo