【问题标题】:Javascript code not running inside onload functionJavascript代码未在onload函数内运行
【发布时间】:2016-05-28 01:42:43
【问题描述】:

我想知道为什么这段代码不起作用。当我将它放在 onload 函数中时,它不起作用,我不知道为什么。我在 onload 函数中有很多其他代码,但我已经为这个例子删除了它。无论如何,其他代码都可以正常工作,只有这部分不行。

window.onload = function() {
var i, timer, divide;
i = 0;
divide = 100;

function start() {
    timer = self.setInterval("increment()", (1000 / divide)); 
}

function increment() {
    i++;
    document.getElementById("timer_out").innerHTML = (i / divide);
}

function stop() {
    clearInterval(timer);
    timer = null;
}

function reset() {
    stop();
    i = 0;
    document.getElementById("timer_out").innerHTML = (i / divide);
}

}
<div>
    <span id="timer_out">0</span>
    </br>
    <input type="button" value="Start" onclick="start()"/>
    <input type="button" value="Stop" onclick="stop()"/>
    <input type="button" value="Reset" onclick="reset()"/>
</div>

【问题讨论】:

  • 您检查过您的控制台吗? (按 F12 打开它)。你的答案就在那里。基本上,您的函数需要是全局的才能在您的 onclick 处理程序中访问它们。更好的方法是使用.addEventListener
  • @MikeC 我对此感到困惑,你是什么意思?
  • 基本上@MikeC 想说的是,您的每个按钮的onclick 事件都无法调用其函数,因为您将它们的函数包装在onload 事件中。问题是,您的按钮在其功能声明之前加载。

标签: javascript jquery css


【解决方案1】:

你需要在 onload 范围之外定义你的函数和变量,否则它们是不可访问的。

var i, timer, divide;
function start() {
    if(!timer) {
        timer = setInterval("increment()", (1000 / divide)); 
    }
}

function increment() {
    i++;
    document.getElementById("timer_out").innerHTML = (i / divide);
}

function stop() {
    clearInterval(timer);
    timer = null;
}

function reset() {
    stop();
    i = 0;
    document.getElementById("timer_out").innerHTML = (i / divide);
}
window.onload = function() {
    i = 0;
    divide = 100;
}

如 cmets 中所述,您还有一个错误,如果您多次单击开始,则无法停止计时器。这是因为您正在创建两个(或更多)计时器,但只有最后一个的引用。要解决这个问题,一个简单的if 语句检查是否存在计时器就足够了。上面的代码已更新以显示这一点,下面是它运行的示例:http://jsfiddle.net/qPvT2/40/

【讨论】:

  • @Blindeagle:你的onload 中仍然有它们。 (提示:一致的缩进更容易看到类似的东西。)
  • @Blindeagle 您链接到的代码不包含修复程序。此外,您需要删除self.,因为您没有声明self。最后,避免使用带有setInterval 的字符串。相反,只需写setInterval(increment, 1000 / divide)
  • 仔细观察self 捕获,将其从我的回答中删除
  • @MikeC 你是个美男子!非常感谢您的所有帮助,真的很开心 x
  • 正如@choz 所提到的,您有一个关于多次按下开始按钮的错误。我也更新了我的答案并对此进行了修复。
【解决方案2】:

问题:

  1. onxyz 属性引用的函数必须是全局的。您的函数不是全局函数,因为它们是在您的 onload 处理程序中声明的。有些人会告诉你将它们设为全局,但有更好的答案。

  2. onload 几乎可以肯定比您真正希望运行此代码要晚得多。例如,它会等到所有图像都完全下载完毕。

  3. setTimeout/setInterval 中使用字符串通常不是一个好主意。

  4. &lt;/br&gt; 是无效的 HTML。在 HTML 中,br 元素写成 &lt;br&gt;。你也可以写成&lt;br/&gt;&lt;br /&gt; 如果你愿意,但是/ 在HTML 中是没有意义的。 (它在 XHTML 中有意义。)

  5. 无需在setTiemout/setInterval 前加上self.。它工作,因为有一个默认的self 全局,但它是不必要的。

  6. 如果您单击两次start,您将覆盖前一个计时器的句柄并且无法停止它。我们需要在开始之前致电stop

请参阅 cmets,了解我如何解决以下问题。

没有 jQuery(因为你标记了它,但似乎没有使用它)

// This script is at the end of the HTML, just beofre the closing
// </body> tag, ands o all the elements defined by the HTML above it
// will be there and ready for us to handle. No need for `onload`.
// But we'll use a scoping function to avoid creating globals.
(function() {
  var i, timer, divide;

  // Hook up our buttons.
  // For a very simple thing like this, we can just assign to 
  // their onclick properties, but for anything more complicated
  // I'd use addEventListener (falling back to attachEvent if
  // the browser doesn't have addEventListener, to support obsolete
  // IE like IE8), but that's overkill for this small example.
  document.querySelector("input[value=Start]").onclick = start;
  document.querySelector("input[value=Stop]").onclick = stop;
  document.querySelector("input[value=Reset]").onclick = reset;
  
  i = 0;
  divide = 100;
  timer = 0; // A value we can safely pass to clearInterval
             // if we never set anything else

  function start() {
    // Make sure to stop any previous timer
    stop();
    
    // Note no quotes or (), we're passing a reference to the
    // increment function into `setInterval`.
    // Also no need for `self.`
    timer = setInterval(increment, (1000 / divide));
  }

  function increment() {
    i++;
    document.getElementById("timer_out").innerHTML = (i / divide);
  }

  function stop() {
    clearInterval(timer);
    timer = null;
  }

  function reset() {
    stop();
    i = 0;
    document.getElementById("timer_out").innerHTML = (i / divide);
  }

})();
<div>
  <span id="timer_out">0</span>
  <br>
  <input type="button" value="Start" />
  <input type="button" value="Stop" />
  <input type="button" value="Reset" />
</div>

有关addEventListener/attachEvent 的更多信息以及如果您需要支持过时的浏览器可以使用的功能,see this answer

使用 jQuery(因为你确实标记了它)

// This script is at the end of the HTML, just beofre the closing
// </body> tag, ands o all the elements defined by the HTML above it
// will be there and ready for us to handle. No need for `onload`.
// But we'll use a scoping function to avoid creating globals.
(function() {
  var i, timer, divide;

  // Hook up our buttons.
  $("input[value=Start]").on("click", start);
  $("input[value=Stop]").on("click", stop);
  $("input[value=Reset]").on("click", reset);
  
  i = 0;
  divide = 100;
  timer = 0; // A value we can safely pass to clearInterval
             // if we never set anything else

  function start() {
    // Make sure to stop any previous timer
    stop();
    
    // Note no quotes or (), we're passing a reference to the
    // increment function into `setInterval`.
    // Also no need for `self.`
    timer = setInterval(increment, (1000 / divide));
  }

  function increment() {
    i++;
    $("#timer_out").text(i / divide);
  }

  function stop() {
    clearInterval(timer);
    timer = null;
  }

  function reset() {
    stop();
    i = 0;
    $("#timer_out").text(i / divide);
  }

})();
<div>
  <span id="timer_out">0</span>
  <br>
  <input type="button" value="Start" />
  <input type="button" value="Stop" />
  <input type="button" value="Reset" />
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

【讨论】:

  • 和miller的回答一样,点击start两次就停不下来了。
  • @choz:谢谢!固定。
  • 啊,没看到这个问题,如果你知道有什么办法可以解决,请告诉我
  • @Blindeagle:现在已在答案中修复(点击刷新以防万一)。
  • 现在更像了。
【解决方案3】:

而不是在 window.onload 中编写您的函数.. 只需将它们写在它之外...当您在 window.onload 函数中编写它们时,它们无法访问...只需将它们写在外面,您的代码就会正常运行

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-05-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-28
    • 2021-10-14
    • 2020-05-04
    相关资源
    最近更新 更多