jQuery中嵌套mouseenter函数里this失效问题咨询
为什么嵌套函数里的
this无法正常工作? 这个问题的核心其实是JavaScript里this的指向规则在搞鬼——它可不是一成不变跟着你定义函数的位置走的,而是看这个函数是被谁调用的。
先还原你的场景
假设你的代码结构大概是这样(对应你说的“嵌套mouseenter函数”的情况):
// 不可行版本 $('.article.has-video-thumb').mouseenter(function() { // 外层这个mouseenter回调里的this,确实是当前触发事件的.article元素,这时候用$(this)找元素完全没问题 // 但一旦你在里面嵌套了另一个函数(比如定时器、异步回调或者子元素的事件处理): setTimeout(function() { // 麻烦来了!这里的this已经不是原来的.article了! $(this).find('.video-bg video').get(0).play(); // 此时$(this)指向的是window(浏览器环境下),自然找不到目标video,所以get(0)返回undefined,调用play就会报你看到的错误 }, 100); }); // 可行版本 $('.article.has-video-thumb').mouseenter(function() { setTimeout(function() { // 你直接用$('.article')全局查找,不管当前this指向谁,都能找到目标元素,所以能正常播放 $('.article').find('.video-bg video').get(0).play(); }, 100); });
为什么this会变?
JavaScript里的this绑定规则很直白:
- 当函数作为DOM事件的回调被调用时(比如外层的mouseenter),jQuery会把触发事件的DOM元素(也就是你的.article)作为
this传给回调; - 但如果是嵌套的普通函数(比如定时器回调、匿名回调),它的调用者是全局对象(浏览器里就是
window),所以this会指向window; - 如果嵌套的是子元素的事件回调,
this会指向那个子元素,而不是原来的.article。
这就导致你在嵌套函数里用$(this)时,根本找不到你要的.video-bg下的video元素,自然会报“Cannot read property 'play' of undefined”的错误。
怎么解决这个问题?
给你几个常用的方案,随便挑一个都能解决:
- 在外层保存
this的引用
把外层的.article元素用变量存起来,嵌套函数里直接用这个变量,就不会受this指向变化的影响了:$('.article.has-video-thumb').mouseenter(function() { const $currentArticle = $(this); // 保存当前的.article元素 setTimeout(function() { $currentArticle.find('.video-bg video').get(0).play(); }, 100); }); - 用箭头函数
箭头函数不会绑定自己的this,而是直接继承外层作用域的this,所以嵌套函数用箭头函数的话,this还是原来的.article:$('.article.has-video-thumb').mouseenter(function() { setTimeout(() => { $(this).find('.video-bg video').get(0).play(); }, 100); }); - 用
bind手动绑定this
给嵌套函数绑定外层的this,强制它的指向不变:$('.article.has-video-thumb').mouseenter(function() { setTimeout(function() { $(this).find('.video-bg video').get(0).play(); }.bind(this), 100); // 把外层的this绑定给嵌套函数 });
内容的提问来源于stack exchange,提问作者dungey_140
相关产品推荐
相关产品推荐

