Revisited = image.onload НЕ вызывается
Очень старая, но очень ООН решаемая тема: 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, alert(err)
внутри моего обработчика событий.onerror выдается "undefined". Но я использовал alert(this.width)
а также alert(this.naturalWidth)
, каждый показывает 0... что означает, что это недопустимое изображение???
И ошибка недействительного изображения даже происходит, если я помещаю src перед .onload
Handler.
Это действительно так сейчас!
* РЕДАКТИРОВАТЬ № 2 - 8 августа 2015 года *
1) Мне правда очень жаль, что я не вернулся раньше... но я начал плохо себя чувствовать, поэтому получил немного больше физического отдыха
2) Так или иначе, я реализовал замечательный код IIFE Дэйва Снайдера, и он определенно работал... код в.onload Handler работал правильно, и я действительно чрезвычайно благодарен Дейву и все время, которое он предоставил little-ole-me. Конечно, я сбросил newConnection = new MeasureConnectionSpeed () и использовал подход Дейва IIFE.
Теперь все, что мне нужно выяснить, почему этот код дает мне скорость около 5 Мбит / с, где у меня 30 Мбит / с через Ethernet-маршрутизатор. Я действительно ожидал бы увидеть число близко.
Я действительно, очень не хочу включать другой API, так как моя цель измерения скорости состоит в том, чтобы выбрать погоду для перенаправления на относительно "загруженный" сайт или "упрощенную" версию.
Большое спасибо, Дейв. Ты мой герой.
Джон Лав
1 ответ
Это работает для меня в Chrome.
(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);
})();
<!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 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
<pre id="log"></pre>