好久沒來簡(jiǎn)書發(fā)文了,慚愧慚愧。主要是因?yàn)槲易?月份左右將自建的博客弄到了網(wǎng)上,所以一直在自己的博客上寫。至于為什么不同時(shí)發(fā)到簡(jiǎn)書,主要是因?yàn)槲覒小贿^,自己的博客建的對(duì)SEO很不友好,沒人到我博客上,所以我又回到簡(jiǎn)書了,哈哈。
廢話不多說,今天寫的東西是我在做畢設(shè)的時(shí)候弄出來的,是三個(gè)JS插件,分別是 自定義單選框 , 自定義下拉列表 , 自定義日歷卡片 。先放出預(yù)覽圖:




不要吐槽我的審美……作品鏈接就放到最底下了,大家可以下下來看看,我做了部分兼容(火狐,chrome,Edge)。另外不準(zhǔn)備詳細(xì)說明做法,更多的是說說想法。
單選框
這個(gè)最簡(jiǎn)單,我的想法是
- 通過傳遞的dom元素(其中包含
input#radio)來找尋其中的input#radio節(jié)點(diǎn)- 生成一個(gè)元素(如
i),用它來替換原radio元素(隱藏原radio)- 將原radio中的屬性復(fù)制到新radio中
- 添加事件,保證新生成的radio是單選
最后生成的dom,如下面dom節(jié)點(diǎn):

代碼如下:
function selfRadio(dom) {
// 該dom元素不存在
if(typeof dom == 'undefined' || dom.length == 0) return false;
// 獲取該dom下面的input#radio元素
var oInput = dom.getElementsByTagName('input');
var aRadio = [];
for (var i = 0,j=0; i < oInput.length; i++) {
if(oInput[i].getAttribute('type') == 'radio') {
// 獲取上一級(jí)節(jié)點(diǎn)
var oParNode = oInput[i].parentNode;
// 采用i作為新的input#radio
var oRadio = document.createElement('i');
oRadio.setAttribute('name' , oInput[i].getAttribute('name'));
oRadio.setAttribute('value' , oInput[i].getAttribute('value'));
oRadio.setAttribute('class' , 'selfradio');
// 隱藏原來的input#radio
oInput[i].style.display = 'none';
// 插入到web中
oParNode.insertBefore(oRadio , oInput[i]);
// 將節(jié)點(diǎn)存儲(chǔ) 便于建立事件
aRadio[j++] = oRadio;
}
}
for(var i = 0; i < aRadio.length; i++) {
aRadio[i].index = i;
// 建立點(diǎn)擊事件
aRadio[i].addEventListener('click' , function() {
for (var i = 0; i < aRadio.length; i++) {
if(i != this.index) {
aRadio[i].setAttribute('class' , 'selfradio');
}
}
aRadio[this.index].setAttribute('class' , 'selfradio change');
});
}
}
下拉列表
通過傳遞的dom元素,找出該dom下所有的select元素
// 獲取select節(jié)點(diǎn)
var oSelect = dom.getElementsByTagName('select');
然后,循環(huán)的去重建select元素。在創(chuàng)建中第一部分,我稱為標(biāo)題,結(jié)構(gòu)如下:
<div class="title" value="">
<em>請(qǐng)選擇</em>
<i class="iconfont icon-xiala"></i>
</div>
第二部分就是原來的option,結(jié)構(gòu)如下
<div class="option">
<ul class="option_ul">
<li value="1">游戲1</li>
<!-- 更多的li -->
</ul>
</div>
而新建的option展現(xiàn)內(nèi)容的獲取與自定義的單選框類似,都是將原來dom中的屬性復(fù)制過來。
最后,重要的是將事件添加上去,保證點(diǎn)擊標(biāo)題展開option,點(diǎn)擊option該option被選中
// 下拉圖標(biāo)切換
oSelfTitle.addEventListener('click' , function() {
oSelfSelect.setAttribute('class' , 'selfselect auto');
oSelfIcon.setAttribute('class' , 'iconfont icon-xiala-copy');
});
// 下拉列表選擇
var oLi = oSelfUl.getElementsByTagName('li');
for (var i = 0; i < oLi.length; i++) {
oLi[i].index = i;
oLi[i].addEventListener('click' , function() {
oSelfSelect.setAttribute('value' , oLi[this.index].getAttribute('value'));
oSelfText.innerHTML = oLi[this.index].innerHTML;
oSelfSelect.setAttribute('class' , 'selfselect');
oSelfIcon.setAttribute('class' , 'iconfont icon-xiala');
});
}
日歷
自定義日歷控件一開始是采用過程式來寫的,后來?yè)Q成了面向?qū)ο蟮姆绞?。還是簡(jiǎn)單的說說我的想法,畢竟不是很復(fù)雜的東西。
日歷的生成主要分成三個(gè)部分,年,月,日。年和月的創(chuàng)建比較簡(jiǎn)單,利用for循環(huán)就可以了,然后添加個(gè)點(diǎn)擊事件,用于獲取你選擇的年和月。
稍微麻煩的是具體日期的生成,你需要注意本月開始的星期數(shù)。
這里對(duì)JS的時(shí)間對(duì)象的應(yīng)用很重要,否則不僅本月開始的星期數(shù)以計(jì)算,你還要注意閏平年的問題,而有了時(shí)間對(duì)象都不是問題。
通過時(shí)間對(duì)象中的getDay函數(shù)可以獲取一周是哪一天(0為周末),如果希望知道 2016年11月 從星期幾開始,只要傳遞 2016年11月1日 給時(shí)間對(duì)象,并利用getDay來獲取即可
// 注意JS時(shí)間對(duì)象月計(jì)算是從0開始
var sNowWeek = new Date(2016,10,1).getDay();
console.log(sNowWeek); // 2
同樣的獲取每月的具體有多少天,就利用getDate,它返回一個(gè)月中某一天:
// 想要返回一月天數(shù),時(shí)間對(duì)象中天數(shù)參數(shù)以0代替
var sNowDays = new Date(2016,10,0).getDate();
console.log(sNowDays); // 30
獲取了一月的天數(shù)就可以利用for循環(huán)創(chuàng)建了,當(dāng)然不要忘了添加事件(當(dāng)時(shí)做的時(shí)候我是利用for循環(huán)一個(gè)個(gè)添加事件的,現(xiàn)在想來比較蠢,可以用事件委托來完成,以后修改吧……)