javascript - 动态替换大列表的内容

标签 javascript

如果元素在 View 中,我尝试渲染该元素的子元素,或者如果不在 View 中,则删除内容,如下所示的滚动事件

    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

最佳答案

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

  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

关于javascript - 动态替换大列表的内容,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22563000/

相关文章:

javascript - 在 http-on-examine-response 之前返回响应

javascript - 按字符串属性值对对象数组进行排序

javascript - 带有 froala 的外部 CSS

javascript - 改进安全密码生成器

javascript - 为什么 call.call 调用函数

javascript - 如何使用 jQuery 解析 HTML 并替换字符串中的标签?

javascript - 带百分比的 SVG 进度圈

javascript - 将变量传递到 PHP 文件时出现 AJAX 错误

javascript - 轮询 api 直到响应成功

javascript - jsPDF fromHTML() 不显示 HTML