【发布时间】:2021-07-30 07:36:58
【问题描述】:
我一直在尝试了解如何(在 jQuery 中)使用 $(this) 作为 setInterval/setTimeOut 函数中的起点来遍历 DOM,并且遇到了一些我觉得莫名其妙的行为。
似乎不可能使用 $(this) 作为 setInterval/setTimeOut 函数内的起点来遍历 DOM
为什么会这样?
jQuery/javaScript 人 - 开始吧。
用于说明行为的示例代码:
jQuery:
// 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(上/下/横向)似乎是不可能的?
还有哪些可能的黑客/变通方法/等。对于这种行为?
黑客/变通办法/等的可能非解决方案。
this answer 使用 $.proxy 仅在您使用旧版本的 jQuery 时才有效 - 但由于 as this document attests 'This API has been deprecated in jQuery 3.3'... 目前这不是一个解决方案。
bind 方法也不是,因为文档证明“从 jQuery 3.0 开始,.bind() 已被弃用”并被 on 方法取代(但我看不出我将如何使用.on() 在这里有任何效果 - 但也许这只是因为我缺乏想象力)。
【问题讨论】:
-
请向我们展示出现问题的实际代码。您已经向我们展示了很多代码,但实际上没有一个在
setTimeout中包含this。如果您没有实际向我们展示过代码,那么很难向您展示如何修正您的代码。 -
我试着让它更通用,因为这种行为让我感到困惑,我想要更通用的基本解释来解释为什么它没有按预期工作(在下面接受的答案+获取实际代码的用例工作)但这就是为什么提供更通用的代码(哦,它是 setInterval 而不是 setTimeout - 尽管我怀疑两者的答案是相同的):) - 但根据建议,在问题中添加了一个编辑
标签: javascript jquery dom setinterval dom-traversal