我创建一个表组件,根据收到的数据,它将包含1-10列。列位于响应的容器内,它们永远不会小于100px。根据屏幕尺寸,我想显示所有列,但随着容器变小,我想隐藏不合适的列。
e.g。如果容器的宽度是550px并且有7列。我想隐藏最后两列并显示剩下的5.这5列的宽度应为(550/5 = 110px)。我可以通过简单地将一个类添加到父容器来实现这一点,该容器将子项除以5(20%)。
一旦我隐藏了最后两列,我希望能够单击一个按钮将该行移到显示隐藏的列。请记住,我希望它根据容器中的空间来移动列。 例如如果用户使窗口变小并且容器的宽度现在为380px并且有7列,则一次只能看到三个。如果单击下一个底部,它将显示接下来的三个项目。如果再次单击它将显示最后一个。
我的问题是如何删除多余的列并将我的类应用于父容器?然后我如何点击这些以便我可以查看所有列?下面是我开始编写的JS代码,但我需要帮助将它们放在一起。
function calcSize() {
var tableExpenses = document.querySelectorAll('.table-expenses');
var tableExpensesWidth = document.querySelector('.table-expenses').offsetWidth;
var tableExpensesLength = document.querySelector('.table-expenses').children.length;
if (tableExpensesWidth > 699 ) {
tableExpenses.classList.add('Rtable--7cols');
// remove all other 'Rtable--' classes
}
if (tableExpensesWidth > 599 ) {
tableExpenses.classList.add('Rtable--6cols');
// remove all other 'Rtable--' classes
}
if (tableExpensesWidth > 499) {
tableExpenses.classList.add('Rtable--5cols');
// remove all other 'Rtable--' classes
}
// Do the same thing for other widths...
if (tableExpensesWidth/tableExpensesLength < 100) {
//only show children that can fill that space
}
}
答案 0 :(得分:2)
我认为可以有一个更简单的解决方案,但我试图弄清楚如何做到这将限制JavaScript和media queries。方法是有一个“开始”类,表示“聚焦”表列。隐藏所有不是“开始”列的列,或者不是“start”旁边的已配置数量的兄弟。
这是通过多个adjacent sibling selectors完成的。
在我的示例中,我有一些辅助类来模拟媒体查询而不实际调整屏幕大小。您可以使用单选按钮控制模拟的屏幕大小,以及使用数字输入聚焦的列。
这是很多CSS,但您不必在代码中进行任何元素大小调整。
const m = document.getElementsByTagName("main")[0],
table = document.getElementById("table"),
countInput = document.getElementById("count"),
sizeRadios = document.getElementsByName("size");
const vars = {
get size() {
return this._size;
},
set size(val) {
if (this._size === val) return;
this._size = val;
Array.from(sizeRadios).forEach(r => r.removeAttribute("checked"));
let tmp = document.querySelector(`input[type="radio"][name="size"][value="${val}"]`);
tmp.setAttribute("checked", "");
m.className = this._size;
},
get count() {
return this._count;
},
set count(val) {
if (this._count === val) return;
this._count = val;
countInput.value = val;
this.updateTable();
},
updateTable() {
const trs = table.querySelectorAll("tr");
for (const tr of trs) {
const tds = Array.from(tr.querySelectorAll("th, td"));
if (tds.length < this.count) {
return;
}
tds.forEach(td => td.classList.remove("start"));
tds[this.count - 1].classList.add("start");
}
}
};
Array.from(sizeRadios).forEach(radio => radio.addEventListener("change", e => {
if (!e.target.checked) return;
vars.size = e.target.value;
}));
countInput.addEventListener("input", e => {
vars.count = parseInt(countInput.value, 10);
});
vars.size = "medium";
vars.count = 2;
table {
width: 100%;
}
table th,
table td {
border: 1px solid black;
}
main:not(.default) table th,
main:not(.default) table td {
display: none;
}
/* Simulated Media Query Rules */
main.extra-small table th.start,
main.extra-small table td.start,
main.small table th.start,
main.small table td.start,
main.medium table th.start,
main.medium table td.start,
main.large table th.start,
main.large table td.start,
main.small table th.start+th,
main.small table td.start+td,
main.medium table th.start+th,
main.medium table td.start+td,
main.large table th.start+th,
main.large table td.start+td,
main.medium table th.start+th+th,
main.medium table td.start+td+td,
main.large table th.start+th+th,
main.large table td.start+td+td,
main.large table th.start+th+th+th,
main.large table td.start+td+td+td {
display: table-cell;
}
/* Media Query Rules */
main.media-query table th.start,
main.media-query table td.start {
display: table-cell;
}
@media (min-width: 768px) {
main.media-query table th.start,
main.media-query table td.start,
main.media-query table th.start,
main.media-query table td.start,
main.media-query table th.start+th,
main.media-query table td.start+td {
display: table-cell;
}
}
@media (min-width: 992px) {
main.media-query table th.start,
main.media-query table td.start,
main.media-query table th.start,
main.media-query table td.start,
main.media-query table th.start,
main.media-query table td.start,
main.media-query table th.start+th,
main.media-query table td.start+td,
main.media-query table th.start+th,
main.media-query table td.start+td,
main.media-query table th.start+th+th,
main.media-query table td.start+td+td {
display: table-cell;
}
}
@media (min-width: 1200px) {
main.media-query table th.start,
main.media-query table td.start,
main.media-query table th.start,
main.media-query table td.start,
main.media-query table th.start,
main.media-query table td.start,
main.media-query table th.start,
main.media-query table td.start,
main.media-query table th.start+th,
main.media-query table td.start+td,
main.media-query table th.start+th,
main.media-query table td.start+td,
main.media-query table th.start+th,
main.media-query table td.start+td,
main.media-query table th.start+th+th,
main.media-query table td.start+td+td,
main.media-query table th.start+th+th,
main.media-query table td.start+td+td,
main.media-query table th.start+th+th+th,
main.media-query table td.start+td+td+td {
display: table-cell;
}
}
<main>
<table id="table">
<caption>Table that will adjust how many colums are displayed based on screen size/controlling class.</caption>
<thead>
<tr>
<th>Column 1</th>
<th>Column 2</th>
<th>Column 3</th>
<th>Column 4</th>
<th>Column 5</th>
<th>Column 6</th>
</tr>
</thead>
<tbody>
<tr>
<td>a1</td>
<td>a2</td>
<td>a3</td>
<td>a4</td>
<td>a5</td>
<td>a6</td>
</tr>
<tr>
<td>b1</td>
<td>b2</td>
<td>b3</td>
<td>b4</td>
<td>b5</td>
<td>b6</td>
</tr>
<tr>
<td>c1</td>
<td>c2</td>
<td>c3</td>
<td>c4</td>
<td>c5</td>
<td>c6</td>
</tr>
</tbody>
</table>
<hr>
<div>
<p>Mock media query setter which applies a class to the <code><main></code> tag to simulate media queries.</p>
<ul>
<li><label><input type="radio" name="size" value="default"> <span>Default (all columns)</span></label></li>
<li><label><input type="radio" name="size" value="media-query"> <span>Media Query (follow MQ rules)</span></label></li>
<li><label><input type="radio" name="size" value="extra-small"> <span>Extra Small (1 column)</span></label></li>
<li><label><input type="radio" name="size" value="small"> <span>Small (2 columns)</span></label></li>
<li><label><input type="radio" name="size" value="medium"> <span>Medium (3 columns)</span></label></li>
<li><label><input type="radio" name="size" value="large"> <span>Large (4 columns)</span></label></li>
</ul>
</div>
<hr>
<div>
<p>Sets which column you are "focused" as in which column you have scrolled to.</p>
<label><span>Starting Column</span> <input id="count" type="number" min="1" value="3" step="1"></label>
</div>
</main>