重访 = image.onload 未调用

Revisited = image.onload NOT called

很老,但是非常联合国已解决的主题:image.onload没有调用。

代码胜于文字...

呼叫 .html =

<script>
var newConnection = new MeasureConnectionSpeed();

if (newConnection.isHighSpeed())
    doSomething1;
else
    doSomething2;
</script>

调用 .html =

<script>
function MeasureConnectionSpeed() {

    var connection = this;

    var imgDownloadSrc = "http://someLargeImage.jpg"; 
    var imgDownloadSize = 943 * 1024;     // bytes

    var startTime = 0,
        endTime   = 0;   // set later
    connection.isHighSpeedConnection = false;   // = a Object Property

    // an Object Method ...
    // just the function declaration which is called via
    // connection.computeResults()
    connection.isHighSpeed    = isHighSpeed;

    connection.computeResults = computeResults;   // another Object Method

    var testImgDownload = new Image();

    testImgDownload.onload = function () {

        endTime = (new Date()).getTime();

        connection.computeResults();

    }   // testImgDownload.onload


    testImgDownload.onerror = function (err, msg) {

        alert("Invalid image, or error downloading");

    }

    // We immediately continue while testImgDownload is still loading ...

    // the timer is started here and ended inside testImgDownload.onload 
    startTime = (new Date()).getTime();

    // This forces an attempt to download the testImgDownload and get the
    // measurements withOUT actually downloading to your Cache:
    var cacheBuster = "?nnn=" + startTime;
    testImgDownload.src = imgDownloadSrc + cacheBuster;


    function computeResults() {

        var speedMbps  = someNumber;

        connection.isHighSpeedConnection = speedMbps > 20;

    }   // computeResults

    // this.isHighSpeed() = isHighSpeed()
    function isHighSpeed() {

        return connection.isHighSpeedConnection;

    }

}   // MeasureConnectionSpeed

</script>

* 编辑 #1 *

还有两位...

我决定下载 Google 的 Chrome 并在本地测试我的 .html。 Chrome 访问了我原始代码的 .onerror 事件处理程序。 Safari 和 Firefox 从来没有???

另一个奇怪的观察...在我的 .onerror 事件处理程序中使用 Chrome、alert(err) 生成 "undefined"。但是,我确实使用了 alert(this.width)alert(this.naturalWidth) 每个都显示 0 ...这意味着它是 无效图像???

如果我将 src 放在 .onload 处理程序之前,甚至会发生 无效图像 错误。

现在真的是这样!

* 编辑 #2 - 2015 年 8 月 8 日 *

1) 真的很抱歉没有早点回来...不过我开始身体不舒服,多休息一下

2) 无论如何,我实现了 Dave Snyder 精彩的 IIFE 代码,它确实有效…….onload 处理程序中的代码正常工作,我真的非常感谢 Dave 和他为 [=79 提供的所有时间=].当然,我放弃了 newConnection = new MeasureConnectionSpeed() 并使用了 Dave 的 IIFE 方法。

现在,我只需要弄清楚为什么这段代码会给我大约 5 Mbps 的速度数字,而我通过以太网路由器有 30 Mbps 的速度。我真的希望看到一个数字接近。

我真的非常讨厌必须包含另一个 API 因为我测量速度的全部目的是决定天气重定向到相对 "busy" 站点或 "keep it simple"版本。

非常感谢,戴夫。你是我的英雄。

约翰·洛夫

这在 Chrome 对我有用。

(function(){
  var imgDownloadSrc = "https://upload.wikimedia.org/wikipedia/commons/d/d8/Schwalbenschwanz_%28Papilio_machaon%29.jpg",
      testImgDownload = new Image(),
      startTime, endTime,
      WhosebugLog = document.getElementById('log');

  var log = function(message, str) {
    WhosebugLog.innerHTML += message.replace("%s", str) + "<br>";
    console.log(message, str);
  }

  testImgDownload.onload = function () {
    log('image loaded!');
    endTime = +new Date();
    log('end time: %s', startTime);
    log('total time: %s', (endTime - startTime));
  }

  testImgDownload.onerror = function (err, msg) {
    throw "Invalid image, or error downloading";
  }

  startTime = +new Date();
  log('start time: %s', startTime);
  testImgDownload.src = imgDownloadSrc + "?" + startTime;
  log('downloading: %s', testImgDownload.src);
})();
<!doctype html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Untitled Document</title>
</head>

<body>
   <pre id="log"></pre>
</body>
</html>

这是您的代码,稍作修改即可运行。 image.onload 似乎工作正常,但 isHighSpeed() 在图像下载完成之前被调用。它需要重构/重新排序,以便您在设置后调用 isHighSpeed()。对于这种事情使用回调是很常见的。

/* for illustration */
var WhosebugLog = document.getElementById("log");
var log = function(message, str) {
  WhosebugLog.innerHTML += message.replace("%s", str) + "<br>";
  console.log(message, str);
}


/* calling.html */

var newConnection = new MeasureConnectionSpeed();

log('newConnection.isHighSpeed()? %s', newConnection.isHighSpeed());

/* called.html */

function MeasureConnectionSpeed() {

    var connection = this;

    var imgDownloadSrc = "https://upload.wikimedia.org/wikipedia/commons/d/d8/Schwalbenschwanz_%28Papilio_machaon%29.jpg"; 
    var imgDownloadSize = 1709360 * 8;     // bits (~1.6mb * 8)

    var startTime = 0,
        endTime   = 0;   // set later
    connection.isHighSpeedConnection = undefined;   // = a Object Property

    // an Object Method ...
    // just the function declaration which is called via
    // connection.computeResults()
    connection.isHighSpeed    = isHighSpeed;

    connection.computeResults = computeResults;   // another Object Method

    var testImgDownload = new Image();

    testImgDownload.onload = function () {

        endTime = (new Date()).getTime();

        log('endTime: %s', endTime);
      
        connection.computeResults();

    }   // testImgDownload.onload


    testImgDownload.onerror = function (err, msg) {

        log("!!! ERROR Invalid image, or error downloading");

    }

    // We immediately continue while testImgDownload is still loading ...

    // the timer is started here and ended inside testImgDownload.onload 
    startTime = (new Date()).getTime();

    log('startTime: %s', startTime);
  
    // This forces an attempt to download the testImgDownload and get the
    // measurements withOUT actually downloading to your Cache:
    var cacheBuster = "?nnn=" + startTime;
    testImgDownload.src = imgDownloadSrc + cacheBuster;

    log('loading: %s', testImgDownload.src);

    function computeResults() {
        var duration, speed, speedMbps;
      
        duration = (endTime - startTime) / 1000; // seconds 
        speed = imgDownloadSize / duration; // bits per second
        speedMbps = speed / 1000000; // megabits

        log('duration: %s', duration);
        log('speed: %s', speed);
        log('speedMbps: %s', speedMbps);
      
        connection.isHighSpeedConnection = speedMbps > 20;

    }   // computeResults

    // this.isHighSpeed() = isHighSpeed()
    function isHighSpeed() {

        return connection.isHighSpeedConnection;

    }

}   // MeasureConnectionSpeed
<pre id="log"></pre>