Horizontal data update is not working on scroll

前端 未结 3 2296
被撕碎了的回忆
被撕碎了的回忆 2021-02-20 03:19

I have a big array and I need to render it into a table. Instead of rendering all items I am rendering only few items horizontally and vertically. Then on scroll based on mouse

相关标签:
3条回答
  • 2021-02-20 03:50

    The problem is that you are hooking your onmousewheel event on #foo but don't realize that #foo is only as big as the data it contain. If you make the following change (i.e. take #wrapper instead of #foo)

    var listHold = document.getElementById('wrapper');
    

    You'll notice that the value do get updated.

    0 讨论(0)
  • 2021-02-20 03:58

    I've noticed that your jsbin example has been modified slightly and is using the wheelDelta attribute. This is why you are not able to distinguish between updating horizontally and vertically. You need to use wheelDeltaX and wheelDeltaY, which will wither be a value or zero, depending on whether the user scrolled vertically or horizontally.

    Also, be careful using the mousewheel event, it is not standards compliant so may come back to haunt you. Might be worth having a look at the JQuery source to see how the scroll() method implements these handlers. I would imagine there is a timer that monitors the scroll offsets of the element, which triggers synthetic events when the object scrolls. But that is a complete wild guess. Like I said, you are better off having a look at it.

    0 讨论(0)
  • 2021-02-20 04:09

    SOLUTION, an conceptual extension to my answer to a similar question

    CODE

    function matrix(data, holder, config) {
        'use strict';
    
        //copy the config, substituting defaults
        config = {
            cellWidth : (config && config.cellWidth) || 150,
            rowHeight : (config && config.rowHeight) || 22,
        };
    
        if (!data) {
            //create 50000x26 array for data
            data = (function (length, depth) {
                var output = new Array(length);
                var startAt;
    
                for (var index = 0; index < length; ++index) {
                    //var startAt = Math.random().toString(36).substring(5);
                    var startAt = index + ':';
                    output[index] = new Array(depth);
    
                    for (var index2 = 0; index2 < depth; ++index2)
                        output[index][index2] = startAt + index2;
                }
    
                return output;
            })(50000, 26);
        }
    
        //guard against 0 length arrays
        if (data.length < 1 || data[0].length < 1)
            return;
    
        var areaForcer = holder.appendChild(holder.ownerDocument.createElement('div'));
    
        var view = null;
        function refreshWindow() {
            //remove old view
            if (view != null)
                view.innerHTML = "";
            //create new view
            else
                view = holder.appendChild(holder.ownerDocument.createElement('div'));
    
            var firstRow = Math.floor(holder.scrollTop / config.rowHeight);
            var lastRow = firstRow + Math.ceil(holder.offsetHeight / config.rowHeight) + 1;
            if (lastRow + 2 > data.length)
                lastRow = data.length - 1;
    
            var firstColumn = Math.floor(holder.scrollLeft / config.cellWidth);
            var lastColumn = firstColumn + Math.ceil(holder.offsetWidth / config.cellWidth) + 1;
            if (lastColumn + 2 > data[0].length)
                lastColumn = data[0].length - 1;
    
            //position view in users face
            view.id = 'view';
            view.style.top = (firstRow * config.rowHeight) + 'px';
            view.style.left = (firstColumn * config.cellWidth) + 'px';
    
            var row;
            var cell;
            //add the rows
            for (var index = firstRow; index <= lastRow; ++index) {
                row = view.ownerDocument.createElement('div');
                row.style.height = config.rowHeight - 2 + 'px';
                view.appendChild(row);
    
                //add the cells
                for (var index2 = firstColumn; index2 <= lastColumn; ++index2) {
                    cell = row.ownerDocument.createElement('div');
                    cell.className = 'listItem';
                    cell.innerHTML = data[index][index2];
                    cell.style.width = config.cellWidth - 2 + 'px';
                    row.appendChild(cell);
                }
            }
    
            console.log('viewing items [' + firstRow + ':' + lastRow + '][' + firstColumn + ':' + lastColumn + ']');
        }
    
        areaForcer.style.height = (data.length * config.rowHeight) + 'px';
        areaForcer.style.width = (data[0].length * config.cellWidth) + 'px';
    
        refreshWindow();
    
        function delayingHandler() {
            //wait for the scroll to finish
            setTimeout(refreshWindow, 10);
        }
    
        if (holder.addEventListener)
            holder.addEventListener('scroll', delayingHandler, false);
        else
            holder.attachEvent('onscroll', delayingHandler);
    }
    
    matrix(null, document.getElementById('listHolder'), false);
    
    html, body {
        width:100%;
        height:100%;
        padding:0;
        margin:0
    }
    
    body{
        overflow:hidden; 
    }
    
    .listItem {
        border : 1px solid gray;
        margin : 1px 0px;
        display : inline-block;
    }
    
    #listHolder {
        position:relative;
        height:100%;
        width:100%;
        background-color:#CCC;
        box-sizing:border-box;
        overflow:auto;
    }
    
    #view {
        position:absolute;
    }
    
    #view, #view * {
        overflow : hidden;
        white-space : nowrap;
    }
    
    #view > div {
        width : 100%;
    }
    
    <div id="listHolder"></div>
    

    Just some things to clean up your code:

    • you're not using the object in an OO fashion, no need for new/use the function as a constructor (and if you are going to, start it with a capital)

    • in this day and age the compiler can do a lot of things for us, there's no reason to use names like 'i' or 'j' where 'index' is much more self explanatory, and the if statement was made for what you used the and operator for (!data && /*set data*/, use if (!data) /*set data*/)

    • don't employ anonymous, call-once functions where they're not required, they need to be recompiled each time the parent function runs

    • declare variables outside of loops

    • don't use random() (in this case) unless the code is working, makes it harder to see whats going on

    • personal preference send null to a function instead of undefined and don't name a function $matrix when matrix is just as apt use comments!

    • personal preference unless you know what you're doing, ++x is exactly what you need and x++ is a minor waste of resources

    • because you're using horizontal scroll, forget about hiding the scrollbar

    • start out simple and don't attempt to get the height, just force one. things like detecting height are niceties reserved for working solutions

    • always use proper indentation, even if the if statement can be written on one line. Doesn't matter about your personal preference because you're posting the code online expecting other people to help you

    • when you edit code make sure you update the semantics. E.g. the element called 'heightForcer' now manipulates the width aswell, obviate that by calling it 'areaForcer'

    0 讨论(0)
提交回复
热议问题