在研究了最近几个小时之后,我开始认为这是不可能的,即使在最新的浏览器中也是如此:
具有水平滚动的HTML table
元素,顶部是“粘性” thead
,是垂直滚动的周围网页的一部分。
这是我的尝试:
#a {
height: 100px;
background-color: green;
}
body {
width: 100%;
}
#wrapper {
overflow-x: scroll;
width: 100%;
}
th {
position:sticky;
top: 0;
background-color: red;
z-index: 1;
}
td {
white-space: nowrap;
}
#b {
height: 2000px;
background-color: blue;
}
<div id="a">
some content
</div>
<div id="wrapper">
<table id="test">
<thead>
<tr>
<th>sticky header</th>
<th>sticky header</th>
<th>sticky header</th>
</tr>
</thead>
<tbody>
<tr>
<td>long content long content long content long content long content long content</td>
<td>long content long content long content long content long content long content</td>
<td>long content long content long content long content long content long content</td>
</tr>
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
</tr>
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
</tr>
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
</tr>
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
</tr>
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
</tr>
</tbody>
</table>
</div>
<div id="b">
some more content
</div>
(还有this fiddle,因此您可以弄乱代码)
当前的方式是,当#wrapper
为overflow-x: scroll
时,“位置:粘性”不起作用。如果删除了overflow-x规则,它会起作用,但是当然表格会扩展整个页面的宽度(绝对不酷)
我知道使表格成为“ scrolling”元素可以解决此问题,但这也不可取(我只希望网页主体可以垂直滚动)。
我试图提出其他CSS解决方案,甚至Javascript解决方案,但我想不出最终可行的解决方案。这实际上是不可能的吗?
虽然我希望使用css
解决方案,但现在我可以使用JavaScript解决方案。
答案 0 :(得分:1)
有一个fiddle并附有有效的示例。您甚至可以通过预先声明宽度/高度来摆脱一些JavaScript。
在原始示例中添加了一些ID
<div id="a">
some content
</div>
<div id="wrapper">
<table id="test">
<thead id="sticky">
<tr id="headerRow">
<th>sticky header</th>
<th>sticky header</th>
<th>sticky header</th>
</tr>
</thead>
<tbody>
<tr>
<td>long content long content long content long content long content long content</td>
<td>long content long content long content long content long content long content</td>
<td>long content long content long content long content long content long content</td>
</tr>
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
</tr>
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
</tr>
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
</tr>
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
</tr>
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
</tr>
</tbody>
</table>
</div>
<div id="b">
some more content
</div>
下面是JavaScript
// When the user scrolls the page, execute addSticky
window.onscroll = function() {addSticky()};
document.getElementById("wrapper").onscroll = function(){addSticky()};
// Get the header
var header = document.getElementById("sticky");
// Get the offset position
var sticky = header.offsetTop;
// Get bottom offset
var bottomOffset = document.getElementById("test").offsetHeight+100;
// Set the width of the row and columns by placing them in an array and looping said array
var headerRow = document.getElementById("headerRow");
header.style.width = headerRow.offsetWidth+"px";
var headerKids = headerRow.children;
for (var i=0; i<headerKids.length; i++){
headerKids[i].style.width=headerKids[i].offsetWidth+"px";
}
// Add the sticky class to the header when you reach its scroll position. Remove "sticky" when you leave the scroll position
function addSticky() {
if (this.scrollY > 100 && this.scrollY < bottomOffset ) {
xScroll = document.getElementById("wrapper").scrollLeft;
header.classList.add("sticky");
header.style.left = "-"+xScroll+"px";
} else {
header.classList.remove("sticky");
}
}
更新为CSS
.sticky {
position: fixed;
top: 0;
height: 20px;
}
答案 1 :(得分:0)
这与您要求的不完全相同,但是请尝试篡改该表:
https://codepen.io/joelPrz/pen/Gclki
for ($i = 0; $i < count($request->products); $i++) {
$l = $request->products[$i]['location'];
// I change it to first instead of get
$locations[] = DB::table('locations')->select('*')->where('location_id', $l)->first();
}
// do foreach loop to fetch that data
foreach ($locations as $key => $location) {
echo $key . " -" . $location->location_id . "<br>";
}
var tee = $('.gridtable thead');
var tw = document.getElementsByClassName('tabWrap')[0];
var cloner = document.getElementsByClassName('tabWrap')[0];
var bd = document.getElementsByClassName('container')[0];
var newTableWrap = document.createElement("div");
var newTable = document.createElement("Table");
var oldTable = document.getElementsByClassName('gridtable')[0];
var childNode = oldTable.childNodes[1];
var wrapW = $(tw).css('width');
var wrapY = $(tw).css('height');
var headHeight = tee.css('height');
//node The node to be cloned.
var dupNode = childNode.cloneNode(true);
newTable.appendChild(dupNode);
newTableWrap.appendChild(newTable);
newTable.classList.add("gridtableT");
newTable.classList.add("gridtable");
$(newTableWrap).css({'width': wrapW, 'overflow':'hidden'});
bd.insertBefore(newTableWrap , tw);
$(oldTable).css('margin-top', ('-' + headHeight) );
$('tr td').filter(":last-child")
.css('border-right-color', 'transparent');
$('tr:last td').css('border-bottom-color', 'transparent');
$(tw).on('scroll', function(e){
var newLeft = e.target.scrollLeft;
$(newTable).css('margin-left', '-' + newLeft + 'px');
});
table { border-collapse: collapse; }
th, td {
border-left-color: transparent!important;
}
.last-cell {
border-right-color: transparent!important;
}
.container {
outline: 1px solid black;
outline-offset: 0px;
width: 800px;
}
.tabWrap {
height: 500px;
margin-right: 30px;
margin-bottom: 0;
overflow: scroll;
width: 800px;
}
.gridtable {
color:#333333;
font-family: verdana,arial,sans-serif;
font-size:11px;
}
.gridtable th {
border-width: 1px;
border-style: solid;
border-color: #666666;
background-color: #dedede;
padding: 8px;
}
.gridtable td {
border-width: 1px;
padding: 8px;
border-style: solid;
border-color: #666666;
background-color: #ffffff;
}
.gridtableT { color: red; }
.gridtableT th { border-top-color: transparent; }
.lastRow td {
background-color: lightcyan;
}
div.tabWrap th {
border-bottom-color: transparent!important;
border-top-color: transparent!important;
}
页眉是粘性的,但仅在表格内部,而不在页面内部。因此maby您可以根据自己的需要进行更改。
(通过链接打开代码,我在此处复制的代码有某种错误)
答案 2 :(得分:0)
如果您使用overflow
以外的其他任何方式使用visible
,则必须为元素提供固定的高度,否则,当滚动父元素时,该元素已准备好粘贴,但高度不受限制。
一个简单的CSS解决方案是使用视口(即#wrapper
)来赋予vh
高度
#wrapper {
height: 30vh;
overflow-x: scroll;
width: 100%;
}
#a {
height: 100px;
background-color: green;
}
body {
width: 100%;
}
#wrapper {
overflow-x: scroll;
width: 100%;
height: 30vh;
}
th {
position:sticky;
top: 0;
background-color: red;
z-index: 1;
}
td {
white-space: nowrap;
}
#b {
height: 2000px;
background-color: blue;
}
#scroller{
width: 100%;
height: 400px;
overflow:auto;
}
<div id="a">
some content
</div>
<div id="wrapper">
<table id="test">
<thead>
<tr>
<th>sticky header</th>
<th>sticky header</th>
<th>sticky header</th>
</tr>
</thead>
<tbody>
<tr>
<td>long content long content long content long content long content long content</td>
<td>long content long content long content long content long content long content</td>
<td>long content long content long content long content long content long content</td>
</tr>
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
</tr>
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
</tr>
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
</tr>
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
</tr>
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
</tr>
</tbody>
</table>
</div>
<div id="b">
some more content
</div>
答案 3 :(得分:0)
将position: sticky
用于表是适用的。请参见下面的代码。
thead th { position: sticky; top: 0; }
<table>
<thead>
<tr>
<th>column 1</th>
<th>column 2</th>
<th>column 3</th>
<th>column 4</th>
</tr>
</thead>
<tbody>
<tr>
<td>Data One</td>
<td>Data Two</td>
<td>Data Three</td>
<td>Data Four</td>
</tr>
<tr>
<td>Data One</td>
<td>Data Two</td>
<td>Data Three</td>
<td>Data Four</td>
</tr>
<tr>
<td>Data One</td>
<td>Data Two</td>
<td>Data Three</td>
<td>Data Four</td>
</tr>
<tr>
<td>Data One</td>
<td>Data Two</td>
<td>Data Three</td>
<td>Data Four</td>
</tr>
<tr>
<td>Data One</td>
<td>Data Two</td>
<td>Data Three</td>
<td>Data Four</td>
</tr>
<tr>
<td>Data One</td>
<td>Data Two</td>
<td>Data Three</td>
<td>Data Four</td>
</tr>
<tr>
<td>Data One</td>
<td>Data Two</td>
<td>Data Three</td>
<td>Data Four</td>
</tr>
<tr>
<td>Data One</td>
<td>Data Two</td>
<td>Data Three</td>
<td>Data Four</td>
</tr>
<tr>
<td>Data One</td>
<td>Data Two</td>
<td>Data Three</td>
<td>Data Four</td>
</tr>
<tr>
<td>Data One</td>
<td>Data Two</td>
<td>Data Three</td>
<td>Data Four</td>
</tr>
<tr>
<td>Data One</td>
<td>Data Two</td>
<td>Data Three</td>
<td>Data Four</td>
</tr>
<tr>
<td>Data One</td>
<td>Data Two</td>
<td>Data Three</td>
<td>Data Four</td>
</tr>
<tr>
<td>Data One</td>
<td>Data Two</td>
<td>Data Three</td>
<td>Data Four</td>
</tr>
<tr>
<td>Data One</td>
<td>Data Two</td>
<td>Data Three</td>
<td>Data Four</td>
</tr>
<tr>
<td>Data One</td>
<td>Data Two</td>
<td>Data Three</td>
<td>Data Four</td>
</tr>
<tr>
<td>Data One</td>
<td>Data Two</td>
<td>Data Three</td>
<td>Data Four</td>
</tr>
<tr>
<td>Data One</td>
<td>Data Two</td>
<td>Data Three</td>
<td>Data Four</td>
</tr>
<tr>
<td>Data One</td>
<td>Data Two</td>
<td>Data Three</td>
<td>Data Four</td>
</tr>
<tr>
<td>Data One</td>
<td>Data Two</td>
<td>Data Three</td>
<td>Data Four</td>
</tr>
<tr>
<td>Data One</td>
<td>Data Two</td>
<td>Data Three</td>
<td>Data Four</td>
</tr><tr>
<td>Data One</td>
<td>Data Two</td>
<td>Data Three</td>
<td>Data Four</td>
</tr>
</tbody>
</table>
请参阅https://caniuse.com/#feat=css-sticky,在这里可以检查该功能是否可用。
答案 4 :(得分:0)
我发现jquery.floatThead
包确实可以满足我的需求,但我只是缺少此设置:
$("table").floatThead({
position:"absolute"
});
默认为“固定”,在这种情况下不起作用。
您可以看到固定的小提琴here,它完全按照我的需要工作。
不过,我需要一个javascript包来完成如此简单的任务,这有点荒谬。如果我遗漏了一些东西,并且对这个基本问题有一个更简单的答案,我很想听听! ?