Выполнение сценария блока Javascript - PullRequest
5 голосов
/ 17 февраля 2010

Мне нужно сделать что-то вроде этого:

  • Выполнить кусок кода
  • Начать загрузку изображения и заблокировать выполнение скрипта
  • Когда изображение загружено, возобновить выполнение
  • Выполнить оставшуюся часть кода

Я знаю, что самый простой способ - назначить функцию для события onload изображения, а затем выполнить оставшуюся часть кода в функции, но если это возможно, я хочу иметь "линейное" поведение, блокирующее выполнение сценария. и затем возобновить это. Итак, есть ли кросс-браузерный способ сделать это?

Ответы [ 5 ]

3 голосов
/ 17 февраля 2010

Единственный способ заблокировать выполнение скрипта - использовать цикл, который также блокирует большинство браузеров и предотвращает любое взаимодействие с вашей веб-страницей.

Firefox, Chrome, Safari, Opera и IE all поддерживают свойство complete, которое было окончательно стандартизировано в HTML5. Это означает, что вы можете использовать цикл while, чтобы остановить выполнение скрипта до завершения загрузки образа.

var img = new Image();
img.src = "/myImage.jpg";
document.body.appendChild(img);
while (!img.complete) 
{
    // do nothing...
}

// script continues after image load

При этом, я думаю, вы должны искать способы достижения своей цели, не блокируя браузер.

1 голос
/ 17 февраля 2010

Вы можете использовать xmlhttprequest и использовать синхронный режим.

var url = "image.php?sleep=3";
var img = new Image;
var sjax = new XMLHttpRequest();
img.src = url;
sjax.open("GET", url, false);
sjax.send(null);
alert(img.complete);

Хитрость в том, что мы загружаем одно и то же изображение дважды, сначала используя объект Image, а также используя ajax в синхронном режиме. Объект Image не нужен, я просто предположил, что вы так хотите его загрузить. Ключевым моментом является то, что если ajax завершится, то изображение будет полностью загружено в кеш браузера. Таким образом, изображение также будет доступно для использования объектом Image.

Предполагается, что изображение обслуживается с http-заголовками, дружественными к кешу. В противном случае его поведение может отличаться в разных браузерах.

1 голос
/ 17 февраля 2010

Я бы не стал полностью блокировать выполнение скрипта, так как это может замедлить работу браузера или даже предупредить пользователя о том, что выполнение скрипта занимает слишком много времени.

Что вы можете сделать, это «линеаризовать» ваш код, используя события для завершения работы. Вам нужно будет добавить тайм-аут в функцию, так как изображение может никогда не загрузиться.

Пример:

var _img = null; 
var _imgDelay = 0;
var _finished = false;

function startWork(){
   _img = document.createElement('img');
   _img.onload = onImgLoaded;
   _img.src = 'yourimg.png';

   // append img tag to parent element here

   // this is a time out function in case the img never loads,
   // or the onload event never fires (which can happen in some browsers) 
   imgTimeout();   
}

function imgTimeout(){
   if (_img.complete){
      // img is really done loading
      finishWork();
   }
   else{
      // calls recursively waiting for the img to load
      // increasing the wait time with each call, up to 12s
      _imgDelay += 3000;

      if (_imgDelay <= 12000){ // waits up to 30 seconds
         setTimeout(imgTimeout, _imgDelay);
      }
      else{
         // img never loaded, recover here.
      }
   }
}

function onImgLoaded(){
   finishWork();
}

function finishWork(){
   if (!_finished){
      // continue here
      _finished = true;
   }
}
1 голос
/ 17 февраля 2010

Это предложение не совсем то, что вы просили, но я предлагаю его в качестве возможной альтернативы.

Создайте класс CSS с фоновым изображением, которое вы хотите использовать. Когда ваше приложение запускается, назначьте этот класс CSS для DIV, который либо скрыт за пределами сайта, либо имеет размер ноль на ноль пикселей. Это обеспечит загрузку изображения с сервера. Если вы хотите загрузить изображение (шаг два выше), используйте созданный вами класс CSS; это произойдет быстро. Может быть, достаточно быстро, чтобы вам не нужно было блокировать последующее выполнение кода?

1 голос
/ 17 февраля 2010

Если вы не возражаете против выполнения этапа предварительной обработки, попробуйте Narrative Javascript , который вы можете

image.onload = new EventNotifier();
image.onload.wait->();
...