经过搜索大部分都是给出使用js来设置css的style属性,这样每个元素还要计算位置,非常不方便,同时可能导致页面混乱
grid布局
阮一峰大神的博客里面啥都有
下面说一下这种特殊定位布局的方法
观察一下上图可以发现可以将父级div分为3x4的其中4号元素占用两行两列
- 声明父级元素为grid
- 指定列数为4列
- 指定行数为3行
- 指定元素的布局见gridpos4 中grid-column(2 / span 2)意思是 从第二列开始,然后跨越两行
注意: 在vue中的less语法经过测试和大神的有出入 (grid-column: 2 / 4; 会报错)
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| #container { display: grid; grid-template-columns: 1fr 1fr 1fr 1fr; grid-template-rows: 1fr 1fr 1fr;
width: 400px; height: 300px; }
.gridpos4 { grid-column: 2 / span 2; grid-row: 1 / span 2; }
|
元素交换位置
- 使用transform动画 参见项目
关键代码如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| <div class="flex-container column"> <div class="item one" @click="clickChart('1')" style="transform: translate(-22.4%,-33.5%) scale(0.33)"> <multipleColumn></multipleColumn> </div> <div class="item two" @click="clickChart('2')" style="transform: translate(-22.4%,0.5%) scale(0.33)"> <column></column> </div> <div class="item three" @click="clickChart('3')" style="transform: translate(-22.4%,34.5%) scale(0.33)"> <v-line></v-line> </div> <div class="item four active" @click="clickChart('4')" style="transform: translate(43.7%, 0) scale(1)"> <point></point> </div> </div>
|
优点就不说了,下面说点不方便的地方
- 要每次写定每个元素的位置,这个还真不好计算
- 切换只是transform等比例放大缩小显示效果(这样放大时可能会早晨模糊)
- 我的方法
既然巴拉巴拉说了人家的不足,show my code, 简单解释下核心思路,因为可以通过grid-column以及grid-row来指定每个元素的位置,于是在鼠标点击的时候来改变类简单时间交换两个元素的位置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174
| <!DOCTYPE html>
<meta name="robots" content="noindex"> <html>
<head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width"> <title>JS Bin</title> <style> #container { display: grid; grid-template-columns: 1fr 1fr 1fr 1fr; grid-template-rows: 1fr 1fr 1fr;
width: 400px; height: 300px; }
.gridpos1 { grid-column: 1; grid-row: 1; }
.gridpos2 { grid-column: 4; grid-row: 1; }
.gridpos3 { grid-column: 1; grid-row: 2; }
.gridpos4 { grid-column: 2 / span 2; grid-row: 1 / span 2; transition: all 4s ease-in-out; transform: rotateY(360deg) scale(0.5) scale(2); animation: move 2s; }
.gridpos5 { grid-column: 4; grid-row: 2; }
.gridpos6 { grid-column: 1; grid-row: 3; }
.gridpos7 { grid-column: 2; grid-row: 3; }
.gridpos8 { grid-column: 3; grid-row: 3; }
.gridpos9 { grid-column: 4; grid-row: 3; }
@keyframes move { from { opacity: 0.2; }
to { opacity: 1; } }
.item { font-size: 4em; text-align: center; border: 1px solid #e5e4e9; overflow: hidden; }
.item-1 { background-color: #ef342a; }
.item-2 { background-color: #f68f26; }
.item-3 { background-color: #4ba946;
}
.item-4 { background-color: #0376c2; }
.item-5 { background-color: #c077af; }
.item-6 { background-color: #f8d29d; }
.item-7 { background-color: #b5a87f; }
.item-8 { background-color: #d0e4a9; }
.item-9 { background-color: #4dc7ec; } </style> </head>
<body> <div id="container"> <div class="item item-1 gridpos1" onclick="clickf(1)">1</div> <div class="item item-2 gridpos2" onclick="clickf(2)">2</div> <div class="item item-3 gridpos3" onclick="clickf(3)">3</div> <div class="item item-4 gridpos4" onclick="clickf(4)">4</div> <div class="item item-5 gridpos5" onclick="clickf(5)">5</div> <div class="item item-6 gridpos6" onclick="clickf(6)">6</div> <div class="item item-7 gridpos7" onclick="clickf(7)">7</div> <div class="item item-8 gridpos8" onclick="clickf(8)">8</div> <div class="item item-9 gridpos9" onclick="clickf(9)">9</div> </div>
<script> window.lastIndex = 4;
function clickf(p) { let ele = document.getElementsByClassName(`item-${p}`)[0]; let centerEle = document.getElementsByClassName(`item-${lastIndex}`)[0];
let posName = ""; let eleClassList = ele.classList; for (let i = 0; i < eleClassList.length; i++) { if (eleClassList[i].indexOf("gridpos") !== -1) { posName = eleClassList[i]; break; } }
if (posName === "gridpos4") { console.log("点击了中间") return; }
ele.classList.remove(posName); centerEle.classList.remove("gridpos4")
ele.classList.add("gridpos4"); centerEle.classList.add(posName); window.lastIndex = p;
} </script> </body>
</html>
|
PS
很久都没ps了,在和echarts结合的时候需要注意两点
- 在切换grid位置完成的时候,要发送一个resize事件,当然前提是每个echart要绑定页面大小改变resize事件,这里不展开说
1 2
| let myEvent = new Event('resize'); window.dispatchEvent(myEvent);
|
- 请注意上例中的
overflow: hidden;
这句不然会造成页面的布局混乱