三个JS小控件

好久没来发文了,惭愧惭愧。主要是因为我自7月份左右将自建的博客弄到了网上,所以一直在自己的博客上写。至于为什么不同时发到,主要是因为我懒……不过,自己的博客建的对SEO很不友好,没人到我博客上,所以我又回到了,哈哈。

废话不多说,今天写的东西是我在做毕设的时候弄出来的,是三个JS插件,分别是 自定义单选框自定义下拉列表自定义日历卡片 。先放出预览图:

三个JS小控件_第1张图片
自定义日历联动菜单
三个JS小控件_第2张图片
自定义下拉列表
自定义单选框-暗色背景
自定义单选框-亮色背景

不要吐槽我的审美……作品链接就放到最底下了,大家可以下下来看看,我做了部分兼容(火狐,chrome,Edge)。另外不准备详细说明做法,更多的是说说想法。

单选框

这个最简单,我的想法是

  • 通过传递的dom元素(其中包含input#radio)来找寻其中的input#radio节点
  • 生成一个元素(如i),用它来替换原radio元素(隐藏原radio)
  • 将原radio中的属性复制到新radio中
  • 添加事件,保证新生成的radio是单选

最后生成的dom,如下面dom节点:

三个JS小控件_第3张图片
radio生成

代码如下:

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') {             
            // 获取上一级节点
            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]);
            // 将节点存储 便于建立事件
            aRadio[j++] = oRadio;
        }
    }   
    for(var i = 0; i < aRadio.length; i++) {
        aRadio[i].index = i;
        // 建立点击事件
        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节点
var oSelect  = dom.getElementsByTagName('select');

然后,循环的去重建select元素。在创建中第一部分,我称为标题,结构如下:

请选择

第二部分就是原来的option,结构如下

  • 游戏1

而新建的option展现内容的获取与自定义的单选框类似,都是将原来dom中的属性复制过来。

最后,重要的是将事件添加上去,保证点击标题展开option,点击option该option被选中

// 下拉图标切换
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');
    });
}

日历

自定义日历控件一开始是采用过程式来写的,后来换成了面向对象的方式。还是简单的说说我的想法,毕竟不是很复杂的东西。

日历的生成主要分成三个部分,年,月,日。年和月的创建比较简单,利用for循环就可以了,然后添加个点击事件,用于获取你选择的年和月。

稍微麻烦的是具体日期的生成,你需要注意本月开始的星期数。

这里对JS的时间对象的应用很重要,否则不仅本月开始的星期数以计算,你还要注意闰平年的问题,而有了时间对象都不是问题。

通过时间对象中的getDay函数可以获取一周是哪一天(0为周末),如果希望知道 2016年11月 从星期几开始,只要传递 2016年11月1日 给时间对象,并利用getDay来获取即可

// 注意JS时间对象月计算是从0开始
var sNowWeek = new Date(2016,10,1).getDay();
console.log(sNowWeek);          // 2

同样的获取每月的具体有多少天,就利用getDate,它返回一个月中某一天:

// 想要返回一月天数,时间对象中天数参数以0代替
var sNowDays = new Date(2016,10,0).getDate();   
console.log(sNowDays);          // 30

获取了一月的天数就可以利用for循环创建了,当然不要忘了添加事件(当时做的时候我是利用for循环一个个添加事件的,现在想来比较蠢,可以用事件委托来完成,以后修改吧……)

附录

自定义下拉列表
自定义日历控件
我的博客,欢迎访问

你可能感兴趣的:(三个JS小控件)