需求需要在原先页面添加一个按钮,触发一个function,如此简单的操作,却无意间发现了一个问题。(还是对html了解的太少)

先看下在菜鸟教程的示例(错误代码)

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>菜鸟教程(runoob.com)</title>
<script src="https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js">
</script>
<script>
function dianji(){
$("input[name='city']:checked").each(function(){
alert($(this).val());
})
}
</script>
</head>
<body>
<form>
<input type='button' id='dianji' onclick='dianji()' value='获取选中的城市'/><br />
<input type='checkbox' name='city' value='北京'/>北京 <br />
<input type='checkbox' name='city' value='上海'/>上海 <br />
<input type='checkbox' name='city' value='天津'/>天津 <br />
<input type='checkbox' name='city' value='重庆'/>重庆 <br />
</form>
</body>
</html>

这个时候点击会出现Uncaught TypeError: dianji is not a function

button元素的id与onclick的函数名字相同 导致方法失效的问题-LMLPHP

为什么会这样呢?一看没啥毛病啊,function是绝对定义的。

button元素的id与onclick的函数名字相同 导致方法失效的问题-LMLPHP

之后可以将框中的代码一出form,变成如下代码

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>菜鸟教程(runoob.com)</title>
<script src="https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js">
</script>
<script>
function dianji(){
$("input[name='city']:checked").each(function(){
alert($(this).val());
})
}
</script>
</head>
<body>
<input type='button' id='dianji' onclick='dianji()' value='获取选中的城市'/><br />
<form>
<input type='checkbox' name='city' value='北京'/>北京 <br />
<input type='checkbox' name='city' value='上海'/>上海 <br />
<input type='checkbox' name='city' value='天津'/>天津 <br />
<input type='checkbox' name='city' value='重庆'/>重庆 <br />
</form>
</body>
</html>

这个时候就正确了,可见是form的问题,原因

form中的input属性的值已经作为当前form的属性了,由于作用域问题,onclick访问的是form的dianji属性而不是外部的函数。

【dianji()会默认传递一个隐性参数this,此时的this代表的是form表单对象,会优先调用表单的属性,即dianji(this),而不是调用window对象的dianji()方法】

解决方法:

  • 修改id名不要与函数名相同
  • onclick="dianji()"改为onclick="window.dianji()"表明是window对象的属性
  • 使用jquery的事件绑定

踩过的坑总结下,共勉

05-11 19:55