JavaScript习题--JQuery事件实现按钮

本文介绍了如何使用JavaScript和jQuery实现一个表单的全选、反选逻辑,以及单选按钮的互斥功能。通过监听事件和修改checkbox的checked属性,实现了当用户操作时,按钮状态和语言选择状态的自动更新。

题目

题目来自廖雪峰的官方网站
对如下的Form表单:

<form id="test-form" action="test">
    <legend>请选择想要学习的编程语言:</legend>
    <fieldset>
        <p><label class="selectAll"><input type="checkbox"> <span class="selectAll">全选</span><span class="deselectAll">全不选</span></label> <a href="#0" class="invertSelect">反选</a></p>
        <p><label><input type="checkbox" name="lang" value="javascript"> JavaScript</label></p>
        <p><label><input type="checkbox" name="lang" value="python"> Python</label></p>
        <p><label><input type="checkbox" name="lang" value="ruby"> Ruby</label></p>
        <p><label><input type="checkbox" name="lang" value="haskell"> Haskell</label></p>
        <p><label><input type="checkbox" name="lang" value="scheme"> Scheme</label></p>
		<p><button type="submit">Submit</button></p>
    </fieldset>
</form>

绑定合适的事件处理函数,实现以下逻辑:
当用户勾上“全选”时,自动选中所有语言,并把“全选”变成“全不选”;
当用户去掉“全不选”时,自动不选中所有语言;
当用户点击“反选”时,自动把所有语言状态反转(选中的变为未选,未选的变为选中);
当用户把所有语言都手动勾上时,“全选”被自动勾上,并变为“全不选”;
当用户手动去掉选中至少一种语言时,“全不选”自动被去掉选中,并变为“全选”。

由于廖雪峰老师的题目中全选全不选按钮使用的是checkbox多选框,我的逻辑有点混乱,因此这里我把题目改成了使用单选按钮。
下面是改为i单选按钮之后的表单html文件:

<form id="test-form" action="test">
        <legend>请选择想要学习的编程语言:</legend>
        <fieldset>
	        <p><a href="#0" class="invertSelect">反选</a></p>
	        <p><label><input name="1" type="radio" class="selectAll" />全选</label><label><input name="1" type="radio" class="deselectAll" />全不选</label></p>
	        <!-- <p><label><input name="1" type="radio" class="deselectAll" />全不选</label></p> -->
	        <p><label><input type="checkbox" name="lang" value="javascript"> JavaScript</label></p>
	        <p><label><input type="checkbox" name="lang" value="python"> Python</label></p>
	        <p><label><input type="checkbox" name="lang" value="ruby"> Ruby</label></p>
	        <p><label><input type="checkbox" name="lang" value="haskell"> Haskell</label></p>
	        <p><label><input type="checkbox" name="lang" value="scheme"> Scheme</label></p>
			<p><button type="submit">Submit</button></p>
    	</fieldset>
</form>

在一个p里面,放置了两个label,分别是“全选”和“全不选”,并把他们的“name”属性设置为一样的值,这样才能实现只选择一个的单选情况。

解答

下面是JS部分的代码:

<script>
    	'use strict';
		var
		    form = $('#test-form'),
		    langs = form.find('[name=lang]'),  //返回的是一个数组,如果查找的东西不存在,他就返回一个[]。!!!!!!!
		    selectAllLabel = form.find('input.selectAll'),
		    deselectAllLabel = form.find('input.deselectAll'),
		    invertSelect = form.find('a.invertSelect');

		// 重置初始化状态:
		form.find('*').show().off();
		form.find(':checkbox').prop('checked', false).off();
		//拦截form提交事件:
		form.off().submit(function (e) {
		    e.preventDefault();
		    alert(form.serialize());
		});
		selectAllLabel.show();
		deselectAllLabel.show();
		selectAllLabel.click(function(){
			langs.prop('checked',true);
		});
		deselectAllLabel.click(function(){
			langs.prop('checked',false);
		});
		invertSelect.click(function() {
			langs.map(function(){
				this.checked = !this.checked;
				if (langs.not(":checked").length == 5){
					deselectAllLabel.prop('checked',true);
				}
				else if (langs.not(":checked").length >= 1){
					deselectAllLabel.prop('checked',false);
				}
				else{
					selectAllLabel.prop('checked',true);
				}
			})
		});
		langs.change(function(){
			if (langs.not(":checked").length == 5){
				deselectAllLabel.prop('checked',true);
				selectAllLabel.prop('checked',false);
			}
			else if (langs.not(":checked").length >= 1){
				deselectAllLabel.prop('checked',false);
				selectAllLabel.prop('checked',false);
			}
			else{
				selectAllLabel.prop('checked',true);
			}
		});
		
    </script>

实现效果:

代码分析

'use strict';

这里是统一标准。

form = $('#test-form'),
		    langs = form.find('[name=lang]'),  //返回的是一个对象数组,如果查找的东西不存在,他就返回一个[]。!!!!!!!
		    selectAllLabel = form.find('input.selectAll'),
		    deselectAllLabel = form.find('input.deselectAll'),
		    invertSelect = form.find('a.invertSelect');

这里使用了jQyery中的find()方法,返回一个jquery对象数组。对象数组:var k = [ { },{ }];d的形式。

form.find('*').show().off();
form.find(':checkbox').prop('checked', false).off();

这里是重置初始化状态。使用find方法,*代表所有的区域。第二行中的冒号代表type类型,即找到所有的type类型为checkbox的分支,也就是那物种语言,然后使用prop方法把他们恩德checked属性设置为false,即为没被选中的状态。
prop()函数的用法:
prop(property)是用来返回属性的值的,比如prop(“checked”);将会返回true或者false。prop(property,value)是用来设置值的,比如prop(“checked”,true);会将checked属性设置为true。

//拦截form提交事件:
		form.off().submit(function (e) {
		    e.preventDefault();
		    alert(form.serialize());
		});

这部分不懂,嘻嘻嘻。

selectAllLabel.show();
deselectAllLabel.show();

这里是设置“全选”和“全不选”这两个按钮为可见状态。不写好像也没啥事。。

selectAllLabel.click(function(){
			langs.prop('checked',true);
		});

这里设置点击全选事件,点击全选按钮之后,将会执行函数,函数里使用prop方法将langs(就是使用jquery查找的五种语言)的checked属性设置为true(勾选状态)。

deselectAllLabel.click(function(){
			langs.prop('checked',false);
		});

原理和上面的一样。

invertSelect.click(function() {
			langs.map(function(){
				this.checked = !this.checked;
				if (langs.not(":checked").length == 5){
					deselectAllLabel.prop('checked',true);
				}
				else if (langs.not(":checked").length >= 1){
					deselectAllLabel.prop('checked',false);
				}
				else{
					selectAllLabel.prop('checked',true);
				}
			})
		});

这里是设置反选,反选代码块要放在langs.change上面,不然就有问题。使用了map高阶函数,直接修改this.checked。这里的this指的是langs。this的用法简单易懂:JavaScript 的 this 原理
下面是一个if else语句,判断lang的未被选中状态的长度,因find为返回值为对象数组,所以可以使用.length来获得长度(反正我是这么理解的)。
如果都没被选,则把全不选按钮打开;如果有1~4个复选框没有被选,就把全不选按钮关闭(全选按钮一直关着呢);如果全都被选择了,即没被选的按钮为0个,就把全选按钮打开。

langs.change(function(){
			if (langs.not(":checked").length == 5){
				deselectAllLabel.prop('checked',true);
				selectAllLabel.prop('checked',false);
			}
			else if (langs.not(":checked").length >= 1){
				deselectAllLabel.prop('checked',false);
				selectAllLabel.prop('checked',false);
			}
			else{
				selectAllLabel.prop('checked',true);
			}
		});

这里是点击五个复选框时的事件处理,逻辑同上。

后记

欢迎大家指出错误和理解不当点的地方!

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值