input type为checkbox或radio时的click默认事件

  在input中,如果type为checkbox或radio时,浏览器会将该input渲染成为系统的单选或多选组件,如果这时,我们在这个input上绑定click事件,那就要小心谨慎使用e.preventDefault()这个方法(jQuery中整合了这个方法使得它能够兼容去掉浏览器中的默认事件)。之所以要说谨慎使用,就是,如果你在这个事件的响应程序中判断该checkbox是否选中时,得到的结果和真正的选中状态会有所不同。下面先从一个简单的示例说明这个现象。(为了简单起见,我使用了jquery,他能节省选择器部分的代码,但不影响本文需要说明的问题)。代码段如下:

<script type="text/javascript">
window.onload=function(){
    $(‘#chk‘).on(‘click‘,function(e){
        e.preventDefault();
        alert($(this).attr(‘checked‘));
    });
}
</script>
</head>
<body>
<input type="checkbox" id="chk" />
</body>

  示例很简单,就是在一个checkbox上绑定一个click事件,这个click事件是判断当前的checkbox是否选上了。通过在浏览器上实际运行,结果是,在鼠标点击checkbox的时候,弹出checked。但是关掉alert之后,页面上的checkbox是未选中的状态。我们将这个form提交到后台也是取不到值的。既然没选上,那我们在alert的后面加上这句:$(this).attr(‘checked‘,true);让它选上,刷新下,再点击,你会发现,在我们关闭alert之后,页面上的checkbox仍然是未选中的。问题就在这,我们通过程序选中了checkbox,为什么在响应函数执行完之后,checkbox还是未选中的状态呢?

  为解释这个问题,我们需要修改上面的代码:

window.onload=function(){
    $(‘#chk‘).on(‘click‘,function(e){
        e.preventDefault();
        $(this).attr(‘checked‘,true);
        alert($(this).attr(‘checked‘));
    });
}

上面的代码我们先将设置check为true的语句放到alert前面,运行下看看,当我们点击checkbox时:

  可以看到,在执行完$(this).attr(‘checked‘,true);后到alert时,checkbox的状态是选中的,而且弹出的状态也是checked,也就是说,这个时候,checkbox是选中的。但是为什么我们在点击确定之后,checkbox又变回了未选中了呢?在相应事件结束之后,一定还有什么东西让它改回去了?其实,这是checkbox的默认click事件的做的。也许大家会问,我不是通过e.preventDefault()把默认事件去掉了吗?为什么还有默认事件?难道e.preventDefault()没有生效?

  在这里需要说明下:一般的默认事件,会在我们绑定的响应事件之后执行(这样说不准确,默认事件和自己绑定的响应事件是在一起执行的,只不过,它的真正的作用一般会在所有事件内容做完之后才会体现出来,因此,在这就简单理解成在绑定的事件之后执行吧)。有了这个说明,我们再来说下这个现象。这不是浏览器的bug,也不是没有禁掉默认事件。由于checkbox是系统的组件,因此它的实现机理比较复杂,在这里不讨论,这个问题的主要原因是:checkbox的click事件的默认事件是将修改的选中状态生效。解释一下,如果在鼠标点击之前,checkbox的状态是选中,那么在点击checkbox时,它会将当前的状态取反即取消选中,然后执行响应事件,最后默认事件将这个状态生效。

  上面的这个代码中,由于去掉了默认事件,因此,在执行响应事件时,checkbox确实选中了,alert出来的也是选中的,但是在事件结束时,由于没有没有默认事件,那么这个checkbox就回到了点击之前的状态。我们如果将input写成:<input type="checkbox" id="chk" checked />,即在点击之前就选中它,那么点击之后,checkbox就是选中的状态了。当然,这个选中状态不是因为$(this).attr(‘checked‘,true);造成的,而是没有默认事件,它又重置回之前的状态了。这里我们将代码改成$(this).attr(‘checked‘,false);在执行完之后,仍然会是选中状态的。

  这个问题充分体现出了默认事件的重要性,我们之前去掉过很多默认事件,但是大部分的默认事件如我们想象的那样,去掉之后,基本功能就不存在了。但是checkbox的click默认事件不是让它没有反应,而是将修改后的状态生效(注意:仅仅是click事件,mousedown和mouseup事件是没有这个特点的)。因此,在我们不知道这个问题之前,如果禁掉了它的click事件,就会出现一些问题了。当然,这知识针对checkbox和radio而言。w3c的文档也证实了这一点,它的文档上有明确的说明:

Note: During the handling of a click event on an input element with a type attribute that has the value "radio" or "checkbox", some implementations may change the value of this property before the event is being dispatched in the document. If the default action of the event is canceled, the value of the property may be changed back to its original value. This means that the value of this property during the handling of click events is implementation dependent.

原文地址:http://www.w3.org/TR/DOM-Level-2-HTML/html.html#ID-6043025

再分享一下我老师大神的人工智能教程吧。零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到我们人工智能的队伍中来!https://www.cnblogs.com/captainbed

原文地址:https://www.cnblogs.com/skinchqqhah/p/10184485.html

时间: 2024-11-05 14:52:50

input type为checkbox或radio时的click默认事件的相关文章

CSS input type=&quot;number&quot;出现上下箭头时解决方案

input type="number"时录入内容不可控制,解决方案是在css中添加//火狐input[type=number] {      -moz-appearance:textfield;  } //谷歌input[type=number]::-webkit-inner-spin-button,  input[type=number]::-webkit-outer-spin-button {      -webkit-appearance: none;      margin:

&lt;input type=&quot;file&quot;&gt;图片上传时,先预览

<label> <input type="file" id="upload"> </label> js $("#upload").on('change',function(){ var file = this.files[0]; console.log(this.files); var reader = new FileReader(); //读取文件过程方法 reader.onloadstart = func

input type=&quot;file&quot;文件上传时得到文件的本地路劲

<!DOCTYPE html><html><head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,minimum-scale=1.0,user-scalable=no"> <title>上传图片预览示例

html之常用input type

单选框,用name区分是否为一组,value表示提交时的值,checked表示被勾选 <input type="radio" name="sex" value="man"/ > 多选框,value表示提交时的值,checked表示被勾选 <input type="checkbox" name="hobby" value="sing"/ ><input typ

input type=file 按钮的样式怎么改变?【转】

修改前样式: 这个貌似是不能直接改的,不过可以模拟: <input type=file name=message_img style="display: none;" onchange="ye.value=value" /> <input name=ye value="None file" /> <input type=button value="Select file" onclick=mess

input type=range滑动事件

<input type="range"/>需求:滑动时,计数$.fn.RangeSlider = function(cfg) { this.sliderCfg = { min: cfg && !isNaN(parseFloat(cfg.min)) ? Number(cfg.min) : null, max: cfg && !isNaN(parseFloat(cfg.max)) ? Number(cfg.max) : null, step: c

使用freemarker模板引擎,后台返回的时间格式(datetime类型)无法显示在input type=&quot;text&quot;中显示

详情: 在使用freemarker是,在后台查出user,其中有入职时间entryDate(date类型),当我想要将 entryDate 显示在 <input type="text" value="${user.entryDate}"/>时,出现错误,无法显示 显示页面: 原因: 因为freemarker无法确定用那种格式来显示这个时间 解决办法: 在 <input type="text" value="${user

input type=&quot;file&quot; accept=&quot;image/*&quot;上传文件慢的问题解决办法

相信大家都写过<input type="file" name="file" class="element" accept="image/*"> 默认过滤掉所有非图片文件: 这段代码在Chrome和Safari等Webkit浏览器下却出现了响应滞慢的问题,可能要等 6~10s 才能弹出文件选择对话框.简直不能忍呀. 在IE和Firefox中使用 accept="image/*" 属性则没有发现响应

&lt;input type=&quot;radio&quot; &gt;与&lt;input type=&quot;checkbox&quot;&gt;值得获取

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <%@taglib prefix="s" uri="/struts-tags"%> <!DOCTYPE html> <html> <head> <meta http-equiv="content-