用于節(jié)點(diǎn)操作的API,顛覆原生操作HTML DOM節(jié)點(diǎn)的API
敏捷開發(fā)的確是利害,但如何練就這種深?yuàn)W的武功呢?就我自身的情況靠人傳授武功是不可能了,因?yàn)楣揪臀乙粋€(gè)做開發(fā)的,苦思冪想之后,決定從開源的優(yōu)秀框架入手,把它一行一行代碼看懂,然后再為我所用。因?yàn)槭且粋€(gè)人開發(fā),前臺和后臺都得包辦,哪從那一面做起呢? 之前有過一二個(gè)月的開發(fā)經(jīng)驗(yàn),覺得前臺的JS很費(fèi)時(shí),而且老覺得在做重復(fù)的事情,比如發(fā)ajax請求,接收結(jié)果之后操作節(jié)點(diǎn)(有時(shí)候遇到不兼容的情況,如select和table在IE下不支持使用innerHTML,style在IE不會自動(dòng)轉(zhuǎn)化為字符串,要用cssText代替,一旦這些情況遇上,真得是無比打擊程序員的積極性,因?yàn)槟阋獮榇嘶〞r(shí)間去找替代方案,去調(diào)試),還有節(jié)點(diǎn)輪換,彈出層,表單驗(yàn)證等一系列煩瑣工作。所以我就堅(jiān)決從前臺的JS做起。為了練就怎么把JS的重用性提高,我選擇向Jquery取經(jīng)?;藥讉€(gè)月看了一大半,略有所得。我其中之一的JS模塊“無限深度操作節(jié)點(diǎn)”(文采不好,名字不妥別見怪)出來了。有了它,我在操作節(jié)點(diǎn)方面變得容易,代碼變得精簡,而且不用寫額外的代碼去兼容瀏覽器,談笑中,功能就完成了。
首先我談?wù)勈鞘裁醋尣僮鞴?jié)點(diǎn)給我們帶來煩惱:
- 編寫ajax程序時(shí),動(dòng)態(tài)增刪改頁面元素幾乎是不可避免的,使用屬性innerHTML就是我們經(jīng)常利用的途徑,但在IE中table,thead,tfoot,tbody,tr,col,colgroup,html,title,style,frameset的innerHTML屬性是只讀的,也就是我們不能使用innerHTML更新這些節(jié)點(diǎn)。(這里沒有提到select,其實(shí)select也是不會成功的,估計(jì)是IE的bug)。例子如下:(下面的$id代表document.getElementById)
<select id="jkit">
<option value="1">jquery</option>
</select>//執(zhí)行代碼:
$id('jkit').innerHTML = '<option>jquery</option>';
//IE下并沒有報(bào)任何錯(cuò)誤,但select一個(gè)option節(jié)點(diǎn)都沒有了。如果你對table使用innerHTML,IE會報(bào)unknown runtime error<div id="jkit">
<select>
<option value="1">jquery</option>
</select>
</div>//執(zhí)行代碼:
$id('jkit').innerHTML = '<select><option value="1">jkit</option></select>';
//這樣IE也成功改變select,但這種做法有個(gè)缺點(diǎn),如果你對select注冊過事件,這些事件會全部丟失,你要外加代碼來重新注冊事件。 - 在指定的節(jié)點(diǎn)前后新增節(jié)點(diǎn),這就涉及于節(jié)點(diǎn)定位,節(jié)點(diǎn)創(chuàng)建以及給節(jié)點(diǎn)屬性設(shè)置。使用innerHTML通常只用于覆蓋DOM元素的所有節(jié)點(diǎn),如果只想改變元素的某個(gè)子節(jié)點(diǎn),或者只想在某個(gè)子節(jié)點(diǎn)前后增加節(jié)點(diǎn),仍然使用innerHTML就適得其反,實(shí)現(xiàn)起來很吃力了,而且使用了innerHTML之后,對子節(jié)點(diǎn)注冊過的事件肯定全部丟失掉。不使用innerHTML,那只好使用原生的DOM方法了,但這種代替方案也不好使,看下面例子:
<select>
<option value="1">jquery</option>
<option value="2">jkit</option>
<option value="3">mars</option>
</select>//現(xiàn)在我想在jkit之前多加一個(gè)option,用原生的DOM方法實(shí)現(xiàn):
var newNode = document.createElement('option'),//新建一個(gè)節(jié)點(diǎn)
selector = document.getElementById('jkit3'),
/* 也可以用selector.options,但getElementsByTagName更通用。
那用childNodes怎么?最好也不要,對于空白節(jié)點(diǎn),IE和FF的處理方式不一樣,
就這例子,在FF中,select的firstChild是空白文本節(jié)點(diǎn),
因?yàn)閟elect和第一個(gè)option之間有換行以及空白字符,
FF會為其創(chuàng)建節(jié)點(diǎn),而IE會忽略 */
options = document.getElementsByTagName('option');
newNode.setAttribute('value','new');
//newNode.setAttribute('text','NewNode');text不支持這樣設(shè)置
//newNode.text = 'NewNode';ie不支持這種方式
newNode.innerHTML = 'NewNode';
selector.insertBefore(newNode,options[1]);//在kit之前插入
<select>
<option value="1">jquery</option>
<option value="new">newNode</option>
<option value="2">jkit</option>
<option value="3">mars</option>
</select>
新增一個(gè)節(jié)點(diǎn)這要用到6句代碼,現(xiàn)在只是新增一個(gè)節(jié)點(diǎn),那對于批量操作怎么辦???而且原生的DOM方法不怎么好用,名字長而且參數(shù)順序不好記住,用的時(shí)候還得翻文檔(除非你的開發(fā)的天天在操作節(jié)點(diǎn),天天用這些方法)。有人說,也不怎么麻煩啊,我可以把這6句代碼寫成一個(gè)方法,然后通過傳參來完成批量操作。某種程度上是可以減輕工作量,但看遠(yuǎn)一點(diǎn),這也是不怎么現(xiàn)實(shí)的。原因有三:其一,每次新增的節(jié)點(diǎn)的屬性不一樣,加的位置不一樣,你還得在方法外面確定新節(jié)點(diǎn)的位置以及在方法內(nèi)部判斷這個(gè)節(jié)點(diǎn)要加那些屬些,下個(gè)節(jié)點(diǎn)要加哪個(gè)屬性,把代碼寫在法方里面只能讓你稍為輕松了些;其二,上面的代碼可以看到,新增一個(gè)節(jié)點(diǎn),你要排除很多不兼容的實(shí)現(xiàn)方法,由其在設(shè)置屬性方面,每種元素有不一樣的屬性,在兼容方案上就有差異,你針對不同元素寫這樣的方法時(shí),你必須要記住每種元素的兼容方案,可誰敢說能記住所有兼容方案,而且程序員想在技術(shù)上有所作為,靠的是思維邏輯的提升,而不是記憶,沒必需在這方面下苦功;其三,一個(gè)項(xiàng)目是實(shí)現(xiàn)功能了,下一個(gè)項(xiàng)目再來,有相似的功能,但在細(xì)節(jié)上有差異,按上面的做法,可以想像的到你的代碼重用性非常得低,因?yàn)橐淖兡承┘?xì)節(jié),你得重新理解曾經(jīng)寫下的邏輯,重新為你細(xì)節(jié)上的不同重構(gòu)代碼,這樣一來,效率太低了,完全談不上敏捷開發(fā)。
看到這樣,估計(jì)讀者都會問,如果不是這樣做,難道開發(fā)真的可以做到復(fù)制粘貼嗎?可以肯定的說,是不可能的。再全面的代碼也不可能滿足實(shí)現(xiàn)了不同包羅所有邏輯。但可以做得復(fù)用性很高,關(guān)鍵在于找出不同邏輯的共性并很好的獨(dú)立出來。上面的操作節(jié)點(diǎn)做法我之所以說復(fù)用性低,是因?yàn)榘巡僮鞴?jié)點(diǎn)跟特定的邏輯混合一起了,就是說特定邏輯的代碼跟操作節(jié)點(diǎn)的代碼關(guān)系太緊密了,到下一個(gè)邏輯又遇上節(jié)點(diǎn)操作時(shí),再想重用上次的代碼,就必須溫習(xí)上次寫下的邏輯,然后把操作節(jié)點(diǎn)的代碼分離出來后再派上用場。下面介紹的由我開發(fā)的無限層次節(jié)點(diǎn)操作,就很好的從邏輯上獨(dú)立出來,與邏輯無關(guān)。 - 上面的以select為例子,option是select的孩子節(jié)點(diǎn),我們操作的是兩層的樹型結(jié)構(gòu),如果再深入一些,操作元素的子孫節(jié)點(diǎn)呢?如何定位元素后代節(jié)點(diǎn)呢?下面還是以原生的dom方法來實(shí)現(xiàn):
<table>
<tr>
<td>
<ul>
<li></li>
<li></li>
</ul>
</td>
<td>
<ul>
<li></li>
</ul>
</td>
</tr>
</table>//現(xiàn)在我想在第一個(gè)li之前多加一個(gè)option,用原生的DOM方法實(shí)現(xiàn):
newNode = document.createElement('li'),
table = document.getElementById('jkit4'),
//取li的父節(jié)點(diǎn):
uls = table.getElementsByTagName('ul'),
/* getElementsByTagName雖然通用,但如果li標(biāo)簽里面嵌套了li,li父節(jié)點(diǎn)的兄弟節(jié)點(diǎn)也有l(wèi)i的話,那么getElementsByTagName都會取到這些節(jié)點(diǎn),如果你的html結(jié)構(gòu)真有哪么復(fù)雜,取出來結(jié)果后你也很難定位到你想找的li節(jié)點(diǎn)。遇到這情況,你只以通過childNodes一層層往下找,但之前提過childNodes在IE和FF中行為是不致的,所以你還要做兼容處理。*/
lis = table.getElementsByTagName('li');
newNode.innerHTML = 'NewNode';
//在指定位置插入
uls[0].insertBefore(newNode,lis[0]);
接下來要談的是,怎么編寫代碼讓我們的事件變得簡單。先不要理會技術(shù)層面的事件,假如現(xiàn)在有這么一個(gè)JS類,里面有若干方法,這些方法足以讓我們完成上面以及比上面更加復(fù)雜的事件。這個(gè)假設(shè)存在的類,因?yàn)橹挥蟹椒瑳]有具體實(shí)現(xiàn),我們把它稱為接口。那些下面要講的是定義接口,當(dāng)我們覺得接口中的方法能滿足需求,我們再去實(shí)現(xiàn)它。(這是比較好的開發(fā)流程,先規(guī)劃后行動(dòng))
- 實(shí)例化一個(gè)對象
開發(fā)項(xiàng)目中,因?yàn)椴恢篃o限層次節(jié)點(diǎn)操作這個(gè)插件,還有很多,囊括了b2c和b2b常用的插件,比如輪換,分頁,表單驗(yàn)證,表單元素取設(shè)值,批量上傳圖片,事件的重新包裝,事件的批量處理,搜索的自動(dòng)補(bǔ)全,購物車的ajax操作,以及公共方法的類。所以整個(gè)js會有很多類,每個(gè)類對應(yīng)一個(gè)js變量,這樣一來就有很多公共的js變量,如果開發(fā)的時(shí)候不小心在別的地方聲明了一個(gè)同名的變量,那么這個(gè)類被消失。為了避免這種情況,我把所有類封裝到一個(gè)名為$jkit類中,這樣公共的變量就只有一個(gè)了。插件的類變成了局部,我怎么樣訪問呢?我另外定義一個(gè)$CL的類,里面定義了一些方法,這些方法用于訪問$jkit的類,這樣一來,就算有再多插件,都只會有兩個(gè)公共變量$CL和$jkit。$CL負(fù)責(zé)調(diào)用$jkit。比如$CL中的newObj就用于實(shí)例化插件對象的方法。newObj有兩個(gè)參數(shù),第一個(gè)指定要實(shí)例化哪個(gè)插件,第二個(gè)參數(shù)用于實(shí)例化這個(gè)插件時(shí)的初始化參數(shù),以數(shù)組的形式傳參。<table id="jkit">
<tbody>
<tr>
<th class="align">Option</th>
<th>
<a href="javascript:void(0);">Status</a>
</th>
<th>
<a href="javascript:void(0);">Attribute</a>
</th>
</tr>
<tr>
<td></td>
<td>
<select size="3" name="status">
<option value="all">所有</option>
<option value="0">下架</option>
</select>
</td>
<td>
<ul>
<li id="lior">L</li>
<li>XL</li>
</ul>
</td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
</tr>
</tbody>
</table>/* 下面代碼實(shí)例化了一個(gè)無限層次節(jié)點(diǎn)操作插件的對象,相當(dāng)于重新構(gòu)造了一棵新的對象樹,新的對象樹帶有新的成員方法。就下面的例子,新對象樹引用為table,table也是新樹的根。它的后代對象由第二個(gè)參數(shù)childs決定 。新樹的根引用是操作其后代對象的入口。重點(diǎn)講解一下第二個(gè)參數(shù)。childs是一個(gè)數(shù)組結(jié)構(gòu),數(shù)組的第一個(gè)元素為tr,表示為dom根節(jié)點(diǎn)root的孩子節(jié)點(diǎn)tr重新構(gòu)造新對象。如果原dom根節(jié)點(diǎn)root的中沒有tr,將不會構(gòu)造對象;如果tr內(nèi)嵌有tr,不會為內(nèi)嵌的tr構(gòu)造節(jié)點(diǎn),也就是說只會為孩子節(jié)點(diǎn)構(gòu)造對象,孩子以下不會理會。第二個(gè)元素是td th,為什么有兩個(gè)呢?因?yàn)閠r下的孩子節(jié)點(diǎn)可以是th也可以是td,如果想同時(shí)為th td構(gòu)造新的對象,就要同時(shí)寫進(jìn)去,用空格分開,檢簽的順序不限制。第三個(gè)元素為select ul,為什么這兩個(gè)可以寫在一起?因?yàn)樗麄兾挥谕粚哟蔚?,相對于根?jié)點(diǎn),它們都在第三層。只要同一層次的都可以寫在一起。后面的以此類推,數(shù)量不限,就是無限層次了。新對象樹的層次結(jié)構(gòu)和原dom樹的層次結(jié)構(gòu)是一一對應(yīng)的。 */
root = document.getElementById('category'),
childs = ['tr', 'td th', 'select ul', 'li option'],
table = $CL.newObj('maNode', [root, childs]); - 新樹的成員方法,閱讀下面的API時(shí),請心里緊記兩點(diǎn),其一,根對象以及后代對象的所有方法都是針對原DOM對象的,比如對新對象調(diào)用del,其實(shí)質(zhì)是刪除了對應(yīng)的原DOM對象;其二,每次調(diào)用對象的增刪改時(shí),都會重新構(gòu)造相應(yīng)的分枝
- 根對象獨(dú)有方法
- function map(index1,index2,,,indexN){}
該方法用于尋找后代節(jié)點(diǎn),table.map(1,1,0)會找到第二行的第二個(gè)單元格的第一個(gè)對象,也就是select對應(yīng)的對象。當(dāng)map只有一個(gè)參數(shù),并且該參數(shù)為DOM原生對象,那么該方法返回對應(yīng)的新對象。- function index(DOMElement){}
該方法返回原生DOMElement對象對應(yīng)的素引,table.index(document.getElementById('lior')),則返回[1,2,0,0],結(jié)果是數(shù)組形式 - function index(DOMElement){}
- 后代對象獨(dú)有的方法
- function add(index, html){}
該方法用于增加兄弟節(jié)點(diǎn),index是相對于調(diào)用該方法的對象所處位置的位移,html就是要插要的節(jié)點(diǎn),html可以是符合W3c標(biāo)淮的任意html字任串
table.map(2).add(-1,'<tr><td></td><td></td><td></td></tr>'),在第三行前面新增一行(可以同時(shí)插入多行)
table.map(2).add(-2,'<tr><td></td><td></td><td></td></tr>'),在第三行前一行前面新增一行
table.map(0).add(2,'<tr><td></td><td></td><td></td></tr>'),在第一行后一行前面新增一行
table.map(1).add(0,'<tr><td></td><td></td><td></td></tr>'),index為0表示在當(dāng)前行前面新增一行,并把當(dāng)前行刪除
table.map(1).add('<tr><td></td><td></td><td></td></tr>'),省略第一個(gè)參數(shù),這是比較特別的用法,不用理會由哪個(gè)對象用,會在最后一行新增一行
table.map(1,1).add(1,'<td class="one">新增單元格</td>'),在第二行的第二個(gè)單元格之后新增一個(gè)單元格,再深入的節(jié)點(diǎn)如些類推,只需由map方法來確定節(jié)點(diǎn)就可以了
- function del(index){}
該方法用于刪除兄弟節(jié)點(diǎn),index是相對于調(diào)用該方法的對象所處位置的位移
table.map(1).del(),index省略表示刪除自身,這里刪除第二行等同于table.map(1).del(0)
table.map(0).del(2),這里刪除相對于當(dāng)前調(diào)用對象后面第二行,這里就是刪除第三行
table.map(2).del(-2),這里刪除相對于當(dāng)前調(diào)用對象前面第二行,這里就是刪除第一行
table.map(0,1).del([0,-1,1]),如果index是一個(gè)數(shù)組,那么就是刪除指定索引的兄弟節(jié)點(diǎn),這時(shí)不用理會由哪個(gè)對象調(diào)用,索引為負(fù)數(shù)表示從最后計(jì)起,-1表示最后一個(gè),這里刪除第一個(gè),第二個(gè)以及最后一個(gè)th
table.map(0,1).del(0,-1),如果有兩個(gè)參數(shù),表示刪除指定區(qū)間的兄弟節(jié)點(diǎn),這時(shí)不用理會由哪個(gè)對象調(diào)用,索引為負(fù)數(shù)表示從最后計(jì)起,-1表示最后一個(gè),這里刪除第一個(gè)至后一個(gè)元素,參數(shù)大的可以作為第一個(gè)參數(shù),大小順序沒有限制
- function getParent(){}
獲取調(diào)用對象父對象對應(yīng)的原生DOM對象節(jié)點(diǎn),table.map(0,1).getParent().tagName為tr- function getHigher(){}
獲取調(diào)用對象的父對象,table.map(0,1).getHigher.getNode().tagName為tr - function del(index){}
- 根對象以及后代對象都擁有的方法
- function getNode(){}
獲取調(diào)用對象對應(yīng)的原生DOM對象節(jié)點(diǎn),table.getNode().tagName為table,table.map(0,1).getNode()為th- function sizeOf(){}
獲取調(diào)用對象子對象的個(gè)數(shù),table.sizeOf()為3,表示有三行- function pos(){}
獲取調(diào)用對象在其所有兄弟節(jié)點(diǎn)的所處的位置,table.map(1).pos()為1- function html(html){}
獲取調(diào)用對象對應(yīng)原生dom對象的innerHTML,如果有傳參,為其innerHTML屬性賦值(請不要對innerHTML為只讀的對象賦值)- function attr(html){}
獲取調(diào)用對象對應(yīng)原生dom對象的innerHTML,如果有傳參,為其對應(yīng)的屬性賦值(還未實(shí)現(xiàn))- function before(index,html){}
往調(diào)用對象的指定子對象前面添加節(jié)點(diǎn),index是相對位移
table.before(1,'<tr><td></td><td></td><td></td></tr>'),第二行前面添加一個(gè)行
table.map(1,2,0).before(-1,'<li style="color:red;">新增li節(jié)點(diǎn)</li>'),在最后一個(gè)li前面新增一個(gè)li(索引為負(fù)數(shù)表示從最后計(jì)起,-1表示最后一個(gè))
table.before('<tr><td></td><td></td><td></td></tr>'),省略第一個(gè)參數(shù)表示在第一個(gè)子對象前面新增節(jié)點(diǎn)- function append(index,html){}
往調(diào)用對象的指定子對象后面添加節(jié)點(diǎn),index是相對位移
table.append(1,'<tr><td></td><td></td><td></td></tr>'),第二行后面添加一個(gè)行
table.map(1,2,0).append(-1,'<li style="color:red;">新增li節(jié)點(diǎn)</li>'),在最后一個(gè)li后面新增一個(gè)li(索引為負(fù)數(shù)表示從最后計(jì)起,-1表示最后一個(gè))
table.append('<tr><td></td><td></td><td></td></tr>'),省略第一個(gè)參數(shù)表示在第一個(gè)子對象后面新增節(jié)點(diǎn)- function replace(index,html){}
用html生成的節(jié)點(diǎn)替代調(diào)用對象的指定子對象對應(yīng)的原生DOM節(jié)點(diǎn),index是相對位移
table.replace(2,'<tr><td>新增行</td><td></td><td></td></tr>'),新增一行,并用其替換掉第二行
table.replace(-1,'<tr><td>新增行</td><td></td><td></td></tr>'),新增一行,并用其替換掉最后一行(索引為負(fù)數(shù)表示從最后計(jì)起,-1表示最后一個(gè))- function clean(index){}
該方法用于刪除兄弟節(jié)點(diǎn),index是相對于調(diào)用該方法的對象所處位置的位移
table.clean(),index省略表示刪除第一個(gè)子對象,這里刪除第一行等同于table.map(1).del(0)
table.clean(2),這里表示刪除第三行
table.clean(-2),這里表示刪除最后一行
table.map(0).clean([0,-1,1]),如果index是一個(gè)數(shù)組,那么就是刪除指定索引的子對象,索引為負(fù)數(shù)表示從最后計(jì)起,-1表示最后一個(gè),這里刪除第一個(gè),第二個(gè)以及最后一個(gè)th
table.map(0).clean(0,-1),如果有兩個(gè)參數(shù),表示刪除指定區(qū)間的子對象,索引為負(fù)數(shù)表示從最后計(jì)起,-1表示最后一個(gè),這里刪除第一個(gè)至后一個(gè)元素,參數(shù)大的可以作為第一個(gè)參數(shù),大小順序沒有限制
- 如果新樹的根節(jié)點(diǎn)是table,而其子節(jié)點(diǎn)是tbody/thead/tfoot,由于我們更多時(shí)候不會操作這些節(jié)點(diǎn),而是直接操作tr,所以我做了一個(gè)允許略過這些節(jié)點(diǎn)的處理。當(dāng)然你如果想操作tbody也是可以的,你大可以這樣傳參['tbody thead tfoot','tr','td'];只想取其中一個(gè)的話可以['tbody','tr','td'];直接取tr的話,可以['tr','td'],這種情況會對tbody/thead/tfoot中的所有tr生成新對象
- function sizeOf(){}
結(jié)束語:回過頭想想,有了這么一個(gè)插件之后,節(jié)點(diǎn)操作不就是小菜一碟,之前提到的操作節(jié)點(diǎn)的三大煩惱就迎刃而解了吧。而且這個(gè)插件與任何邏輯無關(guān),不需要二次加工,拿起來就可以用了,遇到無法滿足需求的時(shí)候還可以對其進(jìn)行擴(kuò)展。想象有一天開發(fā)流程好像是拼圖游戲,開發(fā)好的插件經(jīng)過組合,一個(gè)項(xiàng)目就出來,那是多么美妙的事啊??赡芙Y(jié)果并沒有預(yù)期的美好,但是可以預(yù)料得到,向著這個(gè)方向走,事件變得越來越簡單是必然的。因?yàn)槠L了,源碼部分會在下次發(fā)表文章的時(shí)候進(jìn)行詳細(xì)的解講。
- javascript 獲取HTML DOM父、子、臨近節(jié)點(diǎn)
- html dom節(jié)點(diǎn)操作(獲取/修改/添加或刪除)
- Js 獲取HTML DOM節(jié)點(diǎn)元素的方法小結(jié)
- 獲取HTML DOM節(jié)點(diǎn)元素的方法的總結(jié)
- JavaScript操作HTML DOM節(jié)點(diǎn)的基礎(chǔ)教程
- JavaScript DOM節(jié)點(diǎn)操作實(shí)例小結(jié)(新建,刪除HTML元素)
- [js高手之路]HTML標(biāo)簽解釋成DOM節(jié)點(diǎn)的實(shí)現(xiàn)方法
- 如何將HTML字符轉(zhuǎn)換為DOM節(jié)點(diǎn)并動(dòng)態(tài)添加到文檔中詳解
相關(guān)文章
基于Bootstrap實(shí)現(xiàn)Material Design風(fēng)格表單插件 附源碼下載
Jquery Material Form Plugin是一款基于Bootstrap的Material Design風(fēng)格的jQuery表單插件。這篇文章主要介紹了基于Bootstrap的Material Design風(fēng)格表單插件附源碼下載,感興趣的朋友參考下2016-04-04JS表單數(shù)據(jù)驗(yàn)證的正則表達(dá)式(常用)
這篇文章主要介紹了JS表單數(shù)據(jù)驗(yàn)證的正則表達(dá)式,這種方法比較常用,以及使用正則表達(dá)式驗(yàn)證表單的方法,本文給大家介紹非常詳細(xì),需要的的朋友參考下2017-02-02JavaScript中數(shù)組的22種方法必學(xué)(推薦)
這篇文章主要介紹了JavaScript中數(shù)組的22種方法必學(xué)(推薦)的相關(guān)資料,需要的朋友可以參考下2016-07-07JavaScript動(dòng)態(tài)創(chuàng)建link標(biāo)簽到head里的方法
這篇文章主要介紹了JavaScript動(dòng)態(tài)創(chuàng)建link標(biāo)簽到head里的方法,分別介紹了使用jQuery的方法、使用原生javascript方法與IE特有的createStyleSheet方法等,非常具有實(shí)用價(jià)值,需要的朋友可以參考下2014-12-12微信小程序?qū)崿F(xiàn)手勢滑動(dòng)卡片效果
這篇文章主要為大家詳細(xì)介紹了微信小程序?qū)崿F(xiàn)手勢滑動(dòng)卡片效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-08-08Three.js中網(wǎng)格對象MESH的屬性與方法詳解
三維開發(fā)渲染最多的對象大概是網(wǎng)格mesh了,Webgl開發(fā)三維也不例外,下面這篇文章主要給大家介紹了關(guān)于Three.js中網(wǎng)格對象MESH的屬性與方法,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考借鑒,下面來一起看看吧。2017-09-09uni-app小程序中父組件和子組件傳值的實(shí)現(xiàn)實(shí)例
uniapp父子組件引用傳值,和vue的一樣,沒有小程序那樣的麻煩,下面這篇文章主要給大家介紹了關(guān)于uni-app小程序中父組件和子組件傳值的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-08-08javascript 數(shù)組去重復(fù)(在線去重工具)
很多情況下我們需要去掉重復(fù)的內(nèi)容,一般我們都是將很多內(nèi)容放到一個(gè)數(shù)組里面,然后再去重復(fù),這里簡單為大家整理一下2016-12-12Immutable 在 JavaScript 中的應(yīng)用
在 JavaScript 中,對象是引用類型的數(shù)據(jù),其優(yōu)點(diǎn)在于頻繁的修改對象時(shí)都是在原對象的基礎(chǔ)上修改,并不需要重新創(chuàng)建,這樣可以有效的利用內(nèi)存,不會造成內(nèi)存空間的浪費(fèi),對象的這種特性可以稱之為 Mutable,中文的字面意思是「可變」2016-05-05