摘要:在使用表格顯示資料時我們經常會遇到資料過多無法一屏完全顯示的問題,這個時候我們就會給使用者顯示滾動條來拖動。但是多數情況下表格是帶有表頭的,縱向拖動往往就看不到表頭;而橫向拖動又會出現看不到主題列(例如統計某人基本資訊時姓名就是主題列),這個時候怎麼辦呢?答案就是行列鎖定。
主要内容:
1.行列鎖定的常用方法
2.ie下實作行列鎖定
3.使用jquery開發一個簡單的行列鎖定插件
從使用上來看,要實作行列鎖定的效果無非就是使用第三方元件和自己從零做起一步步實作。第三方元件一般比較強大,除了行列鎖定的功能之外一般還包括排序、篩選等(例如ext的locking-grid擴充元件),但是使用第三方元件也會造成一些其他的問題,或者說有些時候你根本就沒有辦法使用第三方元件(我遇到的就是這種情況)。今天我們主要讨論的是如何利用基本的html來自己實作行列鎖定。自己實作table鎖定行列的方法基本上有兩種:一種是利用多個table拼接,最終"拼"成一個大的table。這種情況一般将表頭和主題列分别放到單獨的table中,資料行放到另一個table,拖動資料所在的table時利用js動态實作其他table的同步拖動。第二種就是利用單獨的table,通過設定table行和列相對位置來實作行列鎖定。兩種方式相比較而言,第一種的方式更加容易控制一些,而且由于它将一個大表格分散到多個table中更有利于完成其他複雜功能;第二種實作比第一種效果要好一些,而且更有利于封裝和擴充。由于我所遇到的情況是必須在原有html基礎上實作行列鎖定,是以這裡就主要說一下第二種方式。
由于我們下面說的方法主要利用tr、td的position:relative樣式,而在新的css标準中沒有對tr進行position:relative定義,是以除了ie在firefox4、chrome等新版本浏覽器中都無法使用我們下面所說的方法(事實上ie9也是使用新标準,隻不過其對相容性做了處理,是以我們這種方法基本在ie所有版本中都是可行的)。我們的實作原理很簡單:首先在table最外層包裝一個div用來顯示滾動條,接着設定tr和td的position和z-index樣式控制其相對顯示,然後在滾動的時候動态修改tr和td的top和left屬性使其相對位置保持不表。下面我們來看一下具體的實作:
<a href="http://www.cnblogs.com/kenshincui/archive/2011/03/30/1999625.html#">+ view code</a>
如果僅僅從實作上來說,到了第二部我們今天的内容就結束了。但是聰明的讀者或許已經發現上面的用法存在的問題:第一我們需要手動的添加很多的class樣式、需要對原有布局修改;第二我們上面使用了expression這個ie所特有的樣式(雖然我們上面說過這個差距不适用于其他浏覽器新版本,但是不代表不适用于舊版本,如果我們修改expression為純js方式也就可以使用于其他低版本浏覽器)。我們剛才說過第二種方式有一個優點就是便于封裝而且幾乎不必對原table布局作出修改,是以我們不妨對整個應用進行一下簡單的封裝,使其隻需要簡單的添加一行js就能夠完美的運作。雖然在這個過程中我們隻是将手動添加class樣式換成動态添加、将expression表達換成onscroll事件,但是一切看起來确實那麼的不一樣。
下面就是我們使用jquery進行封裝的代碼tablelock.js:
<code>/*</code>
<code>author:kenshincui</code>
<code>date:2011.03.29</code>
<code>example:$.fn.tablelock({table:'locktable',lockrow:1,lockcolumn:2,width:'100%',height:'300px'});</code>
<code>*/</code>
<code>(</code><code>function</code><code>($) {</code>
<code> </code><code>$.extend($.fn, {</code>
<code> </code><code>tablelock:</code><code>function</code><code>(options) {</code>
<code> </code><code>var</code> <code>tl = $.extend({</code>
<code> </code><code>table:</code><code>'locktable'</code><code>,</code><code>//table的id</code>
<code> </code><code>lockrow:1,</code><code>//固定行數</code>
<code> </code><code>lockcolumn:1,</code><code>//固定列數</code>
<code> </code><code>width:</code><code>'100%'</code><code>,</code><code>//表格顯示寬度(實質是外出div寬度)</code>
<code> </code><code>height:</code><code>'100%'</code><code>,</code><code>//表格顯示高度(實質是外出div高度)</code>
<code> </code><code>lockrowcss:</code><code>'lockrowbg'</code><code>,</code><code>//鎖定行的樣式</code>
<code> </code><code>lockcolumncss:</code><code>'lockcolumnbg'</code><code>//鎖定列的樣式</code>
<code> </code><code>}, options);</code>
<code> </code>
<code> </code><code>var</code> <code>tableid=tl.table;</code>
<code> </code><code>var</code> <code>table=$(</code><code>'#'</code><code>+tableid);</code>
<code> </code><code>var</code> <code>rowspan=</code><code>function</code><code>(tr){</code>
<code> </code>
<code> </code><code>}</code>
<code> </code><code>if</code><code>(table){</code>
<code> </code><code>var</code> <code>box=$(</code><code>"<div id:='divboxing' class='divboxing'></div>"</code><code>).scroll(</code><code>function</code><code>(){</code><code>//在此處添加事件</code>
<code> </code><code>$(</code><code>'.lockrow'</code><code>).css(</code><code>'top'</code><code>,$(</code><code>this</code><code>).attr(</code><code>'scrolltop'</code><code>)+</code><code>'px'</code><code>);</code>
<code> </code><code>$(</code><code>'.lockcell'</code><code>).css(</code><code>'left'</code><code>,$(</code><code>this</code><code>).attr(</code><code>'scrollleft'</code><code>)+</code><code>'px'</code><code>);</code>
<code> </code><code>});</code>
<code> </code><code>box.css(</code><code>'width'</code><code>,tl.width).css(</code><code>'height'</code><code>,tl.height);</code><code>//設定高度和寬度</code>
<code> </code><code>table.wrap(box);</code>
<code> </code><code>table.addclass(</code><code>'tblock'</code><code>);</code>
<code> </code><code>var</code> <code>crossnum=tl.lockrow*tl.lockcolumn;</code>
<code> </code><code>if</code><code>(tl.lockrow>0){</code>
<code> </code><code>var</code> <code>tr;</code>
<code> </code><code>for</code><code>(</code><code>var</code> <code>r=0;r<tl.lockrow;++r){</code><code>//添加行鎖定</code>
<code> </code><code>tr=table.find(</code><code>'tr:eq('</code><code>+r+</code><code>')'</code><code>).addclass(</code><code>'lockrow'</code><code>).addclass(tl.lockrowcss);</code>
<code> </code><code>for</code><code>(</code><code>var</code> <code>c=0;c<tl.lockcolumn;++c){</code><code>//設定交叉單元格樣式,除了鎖定單元格外還有交叉單元格自身樣式</code>
<code> </code><code>if</code><code>(tr)</code>
<code> </code><code>tr.find(</code><code>'td:eq('</code><code>+c+</code><code>')'</code><code>).addclass(</code><code>'lockcell lockcross'</code><code>).addclass(tl.lockrowcss);</code>
<code> </code><code>}</code>
<code> </code><code>}</code>
<code> </code><code>}</code>
<code> </code><code>if</code><code>(tl.lockcolumn>0){</code>
<code> </code><code>var</code> <code>rownum=$(</code><code>'#'</code><code>+tableid+</code><code>' tr'</code><code>).length;</code>
<code> </code><code>for</code><code>(</code><code>var</code> <code>r=(tl.lockrow);r<rownum;++r){</code>
<code> </code><code>tr=table.find(</code><code>'tr:eq('</code><code>+r+</code><code>')'</code><code>);</code>
<code> </code><code>for</code><code>(</code><code>var</code> <code>c=0;c<tl.lockcolumn;++c){</code><code>//添加列鎖定</code>
<code> </code><code>tr.find(</code><code>'td:eq('</code><code>+c+</code><code>')'</code><code>).addclass(</code><code>'lockcell'</code><code>).addclass(tl.lockcolumncss);</code>
<code> </code><code>} </code>
<code> </code><code>//box.live('scroll',func);</code>
<code> </code><code>}</code><code>else</code><code>{</code>
<code> </code><code>alert(</code><code>'沒有找到對應的table元素,請確定table屬性正确性!'</code><code>);</code>
<code> </code><code>}</code>
<code> </code><code>});</code>
<code>})(jquery);</code>
具體的樣式表檔案tablelock.css:
<code>.lockrow</code><code>/*固定行的樣式*/</code>
<code>{</code>
<code> </code><code>position</code><code>:</code><code>relative</code><code>;</code>
<code> </code><code>/*top: expression(this.parentelement.parentelement.parentelement.scrolltop);*/</code>
<code> </code><code>top</code><code>:</code><code>0px</code><code>;</code>
<code> </code><code>z-index</code><code>:</code><code>2</code><code>;</code>
<code>}</code>
<code>.lockcell</code><code>/*固定列的樣式*/</code>
<code> </code><code>/*left: expression(this.parentelement.parentelement.parentelement.parentelement.scrollleft);*/</code>
<code> </code><code>left</code><code>:</code><code>0px</code><code>;</code>
<code> </code><code>z-index</code><code>:</code><code>0</code><code>;</code>
<code>.lockcross</code><code>/*行列交叉處樣式*/</code>
<code> </code><code>z-index</code><code>:</code><code>3</code><code>;</code>
<code>.divboxing</code><code>/*外出div樣式*/</code>
<code> </code><code>clear</code><code>:</code><code>both</code><code>;</code>
<code> </code><code>overflow</code><code>:</code><code>scroll</code><code>;</code>
<code>.tblock</code><code>/*設定單元格間隙的樣式*/</code>
<code> </code><code>border-collapse</code><code>:</code><code>collapse</code><code>;</code>
<code>.lockrowbg</code>
<code> </code><code>background-color</code><code>:</code><code>#cff</code><code>;</code>
<code>.lockcolumnbg</code>
假設現在你有有這樣一個頁面,當然它不具備鎖定行列的功能:
如果你需要讓它擁有鎖定行列的功能,隻需要引入tablelock.js和tablelock.css(當然不要忘了jquery類庫),然後添加一句簡單的代碼即可:
<code><mce:script type=</code><code>"text/javascript"</code> <code>language=</code><code>"javascript"</code><code>><!--</code>
<code> </code><code>$(</code><code>function</code><code>(){</code>
<code> </code><code>$.fn.tablelock({table:</code><code>'locktable'</code><code>,lockrow:1,lockcolumn:2,width:</code><code>'100%'</code><code>,height:</code><code>'300px'</code><code>});</code>
<code>// --></mce:script></code>
下面是完整的頁面代碼:
<code><</code><code>head</code><code>></code>
<code><</code><code>meta</code> <code>http-equiv="content-type" content="text/html; charset=utf-8" /></code>
<code><</code><code>title</code><code>>tablelock插件示範</</code><code>title</code><code>></code>
<code><</code><code>link</code> <code>rel="stylesheet" href="tablelock.css" mce_href="tablelock.css" /></code>
<code><</code><code>mce:script</code> <code>type="text/javascript" language="javascript" src="jquery-1.5.1.js" mce_src="jquery-1.5.1.js"></</code><code>mce:script</code><code>></code>
<code><</code><code>mce:script</code> <code>type="text/javascript" language="javascript" src="tablelock.js" mce_src="tablelock.js"></</code><code>mce:script</code><code>></code>
<code><</code><code>mce:script</code> <code>type="text/javascript" language="javascript"></code><code><!--</code>
<code> </code><code>$(function(){</code>
<code> </code><code>$.fn.tablelock({table:'locktable',lockrow:1,lockcolumn:2,width:'100%',height:'300px'});</code>
<code>// --></code><code></</code><code>mce:script</code><code>></code>
<code></</code><code>head</code><code>></code>
<code><</code><code>body</code><code>></code>
<code><</code><code>table</code> <code>id="locktable" width="800" border="0"></code>
<code> </code><code><</code><code>tr</code><code>></code>
<code> </code><code><</code><code>td</code> <code>width="100" align="center">第一列</</code><code>td</code><code>></code>
<code> </code><code><</code><code>td</code> <code>width="100" align="center">第二列</</code><code>td</code><code>></code>
<code> </code><code><</code><code>td</code> <code>width="100" align="center">第三列</</code><code>td</code><code>></code>
<code> </code><code><</code><code>td</code> <code>width="100" align="center">第四列</</code><code>td</code><code>></code>
<code> </code><code><</code><code>td</code> <code>width="100" align="center">第五列</</code><code>td</code><code>></code>
<code> </code><code><</code><code>td</code> <code>width="100" align="center">第六列</</code><code>td</code><code>></code>
<code> </code><code><</code><code>td</code> <code>width="100" align="center">第七列</</code><code>td</code><code>></code>
<code> </code><code><</code><code>td</code> <code>width="100" align="center">第八列</</code><code>td</code><code>></code>
<code> </code><code></</code><code>tr</code><code>></code>
<code> </code><code><</code><code>td</code> <code>align="center">1-2</</code><code>td</code><code>></code>
<code> </code><code><</code><code>td</code> <code>align="center">2-2</</code><code>td</code><code>></code>
<code> </code><code><</code><code>td</code> <code>align="center">--</</code><code>td</code><code>></code>
<code> </code><code><</code><code>td</code> <code>align="center">1-3</</code><code>td</code><code>></code>
<code> </code><code><</code><code>td</code> <code>align="center">2-3</</code><code>td</code><code>></code>
<code> </code><code><</code><code>td</code> <code>align="center">1-4</</code><code>td</code><code>></code>
<code> </code><code><</code><code>td</code> <code>align="center">2-4</</code><code>td</code><code>></code>
<code> </code><code><</code><code>td</code> <code>align="center">1-5</</code><code>td</code><code>></code>
<code> </code><code><</code><code>td</code> <code>align="center">2-5</</code><code>td</code><code>></code>
<code> </code><code><</code><code>td</code> <code>align="center">1-6</</code><code>td</code><code>></code>
<code> </code><code><</code><code>td</code> <code>align="center">2-6</</code><code>td</code><code>></code>
<code> </code><code></</code><code>tr</code><code>></code>
<code> </code><code><</code><code>td</code> <code>align="center">1-7</</code><code>td</code><code>></code>
<code> </code><code><</code><code>td</code> <code>align="center">2-7</</code><code>td</code><code>></code>
<code> </code><code><</code><code>td</code> <code>align="center">1-8</</code><code>td</code><code>></code>
<code> </code><code><</code><code>td</code> <code>align="center">2-8</</code><code>td</code><code>></code>
<code> </code><code><</code><code>td</code> <code>align="center">1-9</</code><code>td</code><code>></code>
<code> </code><code><</code><code>td</code> <code>align="center">2-9</</code><code>td</code><code>></code>
<code> </code><code><</code><code>td</code> <code>align="center">1-10</</code><code>td</code><code>></code>
<code> </code><code><</code><code>td</code> <code>align="center">2-10</</code><code>td</code><code>></code>
<code> </code><code><</code><code>td</code> <code>align="center">1-11</</code><code>td</code><code>></code>
<code> </code><code><</code><code>td</code> <code>align="center">2-11</</code><code>td</code><code>></code>
<code> </code><code><</code><code>td</code> <code>align="center">1-12</</code><code>td</code><code>></code>
<code> </code><code><</code><code>td</code> <code>align="center">2-12</</code><code>td</code><code>></code>
<code> </code><code><</code><code>td</code> <code>align="center">1-13</</code><code>td</code><code>></code>
<code> </code><code><</code><code>td</code> <code>align="center">2-13</</code><code>td</code><code>></code>
<code> </code><code><</code><code>td</code> <code>align="center">1-14</</code><code>td</code><code>></code>
<code> </code><code><</code><code>td</code> <code>align="center">2-14</</code><code>td</code><code>></code>
<code> </code><code><</code><code>td</code> <code>align="center">1-15</</code><code>td</code><code>></code>
<code> </code><code><</code><code>td</code> <code>align="center">2-15</</code><code>td</code><code>></code>
<code></</code><code>table</code><code>></code>
<code></</code><code>body</code><code>></code>
<code></</code><code>html</code><code>></code>
下面是運作後的效果: