자바스크립트와 CSS를 사용하여 스크롤할 때 테이블의 첫 번째 행과 첫 번째 열을 잠그려면 어떻게 해야 합니까?
'freeze panes'를 활성화할 때 Excel에서처럼 첫 번째 행과 첫 번째 열이 모두 잠긴 테이블을 어떻게 만들 수 있습니까?수평 및 수직으로 스크롤할 수 있는 테이블이 필요합니다(이에 대한 솔루션은 많이 있지만 수직 스크롤만 허용됨).
따라서 표에서 아래로 스크롤할 때 첫 번째 행은 열 제목이 있기 때문에 그대로 유지됩니다.이것은 결국에 있을 수도 있습니다.thead
또는 그렇지 않을 수도 있습니다. 해결책을 더 쉽게 만드는 것이 무엇이든.
오른쪽으로 스크롤하면 첫 번째 열에 행 레이블이 고정되므로 첫 번째 열은 그대로 유지됩니다.
CSS만으로는 이것이 불가능하다는 것을 꽤 확신합니다만, 누가 저를 자바스크립트 솔루션으로 안내할 수 있습니까?모든 주요 브라우저에서 작동해야 합니다.
아, 저는 이 특정 요구 사항의 필요성을 이해하기 위해 고정된 열이 있는 스크롤 가능한 테이블을 찾았고 당신의 질문은 근접한 답변이 없는 것 중 하나였습니다.
저는 이 질문에 답했습니다. 고정 스크롤 행과 고정 스크롤 열이 있는 동적으로 크기가 큰 HTML 테이블로 플러그인으로서의 제 작업을 보여주는 데 영감을 받았습니다. https://github.com/meetselva/fixed-table-rows-cols
플러그인은 기본적으로 잘 포맷된 HTML 테이블을 고정된 테이블 헤더와 열이 있는 스크롤 가능한 테이블로 변환합니다.
용도는 아래와 같습니다.
$('#myTable').fxdHdrCol({
fixedCols : 3, /* 3 fixed columns */
width : "100%", /* set the width of the container (fixed or percentage)*/
height : 500 /* set the height of the container */
});
이 작업은 다음과 같은 조합으로 수행되었습니다.
- 여러 테이블 사용
- 고정 크기 셀
- jQuery의 스크롤상단 및 스크롤좌측 기능
여기에 시연할 jsfidle 예가 있습니다.
모든 브라우저에서 테스트하지는 않았지만 오래된 IE 버전에서는 좋지 않은 것 같습니다.
$("#clscroll-content").scroll(function() {
$("#clscroll-row-headers").scrollTop($("#clscroll-content").scrollTop());
$("#clscroll-column-headers").scrollLeft($("#clscroll-content").scrollLeft());
});
$("#clscroll-column-headers").scroll(function() {
$("#clscroll-content").scrollLeft($("#clscroll-column-headers").scrollLeft());
});
$("#clscroll-row-headers").scroll(function() {
$("#clscroll-content").scrollTop($("#clscroll-row-headers").scrollTop());
});
.clscroll table {
table-layout: fixed;
}
.clscroll td, .clscroll th {
overflow: hidden;
}
.corner-header {
float: left;
}
.column-headers {
float: left;
overflow: scroll;
}
.row-headers {
clear: both;
float: left;
overflow: scroll;
}
.table-content {
table-layout: fixed;
float: left;
overflow: scroll;
}
.clscroll td, .clscroll th {
width: 200px;
border: 1px solid black;
}
.row-headers, .table-content {
height: 100px;
}
.column-headers, .table-content, .table-content table, .column-headers table {
width: 400px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="clscroll corner-header">
<table>
<tr>
<th> </th>
</tr>
</table>
</div>
<div class="clscroll column-headers" id="clscroll-column-headers">
<table>
<tr>
<th>Bus</th>
<th>Plane</th>
<th>Boat</th>
<th>Bicycle</th>
</tr>
</table>
</div>
<div class="clscroll row-headers" id="clscroll-row-headers">
<table>
<tr>
<th>Red</th>
</tr>
<tr>
<th>Green</th>
</tr>
<tr>
<th>Blue</th>
</tr>
<tr>
<th>Orange</th>
</tr>
<tr>
<th>Purple</th>
</tr>
<tr>
<th>Yellow</th>
</tr>
<tr>
<th>Pink</th>
</tr>
<tr>
<th>Brown</th>
</tr>
</table>
</div>
<div class="clscroll table-content" id="clscroll-content">
<table>
<tr>
<td>Red Bus</td>
<td>Red Plane</td>
<td>Red Boat</td>
<td>Red Bicycle</td>
</tr>
<tr>
<td>Green Bus</td>
<td>Green Plane</td>
<td>Green Boat</td>
<td>Green Bicycle</td>
</tr>
<tr>
<td>Blue Bus</td>
<td>Blue Plane</td>
<td>Blue Boat</td>
<td>Blue Bicycle</td>
</tr>
<tr>
<td>Orange Bus</td>
<td>Orange Plane</td>
<td>Orange Boat</td>
<td>Orange Bicycle</td>
</tr>
<tr>
<td>Purple Bus</td>
<td>Purple Plane</td>
<td>Purple Boat</td>
<td>Purple Bicycle</td>
</tr>
<tr>
<td>Yellow Bus</td>
<td>Yellow Plane</td>
<td>Yellow Boat</td>
<td>Yellow Bicycle</td>
</tr>
<tr>
<td>Pink Bus</td>
<td>Pink Plane</td>
<td>Pink Boat</td>
<td>Pink Bicycle</td>
</tr>
<tr>
<td>Brown Bus</td>
<td>Brown Plane</td>
<td>Brown Boat</td>
<td>Brown Bicycle</td>
</tr>
</table>
</div>
두 개의 테이블이 필요합니다. 첫 번째 테이블은 두 번째 테이블 위에 정확히 겹쳐 놓아야 합니다.두 번째 열에는 모든 데이터가 포함되어 있으며, 첫 번째 열에는 첫 번째 열만 포함되어 있습니다.너비와 내용에 따라 행 높이를 동기화해야 합니다.
이 두 개의 테이블 외에도 세 번째 테이블이 필요합니다.이것이 첫 번째 행입니다. 다른 두 행 사이에 정확히 위치하고 동일한 방식으로 동기화되어야 합니다.
여기에 절대적인 위치를 지정해야 합니다.그런 다음 데이터 테이블의 스크롤을 헤드 행 및 첫 번째 열 테이블의 스크롤 위치와 동기화합니다.
한 가지 문제를 제외하고 모든 주요 브라우저에서 이 기능이 매우 잘 작동합니다.동기화된 스크롤이 펄럭입니다.이 문제를 해결하려면 머리글 행과 첫 번째 열의 내용 복제본을 저장하는 두 개의 추가 div 컨테이너가 필요합니다.수직으로 스크롤할 때 머리글 행 클론을 표시하여 흔들림을 방지하고 원본을 백그라운드에서 재배치할 수 있습니다.수평으로 스크롤할 때 첫 번째 행 클론이 표시됩니다.여기도 마찬가지야.
나는 여기에 내 jQuery 플러그인 솔루션을 게시했습니다: 스크롤 가능한 div 내부의 동결된 테이블 헤더.
그것은 정확히 당신이 원하는 것을 하고 정말 가볍고 사용하기 쉽습니다.
오늘날 이를 위한 크로스 브라우저 솔루션은 꽤 많은데, 그 중에는 우아하고 단순해서 마음에 드는 SuperTable(현재 MoGrid에서 계속 사용되고 있음)과 멋진 기능 세트를 갖춘 SlickGrid가 있습니다.
당신은 그것을 테스트해야 할 것이지만 만약 당신의 페이지에 iframe을 내장하고 CSS를 사용하여 iframe 페이지에서 첫 번째 행과 열을 0.0으로 절대적으로 위치시킨다면 그것이 당신의 문제를 해결할 수 있을까요?
여기 플러그인 JQuery: https://github.com/nitsugario/jQuery-Freeze-Table-Column-and-Rows
테이블 행과 열이 스크롤되지 않도록 할 수 있는 jQuery 플러그인입니다.지정된 HTML 테이블 개체를 사용하여 지정된 수의 열 또는 행 또는 둘 다를 고정하여 고정된 열 또는 행이 스크롤되지 않도록 설정할 수 있습니다.고정할 행은 테이블 헤드 섹션에 배치해야 합니다.colspan 또는 rowspan 속성을 사용하여 결합된 행과 열을 고정할 수도 있습니다.
div 에 넣는 은 어떻습니까?overflow: scroll;
으로 만들고, " 헤더 번째 위에 수 .<div>
.
하지만 수평으로 스크롤할 때 어떻게 작동할지는 잘 모르겠습니다.
테이블 정렬 및 잠금은 IE 이외의 다른 브라우저에서 작동하는 유일한 솔루션입니다. (비록 이 "잠긴 열 CSS"도 작동할 수 있지만)아래에 필요한 코드 블록입니다.
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<meta name="robots" content="noindex, nofollow">
<meta name="googlebot" content="noindex, nofollow">
<script type="text/javascript" src="/js/lib/dummy.js"></script>
<link rel="stylesheet" type="text/css" href="/css/result-light.css">
<style type="text/css">
/* Scrollable Content Height */
.scrollContent {
height:100px;
overflow-x:hidden;
overflow-y:auto;
}
.scrollContent tr {
height: auto;
white-space: nowrap;
}
/* Prevent Mozilla scrollbar from hiding right-most cell content */
.scrollContent tr td:last-child {
padding-right: 20px;
}
/* Fixed Header Height */
.fixedHeader tr {
position: relative;
height: auto;
}
/* Put border around entire table */
div.TableContainer {
border: 1px solid #7DA87D;
}
/* Table Header formatting */
.headerFormat {
background-color: white;
color: #FFFFFF;
margin: 3px;
padding: 1px;
white-space: nowrap;
font-family: Helvetica;
font-size: 16px;
text-decoration: none;
font-weight: bold;
}
.headerFormat tr td {
border: 1px solid #000000;
background-color: #7DA87D;
}
/* Table Body (Scrollable Content) formatting */
.bodyFormat tr td {
color: #000000;
margin: 3px;
padding: 1px;
border: 0px none;
font-family: Helvetica;
font-size: 12px;
}
/* Use to set different color for alternating rows */
.alternateRow {
background-color: #E0F1E0;
}
/* Styles used for SORTING */
.point {
cursor:pointer;
}
td.sortedColumn {
background-color: #E0F1E0;
}
tr.alternateRow td.sortedColumn {
background-color: #c5e5c5;
}
.total {
background-color: #FED362;
color: #000000;
white-space: nowrap;
font-size: 12px;
text-decoration: none;
}
</style>
<title></title>
<script type='text/javascript'>//<![CDATA[
/* This script and many more are available free online at
The JavaScript Source :: http://www.javascriptsource.com
Created by: Stan Slaughter :: http://www.stansight.com/ */
/* ======================================================
Generic Table Sort
Basic Concept: A table can be sorted by clicking on the title of any
column in the table, toggling between ascending and descending sorts.
Assumptions:
* The first row of the table contains column titles that are "clicked"
to sort the table
* The images 'desc.gif','asc.gif','none.gif','sorting.gif' exist
* The img tag is in each column of the the title row to represent the
sort graphic.
* The CSS classes 'alternateRow' and 'sortedColumn' exist so we can
have alternating colors for each row and a highlight the sorted
column. Something like the <style> definition below, but with the
background colors set to whatever you want.
<style>
tr.alternateRow {
background-color: #E0F1E0;
}
td.sortedColumn {
background-color: #E0F1E0;
}
tr.alternateRow td.sortedColumn {
background-color: #c5e5c5;
}
</style>
====================================================== */
function sortTable(td_element,ignoreLastLines) {
// If the optional ignoreLastLines parameter (number of lines *not* to sort at end of table)
// was not passed then make it 0
ignoreLastLines = (typeof(ignoreLastLines)=='undefined') ? 0 : ignoreLastLines;
var sortImages =['data:image/gif;base64,R0lGODlhCgAKAMQXAJOkk3mReXume3uTe3mieXGPcXOYc/Hx8Xadds/Wz9vg24ejh3GUcYOgg6a0pnGVcfP18+3w7c3TzdPY06u4q/r8+v///////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAABcALAAAAAAKAAoAAAUz4IVcZDleixQIQjA1pFFZx2FVRklZvOWUl8LsVgBeFLyE8TLgDZYESISwvAAA1QvjAQwBADs=','data:image/gif;base64,R0lGODlhCgAKAMQXAJOkk3mReXume3uTe3mieXGPcXOYc/Hx8Xadds/Wz9vg24ejh3GUcYOgg6a0pnGVcfP18+3w7c3TzdPY06u4q/r8+v///////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAABcALAAAAAAKAAoAAAUw4CVeDzOeFwCgIhFBBDtY1sAmtIIWFV0VJweNRhkZeoeDpWIQNSYBgSAgWYgQLGwIADs=','data:image/gif;base64,R0lGODlhCgAKALMLAHaRdnCTcHegd7C8sNTa1Ku4q9vg24GXgfr8+uDl4P///////wAAAAAAAAAAAAAAACH5BAEAAAsALAAAAAAKAAoAAAQfcMlJq12hIHKoSEqIdBIQnslknkoqfedIBQNikFduRQA7','http://web.archive.org/web/20150906203819im_/http://www.javascriptsource.com/miscellaneous/sorting.gif'];
// Get the image used in the first row of the current column
var sortColImage = td_element.getElementsByTagName('img')[0];
// If current image is 'asc.gif' or 'none.gif' (elements 1 and 2 of sortImages array) then this will
// be a descending sort else it will be ascending - get new sort image icon and set sort order flag
var sortAscending = false;
var newSortColImage = "";
if (sortColImage.getAttribute('src').indexOf(sortImages[1])>-1 ||
sortColImage.getAttribute('src').indexOf(sortImages[2])>-1) {
newSortColImage = sortImages[0];
sortAscending = false;
} else {
newSortColImage = sortImages[1];
sortAscending = true;
}
// Assign "SORTING" image icon (element 3 of sortImages array)) to current column title
// (will replace with newSortColImage when sort completes)
sortColImage.setAttribute('src',sortImages[3]);
// Find which column was clicked by getting it's column position
var indexCol = td_element.cellIndex;
// Get the table element from the td element that was passed as a parameter to this function
var table_element = td_element.parentNode;
while (table_element.nodeName != "TABLE") {
table_element = table_element.parentNode;
}
// Get all "tr" elements from the table and assign then to the Array "tr_elements"
var tr_elements = table_element.getElementsByTagName('tr');
// Get all the images used in the first row then set them to 'none.gif'
// (element 2 or sortImages array) except for the current column (all ready been changed)
var allImg = tr_elements[0].getElementsByTagName('img');
for(var i=0;i<allImg.length;i++){
if(allImg[i]!=sortColImage){allImg[i].setAttribute('src',sortImages[2])}
}
// Some explantion of the basic concept of the following code before we
// actually start. Essentially we are going to copy the current columns information
// into an array to be sorted. We'll sort the column array then go back and use the information
// we saved about the original row positions to re-order the entire table.
// We are never really sorting more than a columns worth of data, which should keep the sorting fast.
// Create a new array for holding row information
var clonedRows = new Array()
// Create a new array to store just the selected column values, not the whole row
var originalCol = new Array();
// Now loop through all the data row elements
// NOTE: Starting at row 1 because row 0 contains the column titles
for (var i=1; i<tr_elements.length - ignoreLastLines; i++) {
// "Clone" the tr element i.e. save a copy all of its attributes and values
clonedRows[i]=tr_elements[i].cloneNode(true);
// Text value of the selected column on this row
var valueCol = getTextValue(tr_elements[i].cells[indexCol]);
// Format text value for sorting depending on its type, ie Date, Currency, number, etc..
valueCol = FormatForType(valueCol);
// Assign the column value AND the row number it was originally on in the table
originalCol[i]=[valueCol,tr_elements[i].rowIndex];
}
// Get rid of element "0" from this array. A value was never assigned to it because the first row
// in the table just contained the column titles, which we did not bother to assign.
originalCol.shift();
// Sort the column array returning the value of a sort into a new array
sortCol = originalCol.sort(sortCompare);
// If it was supposed to be an Ascending sort then reverse the order
if (sortAscending) { sortCol.reverse(); }
// Now take the values from the sorted column array and use that information to re-arrange
// the order of the tr_elements in the table
for (var i=1; i < tr_elements.length - ignoreLastLines; i++) {
var old_row = sortCol[i-1][1];
var new_row = i;
tr_elements[i].parentNode.replaceChild(clonedRows[old_row],tr_elements[new_row]);
}
// Format the table, making the rows alternating colors and highlight the sorted column
makePretty(table_element,indexCol,ignoreLastLines);
// Assign correct sort image icon to current column title
sortColImage.setAttribute('src',newSortColImage);
}
// Function used by the sort routine to compare the current value in the array with the next one
function sortCompare (currValue, nextValue) {
// Since the elements of this array are actually arrays themselves, just sort
// on the first element which contiains the value, not the second which contains
// the original row position
if ( currValue[0] == nextValue[0] ) return 0;
if ( currValue[0] < nextValue[0] ) return -1;
if ( currValue[0] > nextValue[0] ) return 1;
}
//-----------------------------------------------------------------------------
// Functions to get and compare values during a sort.
//-----------------------------------------------------------------------------
// This code is necessary for browsers that don't reflect the DOM constants
// (like IE).
if (document.ELEMENT_NODE == null) {
document.ELEMENT_NODE = 1;
document.TEXT_NODE = 3;
}
function getTextValue(el) {
var i;
var s;
// Find and concatenate the values of all text nodes contained within the
// element.
s = "";
for (i = 0; i < el.childNodes.length; i++)
if (el.childNodes[i].nodeType == document.TEXT_NODE)
s += el.childNodes[i].nodeValue;
else if (el.childNodes[i].nodeType == document.ELEMENT_NODE &&
el.childNodes[i].tagName == "BR")
s += " ";
else
// Use recursion to get text within sub-elements.
s += getTextValue(el.childNodes[i]);
return normalizeString(s);
}
// Regular expressions for normalizing white space.
var whtSpEnds = new RegExp("^\\s*|\\s*$", "g");
var whtSpMult = new RegExp("\\s\\s+", "g");
function normalizeString(s) {
s = s.replace(whtSpMult, " "); // Collapse any multiple whites space.
s = s.replace(whtSpEnds, ""); // Remove leading or trailing white space.
return s;
}
// Function used to modify values to make then sortable depending on the type of information
function FormatForType(itm) {
var sortValue = itm.toLowerCase();
// If the item matches a date pattern (MM/DD/YYYY or MM/DD/YY or M/DD/YYYY)
if (itm.match(/^\d\d[\/-]\d\d[\/-]\d\d\d\d$/) ||
itm.match(/^\d\d[\/-]\d\d[\/-]\d\d$/) ||
itm.match(/^\d[\/-]\d\d[\/-]\d\d\d\d$/) ) {
// Convert date to YYYYMMDD format for sort comparison purposes
// y2k notes: two digit years less than 50 are treated as 20XX, greater than 50 are treated as 19XX
var yr = -1;
if (itm.length == 10) {
sortValue = itm.substr(6,4)+itm.substr(0,2)+itm.substr(3,2);
} else if (itm.length == 9) {
sortValue = itm.substr(5,4)+"0" + itm.substr(0,1)+itm.substr(2,2);
} else {
yr = itm.substr(6,2);
if (parseInt(yr) < 50) {
yr = '20'+yr;
} else {
yr = '19'+yr;
}
sortValue = yr+itm.substr(3,2)+itm.substr(0,2);
}
}
// If the item matches a Percent patten (contains a percent sign)
if (itm.match(/%/)) {
// Replace anything that is not part of a number (decimal pt, neg sign, or 0 through 9) with an empty string.
sortValue = itm.replace(/[^0-9.-]/g,'');
sortValue = parseFloat(sortValue);
}
// If item starts with a "(" and ends with a ")" then remove them and put a negative sign in front
if (itm.substr(0,1) == "(" & itm.substr(itm.length - 1,1) == ")") {
itm = "-" + itm.substr(1,itm.length - 2);
}
// If the item matches a currency pattern (starts with a dollar or negative dollar sign)
if (itm.match(/^[£$]|(^-)/)) {
// Replace anything that is not part of a number (decimal pt, neg sign, or 0 through 9) with an empty string.
sortValue = itm.replace(/[^0-9.-]/g,'');
if (isNaN(sortValue)) {
sortValue = 0;
} else {
sortValue = parseFloat(sortValue);
}
}
// If the item matches a numeric pattern
if (itm.match(/(\d*,\d*$)|(^-?\d\d*\.\d*$)|(^-?\d\d*$)|(^-?\.\d\d*$)/)) {
// Replace anything that is not part of a number (decimal pt, neg sign, or 0 through 9) with an empty string.
sortValue = itm.replace(/[^0-9.-]/g,'');
// sortValue = sortValue.replace(/,/g,'');
if (isNaN(sortValue)) {
sortValue = 0;
} else {
sortValue = parseFloat(sortValue);
}
}
return sortValue;
}
//-----------------------------------------------------------------------------
// Functions to update the table appearance after a sort.
//-----------------------------------------------------------------------------
// Style class names.
var rowClsNm = "alternateRow";
var colClsNm = "sortedColumn";
// Regular expressions for setting class names.
var rowTest = new RegExp(rowClsNm, "gi");
var colTest = new RegExp(colClsNm, "gi");
function makePretty(tblEl, col, ignoreLastLines) {
var i, j;
var rowEl, cellEl;
// Set style classes on each row to alternate their appearance.
for (i = 1; i < tblEl.rows.length - ignoreLastLines; i++) {
rowEl = tblEl.rows[i];
rowEl.className = rowEl.className.replace(rowTest, "");
if (i % 2 != 0)
rowEl.className += " " + rowClsNm;
rowEl.className = normalizeString(rowEl.className);
// Set style classes on each column (other than the name column) to
// highlight the one that was sorted.
for (j = 0; j < tblEl.rows[i].cells.length; j++) {
cellEl = rowEl.cells[j];
cellEl.className = cellEl.className.replace(colTest, "");
if (j == col)
cellEl.className += " " + colClsNm;
cellEl.className = normalizeString(cellEl.className);
}
}
}
// END Generic Table sort.
// =================================================
// Function to scroll to top before sorting to fix an IE bug
// Which repositions the header off the top of the screen
// if you try to sort while scrolled to bottom.
function GoTop() {
document.getElementById('TableContainer').scrollTop = 0;
}
//]]>
</script>
</head>
<body>
<table cellpadding="0" cellspacing="0" border="0">
<tr><td>
<div id="TableContainer" class="TableContainer" style="height:230px;">
<table class="scrollTable">
<thead class="fixedHeader headerFormat">
<tr>
<td class="point" onclick="GoTop(); sortTable(this,1);" title="Sort"><b>NAME</b> <img src="data:image/gif;base64,R0lGODlhCgAKALMLAHaRdnCTcHegd7C8sNTa1Ku4q9vg24GXgfr8+uDl4P///////wAAAAAAAAAAAAAAACH5BAEAAAsALAAAAAAKAAoAAAQfcMlJq12hIHKoSEqIdBIQnslknkoqfedIBQNikFduRQA7" border="0"></td>
<td class="point" onclick="GoTop(); sortTable(this,1);" title="Sort" align="right"><b>Amt</b> <img src="data:image/gif;base64,R0lGODlhCgAKALMLAHaRdnCTcHegd7C8sNTa1Ku4q9vg24GXgfr8+uDl4P///////wAAAAAAAAAAAAAAACH5BAEAAAsALAAAAAAKAAoAAAQfcMlJq12hIHKoSEqIdBIQnslknkoqfedIBQNikFduRQA7" border="0"></td>
<td class="point" onclick="GoTop(); sortTable(this,1);" title="Sort" align="right"><b>Lvl</b> <img src="data:image/gif;base64,R0lGODlhCgAKALMLAHaRdnCTcHegd7C8sNTa1Ku4q9vg24GXgfr8+uDl4P///////wAAAAAAAAAAAAAAACH5BAEAAAsALAAAAAAKAAoAAAQfcMlJq12hIHKoSEqIdBIQnslknkoqfedIBQNikFduRQA7" border="0"></td>
<td class="point" onclick="GoTop(); sortTable(this,1);" title="Sort" align="right"><b>Rank</b> <img src="data:image/gif;base64,R0lGODlhCgAKALMLAHaRdnCTcHegd7C8sNTa1Ku4q9vg24GXgfr8+uDl4P///////wAAAAAAAAAAAAAAACH5BAEAAAsALAAAAAAKAAoAAAQfcMlJq12hIHKoSEqIdBIQnslknkoqfedIBQNikFduRQA7" border="0"></td>
<td class="point" onclick="GoTop(); sortTable(this,1);" title="Sort" align="right"><b>Position</b> <img src="data:image/gif;base64,R0lGODlhCgAKALMLAHaRdnCTcHegd7C8sNTa1Ku4q9vg24GXgfr8+uDl4P///////wAAAAAAAAAAAAAAACH5BAEAAAsALAAAAAAKAAoAAAQfcMlJq12hIHKoSEqIdBIQnslknkoqfedIBQNikFduRQA7" border="0"></td>
<td class="point" onclick="GoTop(); sortTable(this,1);" title="Sort" align="right"><b>Date</b> <img src="data:image/gif;base64,R0lGODlhCgAKALMLAHaRdnCTcHegd7C8sNTa1Ku4q9vg24GXgfr8+uDl4P///////wAAAAAAAAAAAAAAACH5BAEAAAsALAAAAAAKAAoAAAQfcMlJq12hIHKoSEqIdBIQnslknkoqfedIBQNikFduRQA7" border="0"></td>
</tr>
</thead>
<tbody class="scrollContent bodyFormat" style="height:200px;">
<tr class="alternateRow">
<td>Maha</td>
<td align="right">$19,923.19</td>
<td align="right">100</td>
<td align="right">100</td>
<td>Owner</td>
<td align="right">01/02/2001</td>
</tr>
<tr>
<td>Thrawl</td>
<td align="right">$9,550</td>
<td align="right">159</td>
<td align="right">100%</td>
<td>Co-Owner</td>
<td align="right">11/07/2003</td>
</tr>
<tr class="alternateRow">
<td>Marhanen</td>
<td align="right">$223.04</td>
<td align="right">83</td>
<td align="right">99%</td>
<td>Banker</td>
<td align="right">06/27/2006</td>
</tr>
<tr>
<td>Peter</td>
<td align="right">$121</td>
<td align="right">567</td>
<td align="right">23423%</td>
<td>FishHead</td>
<td align="right">06/06/2006</td>
</tr>
<tr class="alternateRow">
<td>Jones</td>
<td align="right">$15</td>
<td align="right">11</td>
<td align="right">15%</td>
<td>Bubba</td>
<td align="right">10/27/2005</td>
</tr>
<tr>
<td>Supa-De-Dupa</td>
<td align="right">$145</td>
<td align="right">91</td>
<td align="right">32%</td>
<td>momma</td>
<td align="right">12/15/1996</td>
</tr>
<tr class="alternateRow">
<td>ClickClock</td>
<td align="right">$1,213</td>
<td align="right">23</td>
<td align="right">1%</td>
<td>Dada</td>
<td align="right">1/30/1998</td>
</tr>
<tr>
<td>Mrs. Robinson</td>
<td align="right">$99</td>
<td align="right">99</td>
<td align="right">99%</td>
<td>Wife</td>
<td align="right">07/04/1963</td>
</tr>
<tr class="alternateRow">
<td>Maha</td>
<td align="right">$19,923.19</td>
<td align="right">100</td>
<td align="right">100%</td>
<td>Owner</td>
<td align="right">01/02/2001</td>
</tr>
<tr>
<td>Thrawl</td>
<td align="right">$9,550</td>
<td align="right">159</td>
<td align="right">100%</td>
<td>Co-Owner</td>
<td align="right">11/07/2003</td>
</tr>
<tr class="alternateRow">
<td>Marhanen</td>
<td align="right">$223.04</td>
<td align="right">83</td>
<td align="right">59%</td>
<td>Banker</td>
<td align="right">06/27/2006</td>
</tr>
<tr>
<td>Peter</td>
<td align="right">$121</td>
<td align="right">567</td>
<td align="right">534.23%</td>
<td>FishHead</td>
<td align="right">06/06/2006</td>
</tr>
<tr class="alternateRow">
<td>Jones</td>
<td align="right">$15</td>
<td align="right">11</td>
<td align="right">15%</td>
<td>Bubba</td>
<td align="right">10/27/2005</td>
</tr>
<tr>
<td>Supa-De-Dupa</td>
<td align="right">$145</td>
<td align="right">91</td>
<td align="right">42%</td>
<td>momma</td>
<td align="right">12/15/1996</td>
</tr>
<tr class="alternateRow">
<td>ClickClock</td>
<td align="right">$1,213</td>
<td align="right">23</td>
<td align="right">2%</td>
<td>Dada</td>
<td align="right">1/30/1998</td>
</tr>
<tr>
<td>Mrs. Robinson</td>
<td align="right">$99</td>
<td align="right">99</td>
<td align="right">(-10.42%)</td>
<td>Wife</td>
<td align="right">07/04/1963</td>
</tr>
<tr class="alternateRow">
<td>Maha</td>
<td align="right">-$19,923.19</td>
<td align="right">100</td>
<td align="right">(-10.01%)</td>
<td>Owner</td>
<td align="right">01/02/2001</td>
</tr>
<tr>
<td>Thrawl</td>
<td align="right">$9,550</td>
<td align="right">159</td>
<td align="right">-10.20%</td>
<td>Co-Owner</td>
<td align="right">11/07/2003</td>
</tr>
<tr class="total">
<td><strong>TOTAL</strong>:</td>
<td align="right"><strong>999999</strong></td>
<td align="right"><strong>9999999</strong></td>
<td align="right"><strong>99</strong></td>
<td > </td>
<td align="right"> </td>
</tr>
</tbody>
</table>
</div>
</td></tr>
</table>
</body>
</html>
여기 제가 만든 순수 javascript/css만 있는 것이 있습니다.
https://jsfiddle.net/KirbyLWallace/x5sbe0dk/5/
이것은 전체 너비 화면에 사용하기 위한 것이지만, 저는 바이올린에 맞는 특정 너비에 맞게 수정했습니다.
<body onResize="scaleElements()">
<div id="table-container-div">
<table id="data-table">
<thead id="th-header">
<tr id="th-header-row">
<td>Column1</td>
<td>Column2</td>
<td>Column3</td>
<td>Column4</td>
</tr>
</thead>
<tbody id="tbl-body">
<tr><td>a</td><td>b</td><td>c</td><td>d</td></tr>
<tr><td>1</td><td>2</td><td>3</td><td>4</td></tr>
<tr><td>h</td><td>i</td><td>j</td><td>k</td></tr>
<tr><td>a</td><td>b</td><td>c</td><td>d</td></tr>
<tr><td>1</td><td>2</td><td>3</td><td>4</td></tr>
<tr><td>h</td><td>i</td><td>j</td><td>k</td></tr>
<tr><td>a</td><td>b</td><td>c</td><td>d</td></tr>
<tr><td>1</td><td>2</td><td>3</td><td>4</td></tr>
<tr><td>h</td><td>i</td><td>j</td><td>k</td></tr>
<tr><td>a</td><td>b</td><td>c</td><td>d</td></tr>
<tr><td>1</td><td>2</td><td>3</td><td>4</td></tr>
<tr><td>h</td><td>i</td><td>j</td><td>k</td></tr>
<tr><td>a</td><td>b</td><td>c</td><td>d</td></tr>
<tr><td>1</td><td>2</td><td>3</td><td>4</td></tr>
<tr><td>h</td><td>i</td><td>j</td><td>k</td></tr>
<tr><td>a</td><td>b</td><td>c</td><td>d</td></tr>
<tr><td>1</td><td>2</td><td>3</td><td>4</td></tr>
<tr><td>h</td><td>i</td><td>j</td><td>k</td></tr>
<tr><td>a</td><td>b</td><td>c</td><td>d</td></tr>
<tr><td>1</td><td>2</td><td>3</td><td>4</td></tr>
<tr><td>h</td><td>i</td><td>j</td><td>k</td></tr>
<tr><td>a</td><td>b</td><td>c</td><td>d</td></tr>
<tr><td>1</td><td>2</td><td>3</td><td>4</td></tr>
<tr><td>h</td><td>i</td><td>j</td><td>k</td></tr>
<tr><td>a</td><td>b</td><td>c</td><td>d</td></tr>
<tr><td>1</td><td>2</td><td>3</td><td>4</td></tr>
<tr><td>h</td><td>i</td><td>j</td><td>k</td></tr>
<tr><td>a</td><td>b</td><td>c</td><td>d</td></tr>
<tr><td>1</td><td>2</td><td>3</td><td>4</td></tr>
<tr><td>h</td><td>i</td><td>j</td><td>k</td></tr>
<tr><td>a</td><td>b</td><td>c</td><td>d</td></tr>
<tr><td>1</td><td>2</td><td>3</td><td>4</td></tr>
<tr><td>h</td><td>i</td><td>j</td><td>k</td></tr>
<tr><td>a</td><td>b</td><td>c</td><td>d</td></tr>
<tr><td>1</td><td>2</td><td>3</td><td>4</td></tr>
<tr><td>h</td><td>i</td><td>j</td><td>k</td></tr>
<tr><td>a</td><td>b</td><td>c</td><td>d</td></tr>
<tr><td>1</td><td>2</td><td>3</td><td>4</td></tr>
<tr><td>h</td><td>i</td><td>j</td><td>k</td></tr>
<tr><td>a</td><td>b</td><td>c</td><td>d</td></tr>
<tr><td>1</td><td>2</td><td>3</td><td>4</td></tr>
<tr><td>h</td><td>i</td><td>j</td><td>k</td></tr>
</tbody>
</table>
Javascript:
(() => {
scaleElements();
})();
function scaleElements() {
// element() is just shorthand for document.getElementById().
// scaleElements() scales a number of other things, not included here,
// that get rescaled any time the browser, or a container is resized.
// the table header row here is just one of them...
//
// this thing includes checks to see if a table with the table & thead
// is on the page. If it is, it checks to see if the span container is
// here (it's not on the first run, but it is on subsequent calls. So,
// it adds it if it needs it, or reuses it if it's there.
if (element("data-table")) {
if (element("th-span-container")) {
element("th-span-container").parentElement.removeChild(element("th-span-container"));
}
var x = document.createElement("div");
x.id = "th-span-container";
x.style.cssFloat = "left";
x.style.position = "fixed";
x.style.top = "10px";
// you will want to fiddle with your own particular positioning.
// this one is positioned to work on a table that is below a page
// logo banner.
var tds = element("th-header-row").getElementsByTagName("td");
for (i = 0; i < tds.length; i++) {
let z = tds[i];
let y = document.createElement("span");
y.style.padding = "0px";
y.style.margin = "0px";
y.style.fontFamily = "'Segoe UI', Tahoma, Geneva, Verdana, sans-serif";
y.style.fontSize = "13px";
y.style.border = "0px";
y.style.position = "absolute";
y.style.color = "white";
y.style.backgroundColor = "#3D6588";
y.style.left = z.offsetLeft + "px";
y.style.height = z.offsetHeight + "px";
y.style.lineHeight = z.offsetHeight + "px";
y.style.width = z.offsetWidth + "px";
y.innerHTML = z.innerHTML;
x.appendChild(y);
}
element("table-container-div").appendChild(x);
element("th-header-row").style.visibility = "hidden";
}
}
function element(e) {
return document.getElementById(e);
}
CSS:
body {
background: black;
}
#table-container-div {
width: 310px;
position: absolute;
top: 10px;
bottom: 10px;
overflow-x: hidden;
overflow-y: auto;
min-width: 320px;
}
table {
font-size: 13px;
height: 120px;
width: 300px;
border: 0px solid red;
background-color: #11171F;
}
tr {
height: 22px;
color: #cff3ff;
}
tr:hover {
background-color: dimgrey;
}
td {
color:white;
border-right: 1px dotted #4F4F4F;
}
#th-header-row {
background-color: #3D6588;
color: white;
}
자바스크립트 없이도 실제로 할 수 있지만, 스틱 포지션이 있는 순수 CSS + HTML을 사용합니다.고정할 셀에 "위치 고정"을 추가하면 됩니다.
테이블을 만들 때는 테이블 태그 또는 CSS 그리드를 사용할 수 있으며, 이 기술은 두 가지 모두에 적용됩니다.
다음은 테이블 태그(라이브 데모)를 사용한 포맷의 예입니다.
<table>
<tr><th class="head"></th class="head"><th></th> ... </tr>
<tr><th class="head"></th> <th></th> ... </tr>
...
</table>
<style type="text/css">
.head { position: sticky; top: 0; left: 0;}
</style>
다음은 CSS 그리드(라이브 데모)의 예입니다.
<div class="grid">
<!-- cells to freeze -->
<div class="entry head"></div>
<div class="entry head"></div>
...
<!-- normal cells -->
<div class="entry"></div>
...
</div>
<style type="text/css">
.grid {
display: grid;
grid-template-columns: repeat(<your-cell-count>, <cell-size>);
}
.entry.head { position: sticky; top: 0; left: 0 }
</style>
아마도 수평 및 수직으로 동결된 셀을 관리해야 할 것입니다(예: 다른 것보다 더 큰 z 인덱스 설정). 하지만 여전히 CSS일 것입니다.
이 접근 방식의 주요 단점은 아마도 브라우저 호환성 문제일 것입니다.이러한 기술을 사용하기 전에 Can I Use CSS-sticky 및 CSS 그리드를 선택합니다.
몇 주 전에 사이트를 검색해 봤습니다.이것은 첫 번째 열이 잠겨 있지만 Firefox와 브라우저 호환되지 않는 작동 예입니다.주변을 많이 확인하지는 않았지만 IE에서만 작동하는 것 같습니다.작성자가 제공한 노트와 함께 읽을 수 있는 노트가 있습니다.
첫 번째 열 잠금: http://home.tampabay.rr.com/bmerkey/examples/locked-column-csv.html
Table 헤더도 잠글 수 있는 Javascript가 필요하시면 알려주세요.
자바스크립트 없이도 할 수 있습니다.
다음 링크를 참조하십시오. http://yonax73.blogspot.com/2014/09/tabla-con-cabecera-estatica-cuerpo-con.html
또는 라이브 데모: http://jsfiddle.net/yonatanalexis22/aeeme8mt/7/
table{
border-spacing: 0;
display: flex;/*Se ajuste dinamicamente al tamano del dispositivo**/
max-height: 40vh; /*El alto que necesitemos**/
overflow-y: auto; /**El scroll verticalmente cuando sea necesario*/
overflow-x: hidden;/*Sin scroll horizontal*/
table-layout: fixed;/**Forzamos a que las filas tenga el mismo ancho**/
width: 98vw; /*El ancho que necesitemos*/
border:1px solid gray;}
언급URL : https://stackoverflow.com/questions/296020/how-can-i-lock-the-first-row-and-first-column-of-a-table-when-scrolling-possibl
'source' 카테고리의 다른 글
은색 빛에서 자식 요소의 너비를 부모 요소의 너비에 바인딩하는 방법 (0) | 2023.05.17 |
---|---|
Angular 2: 'input'의 알려진 속성이 아니므로 'ngModel'에 바인딩할 수 없습니다. (0) | 2023.05.17 |
VB.NET - IIF(, , ) - "측면"이 모두 평가됩니다.어떤 상황을 주의해야 합니까? (0) | 2023.05.17 |
리누스 토르발스가 Git이 "절대로" 파일을 추적하지 않는다고 말하는 것은 무엇을 의미합니까? (0) | 2023.05.17 |
셸 스크립트가 호출 셸의 환경 변수를 설정할 수 있습니까? (0) | 2023.05.17 |