用CSS在HTML中创建网格的最有效的方法

Most efficient way of creating a grid in HTML with CSS?

本文关键字:有效 方法 网格 创建 CSS HTML      更新时间:2023-09-26

我需要创建一个网格,在每个单元格中应该有一个0或1。单击这些单元格时,应该在0和1之间切换。当鼠标悬停时,它应该显示坐标(例如1,5)。

现在我让它工作的唯一方法是创建三个div。一个用于单元格(包含数字),一个用于坐标(这个是动态添加的),另一个div(包装器)将位于其他两个div之上,这个div将具有事件侦听器。

所以我为cell创建了三个div,现在如果它是10x10的网格,这工作得很好,但是当它变得更大(64x64)时,浏览器开始冻结。

这是HTML查找网格单元格的方式:

<div class="cell cellUnselected" id="cell_1_1" style="left: 0px; top: 0px;">0</div>
<div class="cellCoordinates cellCoordText" id="cell_1_1_coord" style="left: 0px; top: 0px;"></div>
<div class="cellWrapper" id="cell_1_1_wrapper" style="left: 0px; top: 0px;"></div>

我创建了一个工作小提琴:http://jsfiddle.net/vicgonzalez25/Tfs2M/

问题:一旦网格开始变得更大的尺寸(例如64x64)通过创建这三个div,浏览器开始冻结。有没有更有效的方法来做这个网格?

网格HTML

:

<div id="grid" class="gridContainer">
    <div class="cell cellUnselected" id="cell_1_1" style="left: 0px; top: 0px;">0</div>
    <div class="cellCoordinates cellCoordText" id="cell_1_1_coord" style="left: 0px; top: 0px;"></div>
    <div class="cellWrapper" id="cell_1_1_wrapper" style="left: 0px; top: 0px;"></div>
    <div class="cell cellUnselected" id="cell_1_2" style="left: 36px; top: 0px;">0</div>
    <div class="cellCoordinates cellCoordText" id="cell_1_2_coord" style="left: 36px; top: 0px;"></div>
    <div class="cellWrapper" id="cell_1_2_wrapper" style="left: 36px; top: 0px;"></div>
</div>

为了繁殖:

HTML:

<div id="gridLayout" class="gridLayout">
    <div id="gridHeader">
        <h2>Aperture Configuration:</h2>
        Grid Size:
        <input id="rows" type="number" min="1" max="50" value="10" width="40" size="3" onChange="GRASP.start();">
        x
        <input id="cols" type="number" min="1" max="50" value="10" width="40" size="3" onChange="GRASP.start();">
    </div>
    <div id="grid" class="gridContainer"></div>
    <div id="matrixHeader" style="position:absolute">
        <h2>Auto Correlation:</h2>
    </div>
    <div id="matrix" class="autocorrMatrixContainer"></div>
</div>
Javascript:

(function(GRASP, $){
    var GRID_ROWS,
        GRID_COLS,
        GRID_ELEMENT,
        MATRIX_ROWS,
        MATRIX_COLS,
        MATRIXHEADER_ELEMENT,
        MATRIX_ELEMENT,
        A,C;
    GRASP.config = {
        gridContainer: "grid",
        matrixContainer: "matrix",
        matrixHeader: "matrixHeader"
    };
    GRASP.start = function(){
        GRID_ROWS = $("#rows").val();
        GRID_COLS = $("#cols").val();
        MATRIX_ROWS = GRID_ROWS * 2 - 1;
        MATRIX_COLS = GRID_COLS * 2 - 1;
        createGrid();
        createAutocorrelationMatrix();
    };
    function createGrid()
    {
        GRID_ELEMENT = $("#"+GRASP.config.gridContainer);
        GRID_ELEMENT.html(""); // Clear Grid ;)
        var coord;
        var cell; // Contains the 1 or 0 based upon the cell selection
        for(var i=1; i<=GRID_ROWS; i++){
            for(var j=1; j<=GRID_COLS; j++){
                coord = "" + i + "," + j;
                $(document.createElement("div"))
                    .addClass("cellWrapper")
                    .attr("alt", coord)
                    .css("left", parseInt((j-1) * 36, 10) + "px")
                    .css("top", parseInt((i-1) * 36, 10) + "px")
                    .width(36).height(36)
                    .data("row", i).data("col", j)
                    .appendTo("#"+GRASP.config.gridContainer)
                    .on("click", cellClick)
                    .on("mouseenter", {isMatrix: false}, cellMouseEnter)
                    .on("mouseleave", cellMouseLeave);
                $(document.createElement("div"))
                    .addClass("cell cellUnselected")
                    .attr("alt", coord)
                    .css("left", parseInt((j-1) * 36, 10) + "px")
                    .css("top", parseInt((i-1) * 36, 10) + "px")
                    .text("0")
                    .appendTo("#"+GRASP.config.gridContainer);
            }
        }
        GRID_ELEMENT.height(36 * GRID_ROWS);
        GRID_ELEMENT.width(36 * GRID_COLS);
    }
    function createAutocorrelationMatrix() {
        MATRIXHEADER_ELEMENT = $("#" + GRASP.config.matrixHeader);
        MATRIX_ELEMENT = $("#" + GRASP.config.matrixContainer);
        MATRIX_ELEMENT.html("");
        MATRIXHEADER_ELEMENT.css("top", parseInt(GRID_ELEMENT.offset().top + (GRID_ROWS * 36)) + "px");
        MATRIX_ELEMENT.css("top", parseInt(MATRIXHEADER_ELEMENT.offset().top + MATRIXHEADER_ELEMENT.height()) + "px");
        var cellSize = Math.ceil((GRID_ROWS * 36) / MATRIX_ROWS);
        var coord;
        for (var i=1;i<=MATRIX_ROWS;i++){
            for (var j=1;j<=MATRIX_COLS;j++){
                coord = "" + i + "," + j;
                $(document.createElement("div"))
                    .addClass("autocorrMatrixCellWrapper")
                    .attr("alt", coord)
                    .css("left", parseInt((j-1) * cellSize, 10) + "px")
                    .css("top", parseInt((i-1) * cellSize, 10) + "px")
                    .data("row", i).data("col", j)
                    .appendTo("#"+GRASP.config.matrixContainer)
                    .on("mouseenter", {isMatrix: true}, cellMouseEnter)
                    .on("mouseleave", cellMouseLeave);
                $(document.createElement("div"))
                    .addClass("autocorrMatrixCell autocorrMatrixCellUnselected")
                    .attr("alt", coord)
                    .css("left", parseInt((j-1) * cellSize, 10) + "px")
                    .css("top", parseInt((i-1) * cellSize, 10) + "px")
                    .appendTo("#"+GRASP.config.matrixContainer);
            }
        }
        MATRIX_ELEMENT.height(36 * GRID_ROWS);
        MATRIX_ELEMENT.width(36 * GRID_COLS);
    }
    function cellClick(){
        var cell = $(this).next();
        if(cell.text() == "0"){
            cell.text("1");
        } else {
            cell.text("0");
        }
    }
    function cellMouseEnter(e){
        var i = $(this).data("row");
        var j = $(this).data("col");
        var x = e.data.isMatrix ? Math.ceil((GRID_ROWS * 36) / MATRIX_ROWS) : 36;
        var div = $(document.createElement("div"))
            .addClass("cellCoordinates cellCoordText")
            .css("left", parseInt((j-1) * x, 10) + "px")
            .css("top", parseInt((i-1) * x, 10) + "px")
            .text(i + ", " + j);
        $(this).before(div);
    }
    function cellMouseLeave(){
        $(this).prev().remove();
    }
}(window.GRASP = window.GRASP || {}, jQuery));
$(document).ready(function(){
    GRASP.start();
});
CSS:

.gridContainer {
/*  width: inherit; */
/*  float: left; */
    position: relative;
    top: 10px;
    padding: 0 0 0 0;
    display: block;
    background: none;
    font-family: Arial, Helvetica, Verdana, sans-serif;
}
.cell {
    width: 36px;
    height: 36px;
    position: absolute;
    z-index: 0;
/*
    font-size: 16pt;
*/
    font-size: x-large;
    font-weight: normal;
    font-style: normal;
    color: #888888;
    text-align: center;
    display: table-cell;
    vertical-align: middle;
    line-height: 2em;
/*  padding-top: 0.25em; */
}
.cellSelected {
    background: #00CCFF;
}
.cellUnselected {
    background: none;
}
.cellCoordinates {
    width: 36px;
    height: 36px;
    position: absolute;
    background: none;
    z-index: 1;
}
.autocorrMatrixContainer {
    position: absolute;
/*    float: left; */
/*    bottom: 0px; */
    display: block;
    background: none;
    font-family: Arial, Helvetica, Verdana, sans-serif;
}
.autocorrMatrixCell {
    width: 16px;
    height: 16px;
    position: absolute;
    z-index: 0;
    font-size: xx-small;
    font-weight: normal;
    font-style: normal;
    color: #FFFFFF;
    text-align: center;
    display: table-cell;
    vertical-align: middle;
    line-height: 2em;
/*  padding-top: 0.25em; */
}
.autocorrMatrixCellWrapper {
    width: 16px;
    height: 16px;
    position: absolute;
    background: none;
    z-index: 2;
    border-style: solid outset;
    border-width: 1px;
    border-color: black;
    font-size: x-small;
}
.autocorrMatrixCellCoordText {
    font-size: xx-small;
    font-weight: normal;
    font-style: normal;
    padding-top: 2px;
    padding-left: 3px;
    color: #444444;
    text-align: left;
    vertical-align: top;
}
.cellWrapper {
    width: 36px;
    height: 36px;
    position: absolute;
    background: none;
    z-index: 2;
    border-style: solid outset;
    border-width: 1px;
    border-color: black;
    font-size: normal;
}
.cellCoordText {
    font-size: x-small;
    font-weight: normal;
    font-style: normal;
    padding-top: 2px;
    padding-left: 3px;
    color: #444444;
    text-align: left;
    vertical-align: top;
}

您正在做以下事情:

  • 每个cell创建三个divs
  • 为每个div (onclick, onmouseenter/onmouceleave)创建三个处理程序。这是加载浏览器很多。

您可以通过以下操作显著降低负载:

  1. 为每个单元格创建两个divs:一个带有坐标(默认隐藏),第二个带有值;
  2. 不是为每个div附加事件处理程序,而是为整个表附加事件处理程序;
  3. 事件处理器应该依赖于event.target -它将包含值,它的邻居将包含坐标;
  4. 事件处理程序应该做他们在你的代码中实际做的事情,但适用于目标div。

有一点需要处理:每个div都没有onmouseleave;您应该在更改event.target之后运行类似leave(prevDiv)的东西(考虑到您将prevDiv存储在事件处理程序的末尾)。

祝你重构顺利!