javascript - 水平数据更新不适用于滚动

标签 javascript

我有一个大数组,我需要将它渲染到表格中。我没有渲染所有项目,而是只水平和垂直渲染少数项目。然后基于鼠标滚动滚动是否发生垂直/水平更新表值。但是我在这方面有两个问题

这是我的代码的问题

  1. 水平滚动时数据不会更新。
  2. 水平滚动也会使屏幕闪烁。
  3. 水平元素未正确对齐。

这是 jsbin 链接 http://jsbin.com/oSOsIQe/2/edit

这是 JS 代码,我知道代码不干净,但我稍后会清理它。

var $matrix = (function () {
function $matrix(data, holder, hidescrollbar, config) {
    var header_h = config.header || "150px";
    var data_h = config.header || "90px";
    !data && (function () {
        // Fake Data, will be removed later
        data = new Array(50000);
        for (var i = 0, l = data.length; i < l; i++) {
            var dummy = Math.random().toString(36).substring(5);
            var dum = [];
            for (var j = 0; j < 26; j++) {
                dum.push(dummy + i);
            }
            data[i] = dum;
        }
    }());
    hidescrollbar = hidescrollbar || false;
    var heightForcer = holder.appendChild(document.createElement('div'));
    heightForcer.id = "heightForcer";
    var view = null;
    //get the height of a single item
    var dimensions = (function () {
        //generate a fake item and calculate dimensions of our targets
        var div = document.createElement('div');
        div.style.height = "auto";
        div.innerHTML = "<div class='rowHeader'>fake</div><div class='rowData'>fake</div>";
        holder.appendChild(div);
        var output = {
            row: div.firstChild.offsetHeight,
            header: div.firstChild.offsetWidth,
            data: div.lastChild.offsetWidth
        }
        holder.removeChild(div);
        return output;
    })();

    function refreshWindow() {
        //remove old view
        if (view != null) {
            view.innerHTML = "";
        } else {
            //create new view
            view = holder.appendChild(document.createElement('div'));
        }
        var firstItem = Math.floor(holder.scrollTop / dimensions.row);
        var lastItem = firstItem + Math.ceil(holder.offsetHeight / dimensions.row) + 1;
        if (lastItem + 1 >= data.length) lastItem = data.length - 1;

        var hfirstItem = Math.floor(holder.scrollLeft / dimensions.data);
        var hlastItem = hfirstItem + Math.ceil(holder.offsetWidth / dimensions.data) + 1;
        if (hlastItem + 1 >= data[firstItem].length) hlastItem = data[firstItem].length - 1;

        //position view in users face
        view.id = 'view';
        view.style.top = (firstItem * dimensions.row) + 'px';
        view.style.left = (hfirstItem * dimensions.data) + 'px';
        var div;
        //add the items
        for (var index = firstItem; index <= lastItem; ++index) {
            div = document.createElement('div');
            var curData = data[index].slice(hfirstItem, hlastItem);
            div.innerHTML = '<div class="rowHeader">' + 
              curData.join('</div><div class="rowData">') +
            "</div>";
            div.className = "listItem";
            div.style.height = dimensions.row + "px";
            view.appendChild(div);
        }
        console.log('viewing items ' + firstItem + ' to ' + lastItem);
    }
    heightForcer.style.height = (data.length * dimensions.row) + 'px';
    heightForcer.style.width = (data[0].length * dimensions.data) + 'px';
    if (hidescrollbar) {
        //work around for non-chrome browsers, hides the scrollbar
        holder.style.width = (holder.offsetWidth * 2 - view.offsetWidth) + 'px';
    }
    refreshWindow();

    function delayingHandler() {
        //wait for the scroll to finish
        //setTimeout(refreshWindow, 10);
        refreshWindow();
    }
    if (holder.addEventListener) holder.addEventListener("scroll", delayingHandler, false);
    else holder.attachEvent("onscroll", delayingHandler);
}
return $matrix;
 }());

new $matrix(undefined, document.getElementById('listHolder'), false, {
  header: "150px",
  data: "90px",
  headerColumns: 2
});

请帮我解决这个问题。

最佳答案

我注意到您的 jsbin 示例已稍作修改并使用了 wheelDelta 属性。这就是为什么您无法区分水平更新和垂直更新的原因。您需要使用 wheelDeltaXwheelDeltaY,它们将变为一个值或零,具体取决于用户是垂直滚动还是水平滚动。

此外,请小心使用鼠标滚轮事件,它不符合标准,因此可能会再次困扰您。可能值得查看 JQuery 源代码以了解 scroll() 方法如何实现这些处理程序。我会想象有一个计时器监视元素的滚动偏移量,当对象滚动时触发合成事件。但那完全是一个疯狂的猜测。就像我说的,你最好看看它。

关于javascript - 水平数据更新不适用于滚动,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18285760/

相关文章:

javascript - 定位/滚动到不是紧密父/子的 React 组件

javascript - PhpStorm:未解析的变量readyState

javascript - 此实验性语法需要启用解析器插件 : 'exportDefaultFrom'

javascript - 如何防止用户拖动 HTML 输入类型 ='range' 对?

javascript - 有没有办法让浏览器忽略或覆盖 xml-stylesheet 处理指令?

javascript - 从服务获取数据后如何刷新数据表内联编辑器?

javascript - 组合/匹配数组

javascript - 如何缩小 Bootstrap 轮播中的图像

javascript - bool 变量.toString()函数显示[Object Object]

javascript - 如何使用输入字段名称 ="array[]"jQuery ajax?