前端冷门坑(一)表单
诚如标题所言,此处要提及的坑都非常冷门,这主要是因为它们本身很难被遭遇到,且实际的价值也不高所致。只不过我却在不期的机缘巧合之下与它们相逢,本次出场的几位分别是:
1、form标签中的表单元素的id/name不能与该form下的onclick等事件函数同名1)form标签中的表单元素的id/name不能与该form下的onclick等事件函数同名
2)IE下的item
3)选择器(即input[type=checkbox]和input[type=radio])的click、change事件的触发顺序
网页中一个form标签嵌套了一个按钮,按钮绑定了一个onclick事件,当点击按钮时控制台报错,看到错误后,我的第一反应是在控制台访问了下Test函数,发现输出正常:
之后经过很多网络搜索(太难搜了,毕竟这个错误跟普通的未定义函数一模一样)和测试之后,终于对这个把戏有了一点粗浅的认识。首先要清楚两点:
1)浏览器在解析网页时,会自动为form表单创建一个对象,同时把该表单内部的表单元素(是表单元素哦<如input、textarea>,div什么的不行)作为键值对挂载到form表单对象上,键值对的键名是该元素的id或name,键值为该元素本身。
2)当表单元素上绑定的事件被触发时,不仅事件是有冒泡机制,元素在寻找绑定的函数名时也是采用类似的方式向外一层一层去找,首先它会在外层的form对象上找,如果没有,才冒泡到window对象上去找。
知道了上述两点后,事情就明了了,因为代码中的input标签的id是“Test”,与onclick绑定的函数名相同,所以当点击input触发事件时,input向外层寻找Test这个变量,然后在form上找到了,只可惜form上这个Test是个DOM元素而不是用户想触发的那个函数。
知道了原理,那接下来的事情就简单了,又经过一番测试后,大致摸清了一些套路:
2、IE下的item1)绑定事件的表单元素必需隶属于某个form元素才会触发错误,如果将上文中的form标签改成div,则不会出错;
注:通过form属性指向的也算“隶属于”。<form id="Form"> </form> <input type="button" id="Test" value="button" onclick="Test()" form="Form" >
2)只有在html中使用onclick这种方式绑定事件才会发生上述错误,如果是在js中绑定事件是不会出错的。
var Test=function(){console.log('Test');}; var inputObj=document.getElementById("Test"); inputObj.onclick=Test;
自入坑前端以来,item这个变量名见的实在太频繁,以至于我从未怀疑过用它做变量名会有什么风险。直到有一次——
某年某月的某一天,我在某个函数中创建了一个变量名为item的变量,但却没有在函数开头进行变量声明(也有可能是后来误删了,记不清了),所以污染到全局。因为其它地方没再用到这个变量名,所以貌似这并不会引发什么不得了的错误。
但是,在后续测试中,IE浏览器(11及其以下版本)中发现网页无法正常打开,且没有明确的报错。于是只好逐条代码试错,最后发现了这个item,经过一番测试发现它有如下图所示的一些现象。
但我在网上搜索后并没有找到相关联的说法,只查到IE中form表单自带了个同名方法(formname.item("username")),貌似是同一个东西,只是宿主对象从form变成了window(也是类似全局污染的产物?)。
之后又测试发现Edge的form表单也有item方法,但并无此全局变量。
注:当然其它标签元素我也试过了,没有挂这个东西。
3、选择器的click、change事件的触发顺序某天,老板要求在页面中加一些选择性的表单内容,点击选择器时会触发一些操作。当时因为懒所以就直接从附近代码中拷贝来了一个绑着click事件的按钮加以改造,然后没细想就只改了type和事件函数名,接着就撂在一边做其他的了。
界面如下:
局部代码:
<input type="radio" value="正常" v-model="RecordParams[26].HP0" @click="RadioLinkage('HP0')"> 正常
中间过了许久,最后在测试时,问题出现了:代码在FireFox下的逻辑表现非常混乱,其它浏览器符合预期。
经过一番检查和测试,知道是click惹的事儿,换成change事件便可解决问题。但为什么此处二者不能互相替换使用?原因是各浏览器在处理click和change事件上有所差异,具体情况如下:
1)input[checkbox|radio]触发click与change事件的顺序
先触发change再触发click:【IE、Safari】
先触发click再触发change:【Chrome、FireFox、Opera】
但只从上述所列的触发顺序上还是难窥端倪,因为两个阵营都不止一名队员,奈何单单FireFox出错,同一阵营中的Chrome和Opera又是怎么回事?这就引出下一个发现。
2)input[checkbox|radio] 的勾选状态并没有跟change事件捆绑在一起,当click和change事件触发时,我将选框的状态打印出来,情况如下:
IE、Safari、Chrome、Opera 两个事件打印出来的值均是改变后的新值,唯有 FireFox 在click触发时为旧值,change触发时才变成新值。
想来想去,感觉其实FireFox的表现最合理,而Chrome、Opera的表现最奇怪。
共同学习,写下你的评论
评论加载中...
作者其他优质文章