Revisited = image.onload未调用

时间:2015-07-28 03:03:00

标签: javascript onload-event

很老,但非常联合国解决了主题: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从未做过???

另一个好奇的观察......使用Chrome,我的.onerror事件处理程序中的alert(err)产生了“未定义”。但是,我确实使用了alert(this.width)alert(this.naturalWidth)每个都显示0 ...这意味着它是无效的图片???

如果我在.onload处理程序之前放置src ,则会出现无效图像错误。

现在真的是这样!

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

1)我真的很抱歉我没有早点回来......但我开始感觉不舒服,所以得到更多的身体休息

2)无论如何,我实现了Dave Snyder精彩的IIFE代码,它确实有效...... .onload Handler中的代码正常工作,我真的非常感谢Dave,并且他一直非常感谢他给小伙伴。当然,我抛弃了newConnection = new MeasureConnectionSpeed()并使用了Dave的IIFE方法。

现在,我必须弄清楚为什么这段代码给我带来了大约5 Mbps的速度数字,我通过以太网路由器获得30 Mbps的速度。我真的希望看到一个数字接近。

我真的,非常讨厌必须包含另一个API,因为我的速度测量目的是决定将天气重定向到相对“繁忙”的网站或“保持简单”版本。

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

John Love

1 个答案:

答案 0 :(得分:5)

这适用于Chrome。

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

  var log = function(message, str) {
    stackOverflowLog.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);
})();
&#13;
<!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>
&#13;
&#13;
&#13;

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

&#13;
&#13;
/* for illustration */
var stackOverflowLog = document.getElementById("log");
var log = function(message, str) {
  stackOverflowLog.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
&#13;
<pre id="log"></pre>
&#13;
&#13;
&#13;