异步JavaScript回调

news/2024/7/19 14:05:40 标签: javascript, js, java, html, php
htmledit_views">

Ah, asynchronous JavaScripts. Love 'em, hate 'em, but you gotta use them!

嗯,异步JavaScript。 爱他们,恨他们,但您必须使用它们!

I have quite a few posts here on this blog about this stuff. Starting with something I considered an interesting hack to emulate PHP's require(). This was posted in 2005. (2005! That's ancient. That's only a year after gmail was introduced, and you know gmail has been around, like, always). Then there was this and this and this and this. These days dynamic SCRIPT tags are something common, mainly because of their non-blocking behavior that helps performance. This is all good.

我在此博客上有很多与此相关的文章。 与开始的东西我认为是一个有趣的黑客模仿PHP的需要()。 这是在2005年发布的。(2005年!那是很古老的。在gmail推出仅一年之后,您就知道gmail一直存在,就像一直一样)。 然后就是这个和这个,这个和这个。 如今,动态SCRIPT标签很常见,主要是因为它们的非阻塞行为有助于提高性能。 一切都很好。

I wanted to highlight the part where you load a script file and then execute a function once the file is done loading. A common, but kinda wrong pattern I've posted back at the time, and tweaked a little since, is like so:

我想突出显示您加载脚本文件的部分,然后在文件加载完成后执行功能。 我当时发布的一种常见但有点错误的模式,此后进行了一些调整,如下所示:

var first_html" title=js>js = document.getElementsByTagName('script')[0];
var html" title=js>js = document.createElement('script');
html" title=js>js.src = file;
 
// normal browsers
html" title=js>js.onload = function () {
  alert('loaded!!');
};
 
// IE
html" title=js>js.onreadystatechange = function () {
  if (html" title=js>js.readyState in {complete: 1, loaded: 1}) {
    alert('loaded!!');
  }
};
 
 
first_html" title=js>js.parentNode.insertBefore(html" title=js>js, first_html" title=js>js);

Back at the time (2006) this was fine. The problem is now that since version 9, IE supports onload handler in script elements. But it also supports onreadystatechange for backwards compatibility.

追溯到当时(2006年),情况很好。 现在的问题是,从版本9开始,IE在脚本元素中支持onload处理程序。 但是它也支持onreadystatechange以便向后兼容。

In other words in IE9+ your callbacks will be executed twice. Not good.

换句话说,在IE9 +中,您的回调将执行两次。 不好。

单次回调 (Single callback)

There are various ways to deal with this situation.

有多种方法可以处理这种情况。

1. You can delete the onload callback in readystatechange, beacuse readystatechange is called first.

1.您可以在readystatechange删除onload回调,因为首先要调用readystatechange

html" title=js>js.onreadystatechange = function () {
  if (html" title=js>js.readyState in {complete: 1, loaded: 1}) {
    callback();
    html" title=js>js.onload = null;
  }
};

2. You can use a single assignment to both

2.您可以对两者使用单个分配

html" title=js>js.onload = html" title=js>js.onreadystatechange = function () {
  // stuff...
  html" title=js>js.onload = html" title=js>js.onreadystatechange = null;
 
};

The problem with both of these is that readystatechange is involved even in browsers that are modern (IE9+) and support onload. Feels a bit ugh.

两者的问题在于,即使在现代(IE9 +)和支持onload浏览器中,也都需要readystatechange 。 感觉有点

3. You can sniff onload support

3.您可以嗅探onload支持

if (typeof html" title=js>js.onload !== 'undefined') {
  // good stuff..
} else {
  // onreadystatechange jazz
}

This works because old IEs will not have any onload property (hence undefined) while supporting browsers will have this property initially set to null.

之所以可行,是因为旧的IE将没有任何onload属性(因此undefined ),而支持的浏览器会将此属性最初设置为null

Hmm, making a distinction between two falsy values null and undefined seems a little fragile. The next developer will come and say: "meh, what's with the typeof verbosity, let's just say if (html" title=js>js.onload)"... And the whole thing will fail.

嗯,区分两个虚假nullundefined似乎有些脆弱。 接下来开发商会说:“咩,用什么typeof冗长,让我们只说if (html" title=js>js.onload) ” ......而整个事情会失败。

4. (And this is my preferred method) is to sniff support using addEventListener.

4.(这是我的首选方法)是使用addEventListener嗅探支持。

It just happens so that IE9, which supports onload, is also the first IE browser that supports addEventListener.

碰巧,支持onload IE9也是第一个支持addEventListener IE浏览器。

The whole thing looks like:

整个过程看起来像:

var first_html" title=js>js = document.getElementsByTagName('script')[0];
var html" title=js>js = document.createElement('script');
html" title=js>js.src = file;
 
if (html" title=js>js.addEventListener) { // normal browsers
  html" title=js>js.addEventListener('load', function(){
    alert('done!!');
  }, false);
} else {
  html" title=js>js.onreadystatechange = function() { // old IEs
    if (html" title=js>js.readyState in {loaded: 1, complete: 1}) {
      html" title=js>js.onreadystatechange = null;
      alert('done!!');
    }
  };
}
 
first_html" title=js>js.parentNode.insertBefore(html" title=js>js, first_html" title=js>js);

Drawback is that you decide on a feature (script onload support) based on a different feature (addEventListener support). I can live with this. We're talking here about an exception for known legacy browsers and shouldn't be an issue going forward in this brave new world where everyone lives in piece and love and brotherhood and sisterhood and motherhood and all browsers support onload and addEventListener.

缺点是您基于其他功能( addEventListener支持)决定功能(脚本onload支持)。 我可以忍受。 我们在这里谈论的是已知的旧版浏览器的例外情况,在这个勇敢的新世界里,每个人都生活在零碎的爱情,兄弟情谊,姐妹情谊和母性中,所有浏览器都支持onloadaddEventListener ,这不应该成为一个问题。

So anyway, choose your poison 🙂

所以无论如何,选择你的毒药🙂

Here's a test page that listens to everything so you can play in different browsers: http://www.phpied.com/files/html" title=js>jsasync/loaded.html

这是一个测试页面,可监听所有内容,以便您可以在不同的浏览器中播放: http : //www.phpied.com/files/html" title=js>jsasync/loaded.html

BTW, notice that IE is the only browser that fires window.onload before the onload of the (slow) script. This is another thing to keep in mind and look out for.

顺便说一句,请注意IE是唯一一个在onload (慢速)脚本之前触发window.onload浏览器。 这是要记住并提防的另一件事。

Tell your friends about this post on Facebook and Twitter

在Facebook和Twitter上告诉您的朋友有关此帖子的信息

翻译自: https://www.phpied.com/async-html" title=html" title=java>javascript>html" title=java>javascript-callbacks/


http://www.niftyadmin.cn/n/1306011.html

相关文章

主画布 子画布_画布中的像素处理

主画布 子画布Done it before with PHP, but now that JavaScript is all-powerful, lets see how we can manipulate images in an HTML <canvas>. 以前使用PHP进行过处理&#xff0c;但是现在JavaScript具备了强大的功能&#xff0c;让我们看看如何在HTML <canvas&g…

css路径自动加上了路径_CSS和关键路径

css路径自动加上了路径Back when I was still actively into speaking at public events (way, way back, something like year and a half ago (which strangely roughly coincides with the time I joined Facebook, hmmm (hmm? (huh? whats with the parentheses? sure a…

南苏丹华为_速度苏丹

南苏丹华为#2 This post is part of the Velocity countdown series. Stay tuned for the last one tomorrow. &#xff03;2这篇文章是Velocity倒数系列的一部分。 请继续关注最后一个明天。 With only 2 days to Velocity, its time to drop in the quality of these posts (…

Perfplanet.com已打开

#5 This post is part of the Velocity countdown series. Stay tuned for the articles to come. &#xff03;5这篇文章是Velocity倒数系列的一部分。 请继续关注未来的文章。 Its been over a year, since the launch of perfplanet.com. Looks good and useful for people …

泛函倒数_速度倒数

泛函倒数Let me try to set the mood for Velocity 2011 with an attempt to publish one performance-y post a day for the seven days between now and when the conference starts. 让我尝试设置Velocity 2011的氛围&#xff0c;尝试从现在到会议开始的7天每天发布一篇性能…

re 懒惰_懒惰HTML评估

re 懒惰#7 This post is part of the Velocity countdown series. Stay tuned for the articles to come. &#xff03;7这篇文章是Velocity倒数系列的一部分。 请继续关注未来的文章。 Some time ago Google talked about using a sort of lazy JavaScript evaluation which e…

飞鸽传书速度_速度之书

飞鸽传书速度#3 This post is part of the Velocity countdown series. Stay tuned for the articles to come. &#xff03;3这篇文章是Velocity倒数系列的一部分。 请继续关注未来的文章。 Without further ado, please point your browser to the newborn bookofspeed.com. …

成功并不像你想像的那么难_想像

成功并不像你想像的那么难Challenged by Marcel and inspired by another idea by Nicholas (upcoming, stay tuned!) heres the beginning. 受到Marcel的挑战&#xff0c;并受到Nicholas提出的另一个想法的启发(敬请期待&#xff01;)&#xff0c;这是开始。 Imagine theres …