寫做不易,轉載請註明出處,謝謝。javascript
文章類別:Javascript基礎(面向初學者)css
在以前的章節中,咱們已經不依賴jQuery,單純地用JavaScript封裝了不少方法,這個時候,你必定會想,這些常用的方法能不能單獨整理成一個js文件呢?html
固然能夠,封裝原本就是幹這個用的。放在一個單獨js文件裏當然不錯,其實咱們也能夠單獨整一個js類庫,一方面能夠鍛鍊一下本身封裝方法的能力,另外一方面,也能夠將本身學到的東西作一個整理。java
出於這個目的,本文將介紹如何封裝一個簡單的js類庫。(固然,只是開一個頭,熟悉一下js基礎而已。實際使用的話我感受徹底沒有必要,由於jQuery已經很強大了,直接使用第三方的就能夠)node
所謂的js庫,其實也就是一個js文件,我思前想後,決定取個名字叫「miniQuery」,是否是山寨的味道十足呢?哈,請不要在乎這些小細節。ajax
大概的設計以下:json
擴展方法的兼容(主要寫一些兼容的擴展方法,好比 forEach 方法等)api
工具包定義 (就是以前封裝的utils.js,咱們的miniQuery須要依賴這個工具包,爲了方便,就乾脆寫在一個文件裏面了。)數組
miniQuery定義安全
// ------------------------ 基本擴展, 字符串,數組等---------------------------------// function extend_base (){ if(!String.prototype.format ){ String.prototype.format = function() { var e = arguments; return this.replace(/{(\d+)}/g,function(t, n) { return typeof e[n] != "undefined" ? e[n] : t }) }; } if (!Array.prototype.forEach && typeof Array.prototype.forEach !== "function") { Array.prototype.forEach = function(callback, context) { // 遍歷數組,在每一項上調用回調函數,這裏使用原生方法驗證數組。 if (Object.prototype.toString.call(this) === "[object Array]") { var i,len; //遍歷該數組全部的元素 for (i = 0, len = this.length; i < len; i++) { if (typeof callback === "function" && Object.prototype.hasOwnProperty.call(this, i)) { if (callback.call(context, this[i], i, this) === false) { break; // or return; } } } } }; } if(!String.prototype.format ){ Array.isArray = function(obj){ return obj.constructor.toString().indexOf('Array') != -1; } } //待補充 ... }
咱們定義一個extend_base方法,裏面主要對js內置對象的api作了一些兼容性補充,目前還不完善,只有寥寥幾個方法。固然,若是你不考慮IE678的話,那麼基本上不須要這一部分了。
定義完成後當即調用。
extend_base();
// ------------------------ 工具包---------------------------------// var utils = { center : function(dom){ dom.style.position = 'absolute'; dom.style.top = '50%'; dom.style.left = '50%'; dom.style['margin-top'] = - dom.offsetHeight / 2 + 'px'; dom.style['margin-left'] = - dom.offsetWidth / 2 + 'px'; }, /** dom相關 * */ isDom : ( typeof HTMLElement === 'object' ) ? function(obj){ return obj instanceof HTMLElement; } : function(obj){ return obj && typeof obj === 'object' && obj.nodeType === 1 && typeof obj.nodeName === 'string'; } , /** 數組相關 * */ isArray : function(obj){ return obj.constructor.toString().indexOf('Array') != -1; } }
終於到miniQuery了,在寫代碼以前,先簡單說一下自執行函數。
可能你在不少書上,或者下載的源碼裏面,常常會看到這樣的代碼:
(function(){ })();
這樣子你或許以爲很奇怪,沒事,咱們一塊兒來分析。
在js中,你若是把函數看做一個數據類型,和其餘語言中的 Integer, Float , String等等同樣,就會理解不少事情了。固然,其實在js中,函數自己就是一個對象,否則的話就不會出現call方法了。由於只有對象才能夠調用方法嘛。不過,大部分狀況下,你把函數理解爲數據類型就能夠了。
匿名函數:
function(){ }
這是一個函數,由於沒有函數名,因此是一個匿名函數。你定義了它,若是接下來你不想經過函數調用的方式來執行它,那麼是否是能夠直接給它打一個括號來執行呢?
像這樣:
function(){ }();
不過,由於js語法的關係,這樣子是不能執行的,你須要用一對圓括號來包一下:
( function(){ alert("你好!"); }() ) ;
這樣就能夠了,下面是另外一種寫法:
( function(){ alert("你好!"); } )();
這樣也能夠,這種寫法會更多一點。它的意思就是說,我不關心你這個函數叫什麼名字,反正你在被定義的時候就要給我執行,這就是所謂的自執行函數。
好,問題來了,怎麼加參數呢?
之前咱們習慣於這麼寫:
function say(str){ alert(str); } say("你好!");
依葫蘆畫瓢
( function(str){ alert(str); } )("你好!");
OK了。
是否是同樣的意思呢?
沒啥區別,之前怎麼作,如今還怎麼作,無非就是一個函數傳參的事情罷了。
咱們將圓括號的位置調整一下
( function(str){ alert(str); } )("你好!");
這樣差很少就是最終的版本了,我記得初學js的時候,看這種代碼很吃力,好像在看外星語言同樣,後來看多了也就習慣了。
自執行函數就是這麼一回事,沒什麼大不了的。
有了上面的解釋,之後若是你再遇到這種寫法,就 so easy 啦。
因此,不要再恐懼了,它就是這麼回事,沒什麼大不了的,我這麼後知後覺的人都能寫,你也能夠。我花了半年的時間纔看明白,我相信你如今只須要幾分鐘。個人意思是,若是你以前不知道這些的話。
那麼,何時用自執行函數呢?
當你以爲某個函數只須要執行一次,並且不須要在其餘地方調用的時候,就用。
你可能會問了,我幹嗎要這樣寫啊,反正就執行一次,我直接把實現代碼寫在外面不就好了?
緣由很簡單,由於那樣的話,你定義的變量就會是全局的,而通常來講咱們設計的原則是儘可能不要使用全局變量。
而採用這種方式,咱們就造成了一個匿名函數,函數的定義又會造成閉包,因此比較安全和簡潔。
你可能還會以爲疑惑,我幹嗎要這些寫,若是我非要給函數取一個名字,而後立刻調用呢?
額,其實我我的認爲這也是沒有問題的,可是你得費一番心思去給函數取名字,取 a,b,c,d 這樣的名字確定是很差的。那麼,我私覺得,還不如干脆就用匿名函數算了,免得麻煩。
若是這部分知識你之前就不知道,那麼我建議你把這篇文章多看幾遍,反正就是那麼回事,沒什麼大不了的。我當初就是走了不少彎路,也沒有人教我,只有靠本身在那瞎摸索和各類百度,固然,如今想一想很簡單了。
咱們的miniQuery的定義就放在這個自執行函數裏面,這樣一來,只要有人調用了這個js文件,就能調用miniQuery函數了。
固然,你直接放在外面其實也沒事,由於反正就一個方法,並且這個方法原本就是要暴露出去的。
這邊爲了說明自執行函數,就硬加進來了。
咱們把miniQuery的定義丟進去。
好比,像這樣子的:
(function(){ var miniQuery = function(){ alert('Hello miniQuery!'); } })();
咱們嘗試在外面調用:
miniQuery();
很遺憾,調不到。
咱們再回顧一下代碼:
(function(){ var miniQuery = function(){ alert('Hello miniQuery!'); } })(); miniQuery();
原來,miniQuery是存在於一個閉包中的,它能夠訪問到父級做用域的變量,可是反過來就不行,除非函數本身用 return 的方式將私有數據暴露出去。這些在以前的關於閉包的文章裏面已經解釋過了,這裏再也不贅述。
解決方法有不少,好比,最簡單的,咱們直接把var去掉,這樣就會發生一次變量提高,miniQuery被升級爲全局變量,掛在window對象上面。
(function(){ miniQuery = function(){ alert('Hello miniQuery!'); } })(); miniQuery();
成了,簡單明瞭,乾乾淨淨。
雖然我以爲頗有道理,可是我看別人的代碼,他們封裝本身的js庫的時候,幾乎沒有這樣作的,所以咱們也採用一種大衆的作法。
即,咱們把window做爲參數傳進去,而後手動將miniQuery掛上去。
(function(win){ var miniQuery = function(){ alert('Hello miniQuery!'); } win.miniQuery = miniQuery; })(window); miniQuery();
是否是也能夠呢?
若是你以爲每次寫miniQuery太麻煩,那麼咱們能夠給它換一個名字,好比 $
(function(win){ var miniQuery = function(){ alert('Hello miniQuery!'); } win.$ = miniQuery; })(window); $();
這樣就差很少了。
咱們先弄來一個測試用的網頁:
.wrap { width:80px; height:80px; background:darkslateblue; margin:20px; border-radius: 2px; }
<body> <div class='boxes'> <div id='box1' class='wrap'></div> <div id='box2' class='wrap'></div> <div id='box3' class='wrap'></div> </div> </body>
舉一個例子,如今咱們要獲取id爲box1的盒子,並把它的背景色改成紅色。
用js代碼,咱們會這樣作:
var box2 = document.getElementById('box2'); box2.style.backgroundColor = 'red';
思路很清晰,分爲簡單的兩步:
第一步:獲取dom對象。
第二部:設置其背景色爲紅色。
一樣的,咱們的 miniQuery 也要這麼作,首先得獲取對象,而後進行操做。就好像你作飯,首先得有米麪吧。所謂巧婦難爲,無米之炊。
因而,咱們有了下面的代碼:
var miniQuery = function(selector){ var miniQuery = document.getElementById(selector); console.log(miniQuery); }
selector 表明選擇器,它只是一個參數名字,參數列表的名稱是能夠本身定義的。你寫 aaa , bbb , ccc 都沒問題,只要你願意的話。
我之前常常看別人寫的代碼,參數裏面有callback,如今我知道是回調函數的意思。但是我之前不知道,而後就以爲很困惑,做爲一個英語比日語還差的js玩家,我感到很那個啥。
其實無所謂,只是一個名字而已,你寫什麼都行,只要符合標識符的命名規範就成。
總有人以爲,看到參數裏邊寫了context(上下文),callback(回調函數)這樣的詞彙,就以爲很困惑。
不要困惑啦,不要再驚恐啦,它就是一個名稱罷了!
。。。
額,扯遠了,繼續回來。
咱們在外面調用miniQuery ~
window 上面掛的是 $ , 其實就是 miniQuery
$('box1');
運行結果
嗯,確實取到了呢。
接下里,咱們給dom元素變動背景色爲紅色。
var miniQuery = function(selector){ var miniQuery = document.getElementById(selector); miniQuery.style.backgroundColor = 'red'; }
效果確實出來了。
但是呢,若是用戶過幾天又來個需求,說我要把box1的寬度變爲以前的兩倍,你怎麼辦?
總不可能去修改源碼吧!
這時候,咱們就能夠考慮能不能經過一個什麼辦法,我先用miniQuery把你傳進來的東西包裝成dom元素,保存起來返回給你,同時再給你返回一大堆方法,好比改變高度啊,添加背景色啊等等。那麼,操做的就是以前保存的元素了。也就是你一開始但願操做的元素。
這是一個很好的想法,咱們通過代碼的重寫,最終產生了這樣的一個miniQuery函數:
var miniQuery = function(selector){ var miniQuery = document.getElementById(selector); return { obj : miniQuery , //將dom元素保存起來,再返回給你 // ------------------------ css 相關 ------------------------// backgroundColor : function(color){ this.obj.style.backgroundColor = color; } } } win.$ = miniQuery; })(window);
咱們再調用一次,看看這回它給咱們返回的是什麼東東?
var $box = $('box1'); console.log($box);
可見,它給咱們返回的是一個json對象,裏面有 obj 變量和 backgroundColor 函數。這樣的好處就是極大的擴展了咱們的miniQuery,你給我一個選擇器,我就包起來,而後不只把它返回給你,並且還給你各類api方法!
因而咱們就能夠直接調用 backgroundColor 函數了。
var $box = $('box1'); $box.backgroundColor('red');
成了。
咱們如今返回的,不是一個單純的dom元素,dom元素只是它的一部分。能夠說,咱們返回給用戶的是一個miniQuery對象!
通過改進,我已經陸陸續續地給miniQuery添加了不少方法,大部分是模擬的jQuery:
順便弄了兩個小型的組件,一個是按鈕,另外一個是簡單的數據列表。
按鈕使用:
<link rel="stylesheet" type="text/css" href="css/mui.css"/>
<div class='box'></div>
var $box = $('.box').eq(0); $box.linkbutton();
按鈕的樣式就出來了,而後咱們來設置按鈕的屬性。
var $box = $('.box').eq(0); $box.linkbutton({ text : '保存' , click : function(){ alert('保存成功!'); } });
按鈕的大小也自動變大了。
對應的css:
mui.css
.linkbutton { padding: .4em .9em; /*em的好處就是隨着父元素的字體大小而變化,當該元素的字體變化時,會自適應*/ border: 1px solid rgba(0,0,0,.1); background-color: #ac0; border-radius: .2em; box-shadow: 0 1px 5px rgba(0,0,0,.5); color: #fff; text-shadow: 0 -.06em .24em rgba(0,0,0,.5); /*將陰影設置爲半透明,就無所謂底色了,都能很好地適應*/ font-size: 130%; line-height: 1.5; /*行高是字號的1.5倍*/ display:inline-block; cursor:pointer; font-family: "微軟雅黑"; }
數據列表簡單演示:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <link rel="stylesheet" type="text/css" href="css/mui.css"/> <script type="text/javascript" src="js/miniQuery.js"></script> </head> <body> <a id='btn0'></a> <div id='grid0'></div> </body> <script> $('#btn0').linkbutton({ text : '測試' , click : function(){ if(grid0.getSize() < 1){ alert('請選擇一條數據!'); return; } alert('您選擇的是' + JSON.stringify(grid0.getSelected())); } }); var grid0 = mui.get('#grid0').dataGrid({ header : [ {name:'ID' , width:10 , type : 'checkColumn' } , {name:'標題' , type : 'column' , field : 'title'} , {name:'分類' , type : 'column' , field : 'type'} , {name:'做者' , type : 'column' , field : 'author'} , {name:'時間' , type : 'column' , field : 'time'} , ] , }); grid0.load([ {title : '111' , type : 'A' , author : '張三' , time : '2015'} , {title : '222' , type : 'B' , author : '李四' , time : '2015'} , {title : '333' , type : 'C' , author : '王五' , time : '2015'} , {title : '444' , type : 'D' , author : '趙六' , time : '2015'} , ]); </script> </html>
固然,好多組件都還不夠完善,我主要也是本身嘗試一下,不過並不打算再拓展了。
本身作個小類庫主要用於學習,之後仍是用jQuery吧。
附錄A
"use strict"; /** * miniQuery 和 工具類庫 * 版本 1.1 (修正了一部分Bug,增長了一些方法) * 做者:剽悍一小兔 */ // ------------------------ 基本擴展, 字符串,數組等---------------------------------// function extend_base (){ if(!String.prototype.format ){ String.prototype.format = function() { var e = arguments; return this.replace(/{(\d+)}/g,function(t, n) { return typeof e[n] != "undefined" ? e[n] : t }) }; } if (!Array.prototype.forEach && typeof Array.prototype.forEach !== "function") { Array.prototype.forEach = function(callback, context) { // 遍歷數組,在每一項上調用回調函數,這裏使用原生方法驗證數組。 if (Object.prototype.toString.call(this) === "[object Array]") { var i,len; //遍歷該數組全部的元素 for (i = 0, len = this.length; i < len; i++) { if (typeof callback === "function" && Object.prototype.hasOwnProperty.call(this, i)) { if (callback.call(context, this[i], i, this) === false) { break; // or return; } } } } }; } if(!String.prototype.format ){ Array.isArray = function(obj){ return obj.constructor.toString().indexOf('Array') != -1; } } } extend_base(); // ------------------------ 工具包---------------------------------// var utils = { center : function(dom){ dom.style.position = 'absolute'; dom.style.top = '50%'; dom.style.left = '50%'; dom.style['margin-top'] = - dom.offsetHeight / 2 + 'px'; dom.style['margin-left'] = - dom.offsetWidth / 2 + 'px'; }, /** dom相關 * */ isDom : ( typeof HTMLElement === 'object' ) ? function(obj){ return obj instanceof HTMLElement; } : function(obj){ return obj && typeof obj === 'object' && obj.nodeType === 1 && typeof obj.nodeName === 'string'; } , /** 數組相關 * */ isArray : function(obj){ return obj.constructor.toString().indexOf('Array') != -1; } } // ------------------------ miniQuery.js ---------------------------------// ;(function(win){ var miniQuery = function(selector){ var miniQuery = null; var length = 0; var children = []; if(!selector) return; /** 1. 傳入的是id * */ if(selector.toString().indexOf('#') != -1) { selector = selector.replace('#',''); miniQuery = document.getElementById(selector); } /** 2. 傳入的是class * */ else if(selector.toString().indexOf('.') != -1){ selector = selector.replace('.',''); miniQuery = document.getElementsByClassName(selector); } /** 3. 傳入的是dom元素 * */ else if(utils.isDom(selector)){ miniQuery = selector; } /** 4. 傳入的是標籤 * */ else if(typeof selector === 'string'){ miniQuery = document.getElementsByTagName(selector); return miniQuery; } if(!miniQuery) return; //若是本類庫包裝不了,就返回 if(miniQuery.length){ //若是是一個類數組元素的話,就獲取他的長度 length = miniQuery.length; }else{ length = 1; //這種狀況,說明成功包裹了元素,可是該元素仍是存在的,就將長度設定爲1 } children = miniQuery.children; //取得全部的孩子節點 return { /** 屬性區 */ obj : miniQuery, //返回的dom元素 index : 0 , //默認的角標(假如 miniquery 是一個類數組的話) length : length, //元素的個數(假如 miniquery 是一個類數組的話) children : children,//全部孩子節點 /** 方法區 */ // ------------------------ dom 相關 ---------------------------------// /**獲取dom對象自己,返回純粹的dom元素,而非miniQuery元素*/ getObj : function(){ return this.obj; } , /**獲取元素的長度*/ size : function(){ return this.length; } , /** 假如 miniquery 是一個類數組的話,用於返回其中一個元素 */ eq : function(index){ if(length > 0) { return $(this.obj[index]); //eq返回的仍是miniQuery對象 }else{ return null; } } , /** 得到第一個匹配元素 */ first : function(){ return $(this.obj[0]); } , /** 得到最後一個匹配元素 */ last : function(){ return $(this.obj[this.length - 1]); } , /** 得到最後一個匹配元素 */ getChildren : function(){ return this.obj.children; } , /** 得到某一個孩子節點 */ getChild : function(i){ return $(this.children[i]); } , /** 得到父節點 */ getParent : function(){ return $(this.obj.parentElement); } , /** 得到上一個節點 */ previous : function(){ var parent = this.getParent(); var children = parent.children; for(var i = 0; i < children.length; i++){ if(this.obj == children[i]) { return $(children[i - 1]); } } return null; } , /** 得到下一個節點 */ next : function(){ var parent = this.getParent(); var children = parent.children; for(var i = 0; i < children.length; i++){ if(this.obj == children[i]) { return $(children[i + 1]); } } return null; } , findClassDom : function(className){ this.obj = this.obj.getElementsByClassName(className) ; return this ; } , findIdDom : function(id){ var $this = this; var children = this.getChildren(); children = Array.prototype.slice.call(children); //obj 轉 [] children.forEach(function(item){ //console.log(item.id); (id === item.id) && ($this = item) ; }); return this ; } , // ------------------------ css 相關 ---------------------------------// /** 添加背景色 */ backgroundColor : function(color){ this.obj.style.backgroundColor = color; return this; } , /** 獲取style */ getStyle : function(){ var styleEle = null; if(window.getComputedStyle){ styleEle = window.getComputedStyle(this.obj,null); }else{ styleEle = ht.currentStyle; } return styleEle; } , /** 設置或者拿到高度 */ height : function(h){ if(!h) return this.getStyle().getPropertyValue('height'); (typeof h == 'number') && (h = h + 'px'); this.obj.style.height = h; return this; } , /** 設置或者拿到寬度 */ width : function(w){ if(!w) return this.getStyle().getPropertyValue('width'); (typeof w == 'number') && (w = w + 'px'); this.obj.style.width = w; return this; } , /** 設置自定義樣式 */ css : function(obj){ if(!obj) return; for(var key in obj){ //console.log(key + '=========' + obj[key]); this.obj.style[key] = typeof obj[key] === 'number' ? obj[key] + 'px' : obj[key]; } return this; } , /** 設置放大 倍數*/ scale : function(scaleNumber){ this.css({ scale : scaleNumber }); return this; } , hasClass : function(cls) { return this.obj.className.match(new RegExp('(\\s|^)' + cls + '(\\s|$)')); } , addClass : function(cls){ if (!this.hasClass(cls)) this.obj.className += " " + cls; } , removeClass : function(cls) { if (this.hasClass(cls)) { //console.log(this.obj); var reg = new RegExp('(\\s|^)' + cls + '(\\s|$)'); this.obj.className = this.obj.className.replace(reg, ' '); //修正bug,以前右邊少了一個this } } , toggleClass : function(cls){ if(this.hasClass(cls)){ this.removeClass(cls); }else{ this.addClass(cls); } } , // ------------------------ 動畫 相關 ---------------------------------// //TODO animate : function(){ } , // ------------------------ 事件相關 ---------------------------------// on : function(eventName,callback){ var $this = this; this.obj['on' + eventName] = function(){ callback.call($this,$this.obj); //context指向$this,參數傳入dom對象 }; return this; } , // ------------------------ 屬性相關 ---------------------------------// attr : function(attr){ return this.obj.attributes[attr]; } , // ------------------------ ajax相關 ---------------------------------// // ------------------------ ui ---------------------------------// /** 按鈕 * */ linkbutton : function(opts){ var opts = opts || {}; /**添加基本樣式* */ this.addClass('linkbutton'); this.on('mouseover' , function(e){ //console.log(e); this.css({ backgroundColor: '#d4ef50' }); }).on('mouseout',function(e){ this.css({ backgroundColor: '#ac0' }); }); opts.text && (this.obj.innerText = opts.text); opts.click && (this.on('click' , opts.click)); } , /** 數據列表 * */ dataGrid : function(opts){ var $this = this; var opts = opts || {}; var header = null; //表頭 var id = null; //grid的id,惟一 var tb_id = null; var tbody_id = null; var count = 0; //爲了防止id重複 var columns = []; //存放field var types = []; if(!this.obj.id) return; else id = this.obj.id; if(!opts.header) return; else header = opts.header; /**添加基本樣式* */ this.addClass('tableBox'); //初始化表頭 function initHeader(){ var time = new Date().getTime(); tb_id = 'mui-table_' + time + '_' + count++; var html = " <table id='"+tb_id+"'><thead>" ; //拼接表頭 html += '<tr>' ; header.forEach(function(item){ columns.push(item.field); //添加字段名 types.push(item.type); //添加列類型 var width = null; if(item.width) width = item.width + 'px'; //設置寬度 if(width) width = "width='"+width+"' "; html += "<th "+width+">" + item.name + '</th>' }); tbody_id = 'mui-table-tbody_' + time + '_' + count++; html += "</tr></thread><tbody id='"+tbody_id+"'></tbody>" ; html += '</table>' ; $this.obj.innerHTML = html; } // initHeader(); return { tbody_id : tbody_id , allData : null , ids : [], //保存每一行的id index : 0,//做爲行號和id //加載數據 load : function(data){ this.allData = data; var html = ''; //console.log($('#' + tbody_id)); var len = data.length; //總行數 var columnSize = columns.length;//總列數 //alert(len); for(var i = 0;i < len ; i++){ this.ids.push('mui-dataGrid-tr_' + ( new Date().getTime() ) + '_' + this.index++) ; //console.log(this.ids[this.index - 1]); //console.log(this.ids[this.index - 1].substring(this.ids[this.index - 1].length - 1 )); //獲取行號 html += "<tr id='"+this.ids[this.index - 1]+"'>"; /*以前在這裏少了一個單引號,最終顯示的數據只有所有的一半,如今已經更正*/ //遍歷列 //console.log(types); for(var j = 0; j < columnSize ; j++){ var columnName = columns[j]; if(data[i][columnName]){ html += '<td>' + data[i][columnName] + '</td>'; }else if(types[j] == 'checkColumn'){ html += '<td><input type="checkbox" value=""/></td>'; }else { html += '<td></td>'; } } //列遍歷完後,這一行才結束 html += '</tr>' } //展現數據 win.$('#' + this.tbody_id).obj.innerHTML = html; //給每一行添加事件 this.ids.forEach(function(rowId){ win.$('#' + rowId).on('click',function(){ this.toggleClass('selected'); if(this.hasClass('selected')){ this.obj.getElementsByTagName('input')[0].checked = true; }else { this.obj.getElementsByTagName('input')[0].checked = false; } }); }); } , //獲取全部數據 getData : function(){ return this.allData; } , //根據行號獲取某一行 getRow : function(rowIndex){ return this.getData()[rowIndex]; } , //獲取全部的行號 getSize : function(){ var len = 0; this.getSelected && (len = this.getSelected().length) ; return len; } , //返回選中的行,一條或者多條 getSelected : function(){ var rows = win.$('.selected').obj; //獲取全部選中行 var len = 0; len = rows.length; var arr = []; for(var i = 0;i < len;i++){ //console.log(rows[i].id.substring(rows[i].id.length - 1)); arr.push(this.getRow(rows[i].id.split('_')[2])) ; } arr.length == 1 && ( arr = arr[0] ); return arr; //this.ids[this.index - 1].substring(this.ids[this.index - 1].length - 1 ) } }; } } } win.$ = miniQuery; win.mui = { get : function(sel){ return miniQuery(sel); } } })(window);
.linkbutton { padding: .4em .9em; /*em的好處就是隨着父元素的字體大小而變化,當該元素的字體變化時,會自適應*/ border: 1px solid rgba(0,0,0,.1); background-color: #ac0; border-radius: .2em; box-shadow: 0 1px 5px rgba(0,0,0,.5); color: #fff; text-shadow: 0 -.06em .24em rgba(0,0,0,.5); /*將陰影設置爲半透明,就無所謂底色了,都能很好地適應*/ font-size: 130%; line-height: 1.5; /*行高是字號的1.5倍*/ display:inline-block; cursor:pointer; font-family: "微軟雅黑"; } .tableBox{ width:1200px; background:#f9f9f9; margin:20px auto 0; padding:6px; position:relative; font-family: 微軟雅黑; } .tableBox table{ width:100%; border:2px solid #fff; } .tableBox table tr { border-collapse: separate; border-spacing: 1px; } /*選中行*/ .tableBox table tr.selected { background:#cce4f3; } /*表頭*/ .tableBox th{ background: #eaeaea; padding: 6px; color: #666; font-size: 14px; } .tableBox td { font-size: 13px; padding: 4px 10px; }
畢竟是本身DIY出來的,因此沒仔細測試,確定還有一些BUG。不過無論怎麼說,都算是一次嘗試吧,呵呵。