关于 JS 中 onclick="" 与 $('').on('click',); 区别

有这样的一个函数

function addProduct(obj) {
    console.log(obj);
}

分别有以下这样两种方式操作
第一种

<span class="dab1">+对比</span>

<script>
    $('.dab1').on('click', addProduct);
</script>

第二种

<span onclick="addProduct(this)">+对比</span>

第一种执行的结果如下

clipboard.png

第二种执行方式如下

clipboard.png

为什么执行出来的结果不一样呢? 如何让第二种方法执行的结果和第一种一样.

阅读 11.3k
7 个回答

楼主最好检查一下你的代码。毕竟你那个内联调用的时候传入是this而不是事件对象

如果修改第二个例子的代码成

<span onclick="addProduct(event)">+对比</span>

在chrome里面就会是Event对象的实例了。

但是需要提一下的是,使用jquery的事件监听函数on

$('.dab1').on('click', addProduct);

回调函数的第一个参数得到的不仅仅是Event对象的实例,而是jQuery增强版Event对象的实例。

jQuery为了让所有的浏览器的事件都表现完全一致,是下了不少功夫的。--- 自己实现了一套冒泡,捕捉机制。

同时也给浏览器原有的事件对象做了扩展。

让我们来到源码里找到答案把。

关键的一个函数 fix 函数
把原有的事件对象和jQuery的Event对象的实例做了一次merge。于是后面的事件对象的传递都是加了jQuery.Event补丁的原生事件对象。

如果顺藤摸瓜,找到jQuery.Event.prototype的时候,就会发现原有的stopPropagationpreventDefault都被jQuery重写了。做了有关IE的兼容。

  • 为什么执行出来的结果不一样呢?

因为前者是把原生dom包装过一遍的jQuery对象,而后者是原生的dom对象

  • 如何让第二种方法执行的结果和第一种一样?

function addProduct(obj) {
    // console.log(obj);
    console.log($(obj)) // 用$包一层
}

第一种jQuery对象中调用click,由于在调用的时候没有传入参数,因此参数就是在定义addProduct时的默认参数。也就是我们常见的event。虽然你这里用了obj,只是名字不同而已。

因此运行$('.dab1').on('click', addProduct)会log出来jQuery包装的event对象。

第二种方式传入了this,这里的this就是调用click方法的对象了,这个对象就是span元素本身。因此会log出来span元素。

能一样么,第二种方式this指的span元素,第一种obj指的被包装的event对象。

不明白你要两者一样是什么意思,最好说清你的目的

传入的实参不同肯定obj不同啊,默认不传会有个event事件对象,传了就覆盖了!楼上都说过了,不多解释

执行结果的不同
第一种的执行结果是jQuery的Event对象;第二种的执行结果是dom对象本身。
所使用方式不同
第一种:
jQuery.on是事件注册函数,基于事件监听器,是可以持续对同类型事件进行多次注册的。

$(selector).on(eventType,callback(event){...});//默认传入event对象

第二种:
在HTML中直接定义,
相当于

element.onclick = callback(...){...};

,这种方式是内联事件定义,只针对最后一次定义有效。
两种方式的具体讨论可以参考@cc_andy提供的链接(想给cc_andy投票,却因分数不够无法操作T T)。
如何让两者输出结果一致
将addProduct函数修改为:

function addProduct() {
    console.log(this);//打印触发事件的DOM元素
}
推荐问题
宣传栏