背景:我正在使用一个仪表板,该仪表板下面显示一个标题和一个表格。该表可以有很多行(超过100行)。
问题:大量行会触发显示垂直滚动条,从而隐藏其余行。
可能的解决方案:我想轮换一下,仪表板所在的每个屏幕上都显示哪些表行。我想避免设置固定数量的在屏幕上可见的行,而是确定在滚动条出现之前可以在屏幕上放置多少行。这意味着,首先,我想确定在滚动条出现之前屏幕上可见多少行,然后创建轮播动画,在该动画中显示下一个X行,直到显示所有行并重置动画为止。
使用的技术:React JS,Bootstrap表
对于轮播部分,我发现Bootstrap Carousel可以正常工作,但问题是要弄清楚屏幕上可见多少行。如何确定在滚动条出现之前可以在屏幕上显示多少行?非常感谢你!
答案 0 :(得分:1)
一种可能的解决方案是:
在DOM中创建一个元素,该元素的高度将为100%(其他任何可能的高度也将起作用)。例如:
<div id="row-wrapper" style="height: 100%"></div>
获取元素的高度。
var availableHeight = document.getElementById('row-wrapper').clientHeight;
知道单行占用了多少高度,只需将availableHeight除以,就可以知道要渲染多少行。如果您的行高是30:
var numberOfRows = Math.floor(availableHeight / 30);
答案 1 :(得分:0)
这是一个示例,您可以在整个div之前填充它。如果有人对此感兴趣,也可以做出jQuery答案。
我做了2格。一个具有设定高度的示例(在示例中为100%,但也可以为静态高度),并且在一个随内容而增长的可增长div中。
首先,它将填充可增长的div,只要它小于内容div。 最后添加的元素可以大于剩余空间。如果发生这种情况,它将删除最后一个元素。
这也适用于具有动态高度的内容。
注意:使用while循环时,最好有一个备份计划来避免无限循环。因此,我添加了一个max records变量。
Javascript:
window.onload = function() {
document.getElementById('fill').onclick = function() {
var content = document.getElementById('content');
var growableWrapper = document.getElementById('growableWrapper');
var maxRecords = 50;
while ((content.childNodes.length === 0 || parseInt(window.getComputedStyle(growableWrapper).height) < parseInt(window.getComputedStyle(content).height)) && growableWrapper.childNodes.length < maxRecords) {
var newElement = document.createElement("p");
var newText = document.createTextNode("Test");
newElement.appendChild(newText);
growableWrapper.appendChild(newElement);
}
if (window.getComputedStyle(growableWrapper).height > window.getComputedStyle(content).height && growableWrapper.childNodes.length > 1) {
growableWrapper.removeChild(growableWrapper.childNodes[growableWrapper.childNodes.length - 1]);
}
}
}
html,
body,
#content {
margin: 0;
padding: 0;
height: 100%;
}
#fill,
#content {
width: 40%;
float: left;
}
#content {
background-color: gray;
overflow: hidden;
}
#growableWrapper {
background-color: lightgray;
overflow: auto;
}
<div>
<button id="fill">Fill</button>
</div>
<div id="content">
<div id="growableWrapper">
</div>
</div>
jQuery:
$(document).ready(function() {
$('#fill').on('click', function() {
var content = $('#content');
var growableWrapper = $('#growableWrapper');
var maxRecords = 50;
while ((content.children().length === 0 || growableWrapper.height() < content.height()) && growableWrapper.children().length < maxRecords) {
growableWrapper.append('<p>test</p>');
}
if(growableWrapper.height() > content.height() && growableWrapper.children().length > 1) {
growableWrapper.children().last().remove();
}
});
});
html,
body,
#content {
margin: 0;
padding: 0;
height: 100%;
}
#fill, #content {
width: 40%;
float: left;
}
#content {
background-color: gray;
overflow: hidden;
}
#growableWrapper {
background-color: lightgray;
overflow: auto;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
<button id="fill">Fill</button>
</div>
<div id="content">
<div id="growableWrapper">
</div>
</div>
答案 2 :(得分:0)
我知道您标记了ReactJS,但是一个很好的基础是始终保持DOM尽可能的小。我的策略是将数据保留在JavaScript中,仅向DOM介绍绝对需要的内容。
下面是一个简单的示例,显示了10个带有偏移量的行:
var dummyData = [];
(function populateData() {
var names = ["Greg", "Jeff", "Bob", "Bruce", "Clark", "Diana"];
while (dummyData.length < 100000) {
dummyData.push({
name: names[Math.floor(Math.random() * names.length)],
age: Math.floor(Math.random() * 100)
});
}
})();
function displayData(data, offset, limit) {
if (offset === void 0) {
offset = 0;
}
if (limit === void 0) {
limit = data.length;
}
var tbody = document.body.appendChild(document.createElement("tbody"));
for (var i = offset; i < (limit + offset); i++) {
if (i >= data.length) {
break;
}
var person = data[i];
var tr = tbody.appendChild(document.createElement("tr"));
tr.innerHTML = "<td>" + i + "</td><td>" + person.name + "</td><td>" + person.age + "</td>";
}
return tbody;
}
var pagesize = 10;
var offset = 0;
var offsetInput = document.body.appendChild(document.createElement("input"));
offsetInput.type = "number";
offsetInput.min = "0";
offsetInput.value = "0";
var table = document.body.appendChild(document.createElement("table"));
table.style.width = "100%";
table.innerHTML = "<thead><tr><th>Index</th><th>Name</th><th>Age</th></tr></thead>";
var tbody = table.appendChild(displayData(dummyData, offset, pagesize));
function update() {
if (offsetInput.validity.valid) {
offset = parseInt(offsetInput.value, 10);
table.removeChild(tbody);
tbody = displayData(dummyData, offset, pagesize);
table.appendChild(tbody);
}
}
offsetInput.addEventListener("change", update);
offsetInput.addEventListener("keyup", update);
从这里开始,将需要一些CSS技巧并读取滚动条以获取偏移量。
var dummyData = [];
(function populateData() {
var names = ["Greg", "Jeff", "Bob", "Bruce", "Clark", "Diana"];
while (dummyData.length < 100) {
dummyData.push({
name: names[Math.floor(Math.random() * names.length)],
age: Math.floor(Math.random() * 100)
});
}
})();
function displayData(data, offset, limit) {
if (offset === void 0) {
offset = 0;
}
if (limit === void 0) {
limit = data.length;
}
var tbody = document.body.appendChild(document.createElement("tbody"));
for (var i = offset; i < (limit + offset); i++) {
if (i >= data.length) {
break;
}
var person = data[i];
var tr = tbody.appendChild(document.createElement("tr"));
tr.innerHTML = "<td>" + i + "</td><td>" + person.name + "</td><td>" + person.age + "</td>";
}
return tbody;
}
var pagesize = 10;
var offset = 0;
var offsetInput = document.body.appendChild(document.createElement("input"));
offsetInput.type = "number";
offsetInput.min = "0";
offsetInput.max = "" + (dummyData.length - pagesize);
offsetInput.value = "0";
var outerContainer = document.body.appendChild(document.createElement("div"));
outerContainer.style.maxHeight = "400px";
outerContainer.style.width = "450px";
outerContainer.style.overflowY = "scroll";
var innerContainer = outerContainer.appendChild(document.createElement("div"));
innerContainer.style.height = dummyData.length * 20 + 200 + "px";
var table = innerContainer.appendChild(document.createElement("table"));
table.style.position = "absolute";
table.style.width = "400px";
table.innerHTML = "<thead><tr><th>Index</th><th>Name</th><th>Age</th></tr></thead>";
var tbody = table.appendChild(displayData(dummyData, offset, pagesize));
var handle;
function update() {
table.removeChild(tbody);
tbody = displayData(dummyData, offset, pagesize);
table.appendChild(tbody);
clearTimeout(handle);
handle = setTimeout(function() {
offsetInput.value = offset.toString();
outerContainer.scrollTop = offset * 20;
}, 100);
}
function updateInput() {
if (offsetInput.validity.valid) {
offset = parseInt(offsetInput.value, 10);
}
update();
}
function updateScroll() {
offset = Math.floor(outerContainer.scrollTop / 20);
update();
}
outerContainer.addEventListener("scroll", updateScroll);
offsetInput.addEventListener("change", updateInput);
offsetInput.addEventListener("keyup", updateInput);