提问人:thothlike 提问时间:5/8/2021 最后编辑:thothlike 更新时间:5/10/2021 访问量:89
jQuery 在 setInterval/setTimeOut 函数中使用 $(this) 作为起点遍历 DOM?
jQuery traversing the DOM using $(this) as a starting point inside setInterval/setTimeOut function?
问:
我一直在试图了解如何(在jQuery中)使用$(this)作为setInterval / setTimeOut函数中的起点遍历DOM,并遇到了一些我发现令人困惑的行为。
似乎不可能在 setInterval/setTimeOut 函数中使用 $(this) 作为起点遍历 DOM
为什么?
jQuery/javaScript 人 - 继续吧。
用于说明行为的示例代码:
j查询:
// set this code anywhere (inside/outside - document.ready/named-function/...) and run it
var autoTimer = setInterval(function(){
// INSERT EXAMPLE TEST-CODE FROM BELOW HERE
}, 10000)
尝试的测试代码:
// from inside the setInterval/setTimeOut function above
// if $(this)
if($(this).length !== 0) {
alert('hello');
} // alerts hello
// from inside the setInterval/setTimeOut function above
// if html-tag (body/head/html)
if($('body').length !== 0) {
alert('hello');
} // alerts hello
// from inside the setInterval/setTimeOut function above
// if className
if($('.className').length !== 0) {
alert('hello');
} // alerts hello
// from inside the setInterval/setTimeOut function above
// if id
if($('#id').length !== 0) {
alert('hello');
} // alerts hello
因此,它可以很好地找到文档中的特定元素,除了 $(this) 之外,您还可以从那里遍历 DOM
即。
// from inside the setInterval/setTimeOut function above
if ($('.className').find(something).length !== 0)... // works just fine
当您想使用 $(this) 作为遍历的起点时,问题就来了
遍历测试代码尝试使用 $(this) 作为起点:
// from inside the setInterval/setTimeOut function above
// traversing up the DOM
if($(this).parents('body').length !== 0) {
alert('hello');
} // no alert (same with closest/parentsUntil/etc up the DOM)
// from inside the setInterval/setTimeOut function above
// traversing sideways in the DOM
if($(this).siblings('body').length !== 0) {
alert('hello');
} // no alert (same with next/prev/etc sideways in the DOM)
// from inside the setInterval/setTimeOut function above
// traversing down the DOM
if($(this).find('body').length !== 0) {
alert('hello');
} // no alert (same with children down the DOM)
因此,从 $(this) 'body'(或其他任何与此相关的内容)开始似乎在任何地方(向上/向下/横向)都不存在,从上面的任何其他起点来看都是不正确的
我还尝试使用命名的全局函数,如下所示:
// set outside/inside document.ready
function testCode() {
// INSERT EXAMPLE TRAVERSING TEST-CODE FROM ABOVE HERE
}
// set this code anywhere (inside/outside - document.ready/named-function/...) and run it
var autoTimer = setInterval(testCode, 10000) // no alert
// set this code anywhere (inside/outside - document.ready/named-function/...) and run it
var autoTimer = setInterval(function(){
testCode();
}, 10000) // no alert
因此,再次重申我的问题:
为什么在jQuery中似乎不可能使用$(this)作为起点在setInterval / setTimeOut中遍历DOM(向上/向下/横向)?
对于这种行为,有哪些可能的黑客/变通方法/等?
黑客/变通方法/等可能的无解决方案。
这个使用 $.proxy 的答案仅在您使用旧版本的 jQuery 时才有效 - 但由于本文档证明“此 API 已在 jQuery 3.3 中弃用”......目前,这不是一个解决方案。
绑定方法也不是,因为正如文档所证明的那样,“从 jQuery 3.0 开始,.bind() 已被弃用”并被 on 方法取代(但我看不出我如何在这里使用 .on() 产生任何效果 - 但也许这只是由于我缺乏想象力)。
答:
这是一个基本的范围问题,与jQuery关系不大。this
最直接的方法是将回调之外的另一个变量赋值:this
var that = this;
setInterval(function () {
$(that).parents();
}, 1000);
如果你不关心 IE,或者你有一个构建过程,你可以使用箭头函数,它使用从它外部的作用域:this
setInterval(() => {
$(this).parents();
}, 1000);
我个人的偏好是完全避免使用,因为它的所有鹦鹉行为都给你带来了如此多的悲伤。从您的示例中尚不清楚您的价值来自哪里,但这里有一些方法可以避免它:this
this
// inside .each()
$('a').each(function (_, el) {
$(el).parents();
});
// inside event handler
$('a').on('click', function (event) {
$(event.target).parents();
});
评论
this
setTimeout