三个JS小控件

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

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

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

单选框

这个最简单,我的想法是

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

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

代码如下:

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元素。在创建中第一部分,我称为标题,结构如下:

<div class="title" value="">
    <em>请选择</em>
    <i class="iconfont icon-xiala"></i>
</div>
复制代码

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

<div class="option">
    <ul class="option_ul">
        <li value="1">游戏1</li>
        <!-- 更多的li -->
    </ul>
</div>
复制代码

而新建的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循环一个个添加事件的,现在想来比较蠢,可以用事件委托来完成,以后修改吧……)

附录

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

转载于:https://juejin.im/post/5a30f2d96fb9a045023ba1c5

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值