You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用setTimeout丢失上下文,背景切换脚本setTimeout失效求助

Hey there! Let's break down what's going wrong with your script and fix that setTimeout issue step by step.

First: Fix the Initialization Bug

Your current code has a critical mistake in how you're setting up the init function:

$(document).ready(function() { window.onload = Main.init(); });

When you add () to Main.init, you're immediately running the function instead of assigning it as the window.onload handler. Plus, using both $(document).ready() and window.onload is redundant here—jQuery's ready fires as soon as the DOM is ready (which is all you need for a button click handler). Let's simplify that:

$(document).ready(function() {
  Main.init();
});

// Or even more concise:
// $(document).ready(Main.init);

The Big Issue: this Binding in setTimeout

The main reason your setTimeout isn't working is almost certainly a this scope problem. Inside the each loop, when you pass a regular function to setTimeout, this will point to the global window object instead of the <div> element you're trying to target.

Here's a complete, fixed version of your script (I filled in the missing parts of your chBackground function):

var Main = {
  init: function() {
    // Bind `this` so `chBackground` has access to the Main object if needed
    $('#button').click(this.chBackground.bind(this));
  },
  chBackground: function() {
    $('#r1 > div').each(function(index) {
      // Store the current div in a variable to preserve its reference
      const $currentDiv = $(this);
      
      // Switch to your custom background
      $currentDiv.css('backgroundColor', '#ff4444'); // Replace with your custom color
      
      // Set timeout to revert to default—stagger timing with index if desired
      setTimeout(function() {
        $currentDiv.css('backgroundColor', '#ffffff'); // Replace with your default color
      }, 1000 * index); // Adjust delay; multiplying by index makes each div revert one after another
    });
  }
};

Why This Works

  • We save the current <div> to a $currentDiv variable inside the each loop. This creates a closure that keeps the reference to the specific div alive when setTimeout runs later.
  • If you prefer modern JS, you could use an arrow function in setTimeout instead—arrow functions inherit the this value from their surrounding scope, so $(this) would still point to the current div:
    setTimeout(() => {
      $(this).css('backgroundColor', '#ffffff');
    }, 1000 * index);
    

Pro Tip: Use CSS Classes Instead of Inline Styles

For cleaner, more maintainable code, avoid hardcoding colors in JavaScript. Define CSS classes instead:

.default-bg {
  background-color: #ffffff;
}
.highlight-bg {
  background-color: #ff4444;
}

Then update your script to use class toggles:

$currentDiv.addClass('highlight-bg');
setTimeout(() => {
  $currentDiv.removeClass('highlight-bg').addClass('default-bg');
}, 1000 * index);

内容的提问来源于stack exchange,提问作者linearSpin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 07:54:15