作者s25g5d4 (死城盗贼)
看板Ajax
标题Re: [问题] jquery attr onclick IE7 & 8
时间Sat Jan 29 22:20:40 2011
屋 其实我也被打过脸 说真的出来说嘴只是想赚文章数这样
※ 引述《sk1765 (鼎玉铉)》之铭言:
: ※ 引述《gaekeamql (芋头)》之铭言:
: : 问一下
: : <input type="button" id=1 onclick="alert('001122');" value="alert">
: : <input type="button" onclick="$('#1').attr('onclick','');" value="C">
: : <input type="button" onclick="$('#1').attr('onclick','alert(\'334455\');');"
: : value="RE">
: : 此动作在OPREA OK 但是在IE 清除候 再输入
: : $('#1').attr('onclick','alert(\'001122\');'); 却是没反应的
: : 但是 是有把 oncilck="alert('334455');" 写进去 但是不会动作
: attr()这个方法 应该是用W3C DOM的属性方法 setAttribute()写成的
: 在ppk on Javascript一书第8-G节 有详细的警告 我把它节录如下:
: ------------------------------------------------------------
: 很多HTML标签用特定的属性去保存行内样式(inline style)和
: 行内事件处理常式(inline event handler)如 onclick,onkeydown等
: 在IE中,这些属性不能透过getAttribute()和setAttribute()来读写;
: 事实上,如果你尝试这麽做你会遇到怪异的bug
: 解决的办法是使用Javascript属性(Javascript property)
: style,onclick,onkeydown等来读写这些属性
: 为了完全明白这一点,先来探讨 HTML属性(HTML attributes) 和
: javascript 属性(javascript property)有何区别
: 至於 HTML属性(HTML attributes) 和 javascript 属性(javascript property)
: 以及属性映射 我就不打了
: 麻烦请自行参阅ppk on Javascript中文版8-G 图书馆就有
: 全部打字太累了把 读写属性的最佳方式 看完你就会了解啦
: ------------------------------------------------------------
以上应该是没错 (吧)
: 以下是解答
: <input type="button" id="id1" onclick="alert('001122');" value="alert">
: <input type="button" onclick="$('#id1').onclick=function(){};" value="C">
: <input type="button" onclick="$('#id1').onclick=function() {
: alert('334455'); }" "value="RE">
这里取出来的是jQuery物件 不能直接套上.onclick属性
很多很方便取出HTML物件的framework都会直接包成一个特定的Object
因为你不可能在HTML Node上新增如.attr()等的属性、函式
所以jQuery就将他打包成jQuery物件 使它可以支援一堆功能
然而有时总是会遇到必须取得原始Node的情况
这时只要把它当作一个阵列 也就是jQuery把match到的所有node都存入这个阵列中
所以要取得第一项就是$(selector)[0]这样
不过这边称他为阵列也不太对 应该说是物件 或说关联阵列
javascript在这边本来就是有着复杂的关系
jQuery本身程式码 因为小弟才疏学浅没有研究
所以也不知道到底是哪种 不过应该是物件没错...
所以这边正确写法是$('#id1')
[0].onclick=function(){};
如果很不幸的 match到不只一个 而且必须每个元件都要执行後面的动作
那就刚好可以呼叫jQuery内建的.each()函式
$(selector).each(function(i, obj) {
...
传进来的obj就是原始的Node 不是jQuery物件 所以可以直接呼叫.onclick属性
i是代表第几项
)
: 不用famework直接写如下
: <input type="button" id="id1" onclick="alert('001122');" value="alert">
: <input type="button" onclick="document.getElementById('id1').
: onclick=function() {};" value="set onclick null">
: <input type="button" onclick="document.getElementById('id1').
: onclick=function() { alert('334455'); }" value="set new onclick">
: 也就是直接用Javascript property映射就好啦
: 不能用W3C的方法
: 在inline event handler里写 匿名函式要注意会形成closure的效果 请小心使用
: <input id="btn1" type="button" onclick="document.getElementById('id1').
: onclick=function () {
: alert('334455');
: }"
: value="set new onclick">
拍谢 这里我也看不懂...
: 翻回传统注册法就会变成
: var x = document.getElementById('btn1');
: x.onclick = function () {
: document.getElementById('id1').onclick = function () {
: alert('334455');
: }
其实这样跟行内注册没啥差耶... 只有美丑的差别而已
正确来说应该呼叫W3C的addEventListener
然後要删掉就要呼叫removeEventListener
当然匿名函式要怎麽删掉是个问题
所以应该这样写
var obj = document.getElementById('id'),
f = function () { alert('test'); };
obj.addEventListener('click', f, true);//第三个参数是要不要触发上一层Node的事件
obj.removeEventListener('click', f, true);
范例:
http://jsfiddle.net/5DgfQ/1/
忘了说...这里有浏览器相容性问题 至於是哪款..大家都知道我就不搬出来鞭了
: }
: --------------------------------------------
: 另外在jQuery中使用
: $('#id1')[0].click(function(){
: alert('334455');
: });
: $('#id1')[0].bind('click', function(){
: alert('334455');
: });
都说将元素取出阵列就不是jQuery物件了 当然无法呼叫.click()或.bind()
: 这些都是利用进阶模式 注册事件
: 也就是透过addEventListener 和 attachEvent完成的
: 这两者的第一个参数都是事件名称系结 事件名称在javascript中和
: javascript property的使用又不相同 利用这两者具有附加的效果而非取代效果
: 所以在取消时 必须用 unclick ,unbind 否则新的click只是附加动作
: 同时利用进阶模式来取消 无法移除传统注册以及行内注册事件
: <input type="button" id="id1" onclick="alert('001122');" value="alert">
: <input type="button" onclick="$('#id1')[0].unclick();" value="C"> //->不生效?
阿又没有unclick可以让你叫...
应该要用unbind
jQuery API Refrence:
http://api.jquery.com/unbind/
用法差不多同上
范例:
http://jsfiddle.net/5DgfQ/2/
不过对於onclick行内注册绑上去的function 是不能透过.unbind()去掉的
至少我刚刚试是这样
: <input type="button" onclick="$('#id1')[0].click(function(){alert('334455');});"
: value="RE"> //->无法附加event handler?
: <input type="button" onclick="$('#id1')[0].click(function(){});" value="C">
: 应该是不行的 因为他是附加动作不是覆盖动作
: 同时在jQuery中使用 $('#id1')[0].click(); 很容易让人迷惘
: 因为在javascript中 他明明是 事件模拟(event simulation)
: 但是到了Jquery中变成系结方法
: 所以如果不传参数 是否就是事件模拟
: 而他的事件模拟 是否有修正javascript中只对表单栏位动作的问题则不确定
: 结论 行内注册建议还是用javascript property mapping的方式来取代原来的handler
--
1F:→ s25g5d4:五楼是甲甲 12/11 19:59
2F:→ s25g5d4:我..推错篇了 12/11 19:59
3F:→ sherwinc:XD12/11 19:59
4F:→ pp1877:喔XD12/11 20:00
5F:推 victory55:5楼甲甲喜欢拿按摩棒自己搓自己小菊花12/11 20:01
6F:→ victory55:........可以修文吗12/11 20:01
--
※ 发信站: 批踢踢实业坊(ptt.cc)
◆ From: 59.116.108.169
addEventListener後面注解打错了 应为第三个不是第二个...
※ 编辑: s25g5d4 来自: 59.116.108.169 (01/29 22:26)
另外说明一下为甚麽不能写obj.onclick = f(a,b);
当浏览器读取到f时他会认得他是一个function
之後接上()造成他被触发(执行) 所以到那边不管三七二十一都会跑一次
然後勒? onclick绑上去的将会是f(a,b)的传回值
如果很不幸的 传回的是null 那就是onclick没有绑任何东西上去
一个简单的范例就是
var f=function () {
alert('test');
return function () {alert('test2');};
};
obj.onclick = f();
obj2.onclick = f;
http://jsfiddle.net/5DgfQ/3/
※ 编辑: s25g5d4 来自: 59.116.108.169 (01/29 22:34)
※ 编辑: s25g5d4 来自: 59.116.108.169 (01/29 22:44)
夭寿...each的参数写反了
※ 编辑: s25g5d4 来自: 59.116.108.169 (01/30 00:24)