How to calculate the amount of flexbox items in a row?

后端 未结 11 1879
北荒
北荒 2020-12-04 12:12

A grid is implemented using the CSS flexbox. Example:

The number of rows in this example is 4 because I fixed the container width for demo purposes. But, in

11条回答
  •  悲&欢浪女
    2020-12-04 12:32

    This example assumes movement ends at the bounds. Also, if moving from the second to last row down to the last row, but there are fewer columns in the last row, it will move to the last column of the last row instead.

    This solution keeps track of row/columns and uses a grid object to keep track of where the elements are. The positions will be updated in the grid object when the page is resized.

    (you can see the wrapping update in action in full-screen mode)

    var items = document.querySelectorAll(".item");
    var grid = {}; // keys: row, values: index of div in items variable
    var row, col, numRows;
    
    // called only onload and onresize
    function populateGrid() {
        grid = {};
        var prevTop = -99;
        var row = -1;
    
        for(idx in items) {
            if(isNaN(idx)) continue;
    
            if(items[idx].offsetTop !== prevTop) {
              prevTop = items[idx].offsetTop;
              row++;
              grid[row] = [];
            }
            grid[row].push(idx);
        }
    
        setActiveRowAndCol();
        numRows = Object.keys(grid).length
    }
    
    // changes active state from one element to another
    function updateActiveState(oldElem, newElem) {
        oldElem.classList.remove('active');
        newElem.classList.add('active');
    }
    
    // only called from populateGrid to get new row/col of active element (in case of wrap)
    function setActiveRowAndCol() {
        var activeIdx = -1;
        for(var idx in items) {
            if(items[idx].className == "item active")
                activeIdx = idx;
        }
    
        for(var key in grid) {
            var gridIdx = grid[key].indexOf(activeIdx);
            if(gridIdx > -1) {
              row = key;
              col = gridIdx;
            }
        }
    }
    
    function moveUp() {
        if(0 < row) {
            var oldElem = items[grid[row][col]];
            row--;
            var newElem = items[grid[row][col]];
            updateActiveState(oldElem, newElem);
        }
    }
    
    function moveDown() {
        if(row < numRows - 1) {
            var oldElem = items[grid[row][col]];
            row++;
            var rowLength = grid[row].length
            var newElem;
    
            if(rowLength-1 < col) {
                newElem = items[grid[row][rowLength-1]]
                col = rowLength-1;
            } else {
                newElem = items[grid[row][col]];
            }
            updateActiveState(oldElem, newElem);
        }
    }
    
    function moveLeft() {
        if(0 < col) {
            var oldElem = items[grid[row][col]];
            col--;
            var newElem = items[grid[row][col]];
            updateActiveState(oldElem, newElem);
        }
    }
    
    function moveRight() {
        if(col < grid[row].length - 1) {
            var oldElem = items[grid[row][col]];
            col++;
            var newElem = items[grid[row][col]];
            updateActiveState(oldElem, newElem);
        }
    }
    
    
    
    document.onload = populateGrid();
    window.addEventListener("resize", populateGrid);
    
    document.addEventListener('keydown', function(e) {
        e = e || window.event;
        if (e.keyCode == '38') {
            moveUp();
        } else if (e.keyCode == '40') {
            moveDown();
        } else if (e.keyCode == '37') {
            moveLeft();
        } else if (e.keyCode == '39') {
            moveRight();
        }
    });
    .grid {
      display: flex;
      flex-wrap: wrap;
      resize: horizontal;
      align-content: flex-start;
      background-color: #ffffd;
      padding: 10px 0 0 10px;
    }
    
    .item {
      width: 50px;
      height: 50px;
      background-color: red;
      margin: 0 10px 10px 0;
    }
    
    .active.item {
      outline: 5px solid black;
    }

提交回复
热议问题