出于效率和保持js庫最小化的考慮,TWaver HTML5的Tree組件默認的交互方式比較單調,目前只有選中改變文字背景;但是這不代表TWaver功能不夠強大,相反,TWaver預留了很多可以重載的方法方便我們擴展,本文中我們就利用這些方法實現鼠標滑過改變背景色的效果。
先來張gif圖片看看效果:
實現方式再簡單不過,只有短短幾十行代碼,先列一下我們用到的方法:
- onDataRendered(div, data, row, selected)
- adjustRowSize()
- getSelectColor()
除了上面三個方法,還有兩個事件監聽器,稍后我們就會講解,先來看下這三個方法的原理:
- onDataRendered 從字面上很好理解,每當Tree要渲染行數據的時候就會調用此方法
- div 行數據的顯示容器,每行都有一個div容器,我們可以通過改變div背景色來實現變色效果
- data 行數據,我們監聽鼠標move事件,記錄鼠標所在行的數據,然后在onDataRendered里判斷當前行是否在鼠標下,如果在就改變div的背景色
- row 行數
- selected 當前行是否被選中,如果被選中將div設置為深色背景
看一下這個方法的實現:
1 this.onDataRendered = function (div, data, row, selected) {
2 DemoTree.superClass.onDataRendered(div, data, row, selected);
3 if (selected) {
4 //如果當前行被選中,設置div為深色背景和邊框
5 div.style.background = "#d8e9fc";
6 div.style.border = "1px solid #7da2ce";
7 }
8 else if (data == self.newdata) {
9 //如果當前行是鼠標所在的行,設置div為淺色背景和邊框
10 div.style.background = "#f6f9fd";
11 div.style.border = "1px solid rgb(184, 214, 251)";
12 }else{
13 //設置其它行的padding
14 div.style.padding="1px";
15 }
16 }
- adjustRowSize 這個方法緊接著onDataRendered執行,用來設置行寬和行高。我們在onDataRendered為div設置了邊框或padding,會造成Tree上出現橫向滾動條,所以需要重寫這個方法:
1 this.adjustRowSize = function () {
2 var id, div;
3 var hpx = self.getRowHeight() - self.getRowLineWidth() + 'px';
4 //每行div的寬度都減去2像素,避免出現橫向滾動條
5 var wpx = Math.floor((self.getView().scrollLeft + self.getView().clientWidth) / self.getZoom()-2) + 'px';
6 for (id in self._renderMap) {
7 div = self._renderMap[id];
8 div.style.height = hpx;
9 div.style.width = wpx;
10 }
11 };
- getSelectColor 這個方法用來返回Tree上被選中行的文字的背景色,因為我們已經通過div給整行設置了背景色,文字背景就顯得多余了,所以我們重寫這個方法返回一個透明色:
1 this.getSelectColor = function () {
2 return "rgba(0,0,0,0)";
3 };
除了這三個方法,還有兩個監聽器
首先,鼠標移動的時候需要保存鼠標下的data
1 var self=this;
2 this._view.addEventListener("mouseover", function (e) {
3 self.newdata = self.getDataAt(e);
4 if (self.olddata != self.newdata) {
5 if (self.olddata) {
6 //調用invalidateData通知Tree數據發生了變化,TWaver稍后會調用onDataRendered
7 self.invalidateData(self.olddata);
8 }
9 if (self.newdata) {
10 self.invalidateData(self.newdata);
11 }
12 self.olddata = self.newdata;
13 }
14 });
其次:當鼠標移除Tree時,清空滑過時設置的背景色:
1 this._view.addEventListener("mouseout", function (e) {
2 if (self.newdata) {
3 self.invalidateData(self.newdata);
4 self.newdata = null;
5 }
6 });
最后附上完整的代碼:
1 var DemoTree = function (dataBox) {
2 DemoTree.superClass.constructor.apply(this, arguments);
3 var self = this;
4
5
6 this.newdata = null;
7 var olddata = null;
8 this._view.addEventListener("mouseover", function (e) {
9 self.newdata = self.getDataAt(e);
10 if (self.olddata != self.newdata) {
11 if (self.olddata) {
12 self.invalidateData(self.olddata);
13 }
14 if (self.newdata) {
15 self.invalidateData(self.newdata);
16 }
17 self.olddata = self.newdata;
18 }
19 });
20
21 this.onDataRendered = function (div, data, row, selected) {
22 DemoTree.superClass.onDataRendered(div, data, row, selected);
23 if (selected) {
24 div.style.background = "#d8e9fc";
25 div.style.border = "1px solid #7da2ce";
26 }
27 else if (data == self.newdata) {
28 div.style.background = "#f6f9fd";
29 div.style.border = "1px solid rgb(184, 214, 251)";
30 }else{
31 div.style.padding="1px";
32 }
33 }
34
35 this.adjustRowSize = function () {
36 var id, div;
37 var hpx = self.getRowHeight() - self.getRowLineWidth() + 'px';
38 var wpx = Math.floor((self.getView().scrollLeft + self.getView().clientWidth) / self.getZoom()-2) + 'px';
39 for (id in self._renderMap) {
40 div = self._renderMap[id];
41 div.style.height = hpx;
42 div.style.width = wpx;
43 }
44 };
45
46 this.getSelectColor = function () {
47 return "rgba(0,0,0,0)";
48 };
49 this._view.addEventListener("mouseout", function (e) {
50 if (self.newdata) {
51 self.invalidateData(self.newdata);
52 self.newdata = null;
53 }
54 });
55 };
56 twaver.Util.ext(DemoTree, twaver.controls.Tree, {});