Home >Web Front-end >JS Tutorial >HTML CSS JS realizes TABLE fixed columns that are perfectly compatible with major browsers_javascript skills

HTML CSS JS realizes TABLE fixed columns that are perfectly compatible with major browsers_javascript skills

WBOY
WBOYOriginal
2016-05-16 16:02:111188browse

In enterprise-level applications with BS architecture, when a table has a large number of columns, a common user need is to fix the first few important columns. In this way, the fixed columns will facilitate users to view data when dragging the scroll bar. The user experience is great. Some heavyweight JS component libraries also have this function, so is there an easier way to achieve this function?

A common solution to this requirement is to use the table splicing method. If you want to create a static web page or a dynamic page with simple functions, the logic is relatively simple and the technology is not complicated. It is easy to implement, but if you want to do If there are many dynamic functions, you need to write a lot of redundant code, which is difficult to maintain. Even a simple function requires writing a lot of code, such as event processing. This method is clumsy and very flexible. Poor, not a good solution.

After a long period of analysis and research, and experiments in various scenarios, we have found a solution with very good compatibility. Generally speaking, it uses the positioning calculation method. I will post the code below and give an explanation.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>无标题文档</title>
<script type="text/javascript">
function divScroll(scrollDiv){
  var scrollLeft = scrollDiv.scrollLeft;
  document.getElementById("tableDiv_title").scrollLeft = scrollLeft;
  document.getElementById("tableDiv_body").scrollLeft = scrollLeft;    
}
function divYScroll(scrollYDiv){
  var scrollTop = scrollYDiv.scrollTop;
  document.getElementById("tableDiv_y").scrollTop = scrollTop;  
}
function onwheel(event){
  var evt = event||window.event;
  var bodyDivY = document.getElementById("tableDiv_y");
  var scrollDivY = document.getElementById("scrollDiv_y");
  if (bodyDivY.scrollHeight>bodyDivY.offsetHeight){
    if (evt.deltaY){
      bodyDivY.scrollTop = bodyDivY.scrollTop + evt.deltaY*7;
      scrollDivY.scrollTop = scrollDivY.scrollTop + evt.deltaY*7;
    }else{
      bodyDivY.scrollTop = bodyDivY.scrollTop - evt.wheelDelta/5;
      scrollDivY.scrollTop = scrollDivY.scrollTop - evt.wheelDelta/5;
    }
  }
}
</script>
<style type="text/css">
body {
margin:0;
padding:0;
}
table {
border-collapse:collapse;
border:0;
border:none;
}
 
table td {
border:1px solid #000;
overflow:hidden;
padding:0 2px;
}
</style>
</head>
<body>
<div style="width:500px; position:relative; padding-right:18px;">
  <div style="position:relative;height:368px;overflow:hidden;width:100%">
  <div style="padding-left:108px; width:auto; overflow:hidden; background:#f00;" id="tableDiv_title" >
  <table border="0" cellspacing="0" cellpadding="0" >
   <tr>
    <td style="min-width:30px; max-width:30px; left:0; top:0; width:30px; overflow:hidden; background-color:#f00;position:absolute;z-index:1;">000</td>
    <td style="min-width:74px; max-width:74px; left:30px; top:0; width:74px; overflow:hidden; background-color:#f00;position:absolute;z-index:1;">自动表格</td>
    <td style="min-width: 100px; max-width: 100px; width: 100px;" >56454自动</td>
    <td style="min-width: 100px; max-width: 100px; width: 100px;" >56454自动</td>
    <td style="min-width: 100px; max-width: 100px; width: 100px;" >56454自动</td>
    <td style="min-width: 100px; max-width: 100px; width: 100px;" >56454自动</td>
    <td style="min-width: 100px; max-width: 100px; width: 100px;" >56454自动</td>
    <td style="min-width: 100px; max-width: 100px; width: 100px;" >最后一列</td>
   </tr>
   </table>
   </div> 
  <div style="overflow:hidden; position:absolute;height:128px; width:100%;" id="tableDiv_y" onmousewheel="onwheel(event);" onwheel="onwheel(event);">
    <div style="padding-left:108px; width:auto;overflow:hidden;" id="tableDiv_body">
    <table border="0" cellspacing="0" cellpadding="0" >
     <tr>
      <td style="min-width:30px; max-width:30px; left:0; width:30px; overflow:hidden; background-color:#fff;position:absolute;z-index:1;">001</td>
      <td style="min-width:74px; max-width:74px; left: 30px; width: 74px; overflow:hidden; background-color:#fff;position:absolute;z-index:1;">自动表格</td>
      <td style="min-width: 100px; max-width: 100px; width: 100px;" >56454自动</td>
      <td style="min-width: 100px; max-width: 100px; width: 100px;" >56454自动</td>
      <td style="min-width: 100px; max-width: 100px; width: 100px;" >56454自动</td>
      <td style="min-width: 100px; max-width: 100px; width: 100px;" >56454自动</td>
      <td style="min-width: 100px; max-width: 100px; width: 100px;" >56454自动</td>
      <td style="min-width: 100px; max-width: 100px; width: 100px;" >最后一列</td>
     </tr>
      <tr>
      <td style="min-width:30px; max-width:30px; left:0; width:30px; overflow:hidden; background-color:#fff; position:absolute; z-index:1;">002</td>
      <td style="min-width:74px; max-width:74px; left:30px; width:74px; overflow:hidden;background-color:#fff; position:absolute; z-index:1;">自动表格</td>
      <td style="min-width: 100px; max-width: 100px; width: 100px;" >56454自动</td>
      <td style="min-width: 100px; max-width: 100px; width: 100px;" >56454自动</td>
      <td style="min-width: 100px; max-width: 100px; width: 100px;" >56454自动</td>
      <td style="min-width: 100px; max-width: 100px; width: 100px;" >56454自动</td>
      <td style="min-width: 100px; max-width: 100px; width: 100px;" >56454自动</td>
      <td style="min-width: 100px; max-width: 100px; width: 100px;" >最后一列</td>
     </tr>
     <tr>
      <td style="min-width:30px; max-width:30px; left:0; width:30px; overflow:hidden; background-color:#fff;position:absolute;z-index:1;">003</td>
      <td style="min-width:74px; max-width:74px;left: 30px; width: 74px; overflow:hidden;background-color:#fff;position:absolute;z-index:1;">自动表格</td>
      <td style="min-width: 100px; max-width: 100px; width: 100px;" >56454自动</td>
      <td style="min-width: 100px; max-width: 100px; width: 100px;" >56454自动</td>
      <td style="min-width: 100px; max-width: 100px; width: 100px;" >56454自动</td>
      <td style="min-width: 100px; max-width: 100px; width: 100px;" >56454自动</td>
      <td style="min-width: 100px; max-width: 100px; width: 100px;" >56454自动</td>
      <td style="min-width: 100px; max-width: 100px; width: 100px;" >最后一列</td>
     </tr>
     <tr>
      <td style="min-width:30px; max-width:30px; left:0; width:30px; overflow:hidden; background-color:#fff;position:absolute;z-index:1;">004</td>
      <td style="min-width:74px; max-width:74px; left: 30px; width: 74px; overflow:hidden;background-color:#fff;position:absolute;z-index:1;">自动表格</td>
      <td style="min-width: 100px; max-width: 100px; width: 100px;" >56454自动</td>
      <td style="min-width: 100px; max-width: 100px; width: 100px;" >56454自动</td>
      <td style="min-width: 100px; max-width: 100px; width: 100px;" >56454自动</td>
      <td style="min-width: 100px; max-width: 100px; width: 100px;" >56454自动</td>
      <td style="min-width: 100px; max-width: 100px; width: 100px;" >56454自动</td>
      <td style="min-width: 100px; max-width: 100px; width: 100px;" >最后一列</td>
     </tr>
      <tr>
      <td style="min-width:30px; max-width:30px; left:0; width:30px; overflow:hidden; background-color:#fff;position:absolute;z-index:1;">005</td>
      <td style="min-width:74px; max-width:74px; left: 30px; width: 74px; overflow:hidden;background-color:#fff;position:absolute;z-index:1;">自动表格</td>
      <td style="min-width: 100px; max-width: 100px; width: 100px;" >56454自动</td>
      <td style="min-width: 100px; max-width: 100px; width: 100px;" >56454自动</td>
      <td style="min-width: 100px; max-width: 100px; width: 100px;" >56454自动</td>
      <td style="min-width: 100px; max-width: 100px; width: 100px;" >56454自动</td>
      <td style="min-width: 100px; max-width: 100px; width: 100px;" >56454自动</td>
      <td style="min-width: 100px; max-width: 100px; width: 100px;" >最后一列</td>
     </tr>
      <tr>
      <td style="min-width:30px; max-width:30px; left:0; width:30px; overflow:hidden; background-color:#fff;position:absolute;z-index:1;">006</td>
      <td style="min-width:74px; max-width:74px; left: 30px; width: 74px; overflow:hidden;background-color:#fff;position:absolute;z-index:1;">自动表格</td>
      <td style="min-width: 100px; max-width: 100px; width: 100px;" >56454自动</td>
      <td style="min-width: 100px; max-width: 100px; width: 100px;" >56454自动</td>
      <td style="min-width: 100px; max-width: 100px; width: 100px;" >56454自动</td>
      <td style="min-width: 100px; max-width: 100px; width: 100px;" >56454自动</td>
      <td style="min-width: 100px; max-width: 100px; width: 100px;" >56454自动</td>
      <td style="min-width: 100px; max-width: 100px; width: 100px;" >最后一列</td>
     </tr>   
     <tr>
      <td style="min-width:30px; max-width:30px; left:0; width:30px; overflow:hidden; background-color:#fff;position:absolute;z-index:1;">007</td>
      <td style="min-width:74px; max-width:74px; left: 30px; width: 74px; overflow:hidden;background-color:#fff;position:absolute;z-index:1;">自动表格</td>
      <td style="min-width: 100px; max-width: 100px; width: 100px;" >56454自动</td>
      <td style="min-width: 100px; max-width: 100px; width: 100px;" >56454自动</td>
      <td style="min-width: 100px; max-width: 100px; width: 100px;" >56454自动</td>
      <td style="min-width: 100px; max-width: 100px; width: 100px;" >56454自动</td>
      <td style="min-width: 100px; max-width: 100px; width: 100px;" >56454自动</td>
      <td style="min-width: 100px; max-width: 100px; width: 100px;" >最后一列</td>
     </tr>
      <tr>
      <td style="min-width:30px; max-width:30px; left:0; width:30px; overflow:hidden; background-color:#fff;position:absolute;z-index:1;">008</td>
      <td style="min-width:74px; max-width:74px; left: 30px; width: 74px; overflow:hidden;background-color:#fff;position:absolute;z-index:1;">自动表格</td>
      <td style="min-width: 100px; max-width: 100px; width: 100px;" >56454自动</td>
      <td style="min-width: 100px; max-width: 100px; width: 100px;" >56454自动</td>
      <td style="min-width: 100px; max-width: 100px; width: 100px;" >56454自动</td>
      <td style="min-width: 100px; max-width: 100px; width: 100px;" >56454自动</td>
      <td style="min-width: 100px; max-width: 100px; width: 100px;" >56454自动</td>
      <td style="min-width: 100px; max-width: 100px; width: 100px;" >最后一列</td>
     </tr>
      <tr>
      <td style="min-width:30px; max-width:30px; left:0; width:30px; overflow:hidden; background-color:#fff;position:absolute;z-index:1;">009</td>
      <td style="min-width:74px; max-width:74px; left: 30px; width: 74px; overflow:hidden;background-color:#fff;position:absolute;z-index:1;">自动表格</td>
      <td style="min-width: 100px; max-width: 100px; width: 100px;" >56454自动</td>
      <td style="min-width: 100px; max-width: 100px; width: 100px;" >56454自动</td>
      <td style="min-width: 100px; max-width: 100px; width: 100px;" >56454自动</td>
      <td style="min-width: 100px; max-width: 100px; width: 100px;" >56454自动</td>
      <td style="min-width: 100px; max-width: 100px; width: 100px;" >56454自动</td>
      <td style="min-width: 100px; max-width: 100px; width: 100px;" >最后一列</td>
     </tr>
      <tr>
      <td style="min-width:30px; max-width:30px; left:0; width:30px; overflow:hidden; background-color:#fff;position:absolute;z-index:1;">010</td>
      <td style="min-width:74px; max-width:74px; left: 30px; width: 74px; overflow:hidden;background-color:#fff;position:absolute;z-index:1;">自动表格</td>
      <td style="min-width: 100px; max-width: 100px; width: 100px;" >56454自动</td>
      <td style="min-width: 100px; max-width: 100px; width: 100px;" >56454自动</td>
      <td style="min-width: 100px; max-width: 100px; width: 100px;" >56454自动</td>
      <td style="min-width: 100px; max-width: 100px; width: 100px;" >56454自动</td>
      <td style="min-width: 100px; max-width: 100px; width: 100px;" >56454自动</td>
      <td style="min-width: 100px; max-width: 100px; width: 100px;" >最后一列</td>
     </tr>      
    </table>
  </div>     
  </div> 
   <div style="background-color:#eee;overflow:hidden;top:150px; width:100%; z-index:2;position:absolute;">
    <div style="margin-left:108px; width:auto;overflow-x:scroll;overflow-y:hidden;" onscroll='divScroll(this);'>
      <div style="width:630px; height:1px;"></div>
    </div>
  </div>
  </div>
    <div id="scrollDiv_y" style="display:block; overflow-x:hidden; overflow-y:scroll; position:absolute; top:22px; right:0px; height:118px; padding-bottom:10px;" onscroll='divYScroll(this);'>
      <div style="width:1px; height:194px;"></div>
     </div>
  </div>
  </div>
</body>
</html>


1. Overall structure:

The basic element of the page is DIV TABLE. The fixed columns are fixed by absolute positioning. Each column must specify a fixed width. In order to solve the problem of horizontal and vertical scroll bars, the header and body of the table are wrapped with two layers of DIV respectively. The bar adopts a virtual method and is fixed at a fixed position through JS control to simulate the effect of a normal DIV scroll bar.

2. Positioning:

Fixed columns should be positioned absolutely, and the left displacement is controlled through the left attribute. In order to ensure that the fixed columns float above, set z-index to 1. In order to ensure normal display when there is a vertical scroll bar, the outer DIV of the table body is absolutely positioned, so the scroll bars must also be absolutely positioned. In addition, the inner DIV of the table header, table body and scroll bar uses the margin-left attribute to control the left margin, leaving the offset of the fixed column free.

2. Width calculation:

The width of each column must be specified with a fixed value, and a key point must be noted, that is, the min-width and max-width attributes must be added. These two attributes are equal to the width value. The content of the header and body Layer DIV, width is auto, adaptive table width, outer DIV width is 100%, the outermost DIV controls the right inner margin through the padding-right attribute, leaving the position of the vertical scroll bar free.

3. Height calculation:

Because of the existence of absolute positioning, the height of the entire table component must be specified, which can be calculated. The top value of the vertical scroll bar also needs to be calculated.

4. Scroll bar:

A prominent feature of this solution is the virtual scroll bar, which simulates the horizontal scroll bar of the table body DIV through a DIV with the same width as the table and a height of one pixel. The same is true for the vertical scroll bar. The reason why this form is adopted is that the horizontal scroll bar is more beautiful when treated like this. After the vertical scroll bar is treated like this, the outer DIV width of the table header and table body does not need to be calculated, both are 100%. Otherwise, when there is a scroll bar, the table header The displacement of the width of the vertical scroll bar must be freed from the horizontal scroll bar, otherwise it cannot be aligned. This calculation is not complicated, but there are problems in some cases, which will not be expanded here.

5. Scroll event:

Because the scroll bars on the table body are hidden, the mouse wheel does not work, so you need to use JS to handle the mouse wheel event. The sample code in this article is compatible with common browsers. The key point here is that onmousewheel and onwheel events are written at the same time. onmousewheel is compatible with IE. When calculating the scrolling distance, just pay attention to the difference between deltaY and wheelDelta attributes.

6. Analysis of advantages and disadvantages:

The solution in this article has been streamlined. The focus is to explain the principles clearly. In our reality, it is very complicated. This design takes into account a lot of compatibility, including browser compatibility and compatibility in various scenarios. If the requirements are simple, there is room for simplification.

The advantage of this solution is that if you want to make a component, because the HTML structure is simple, the table header and table body are both a TABLE, the JS control code is very clean and easy to maintain. The disadvantage is that it requires too much calculation. We think this solution is more suitable for developing components, and static pages are a bit fussy.

The above is the entire content of this article, I hope you all like it.

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn