2010-02-17 3 views
5

мне нужно сделать что-то вроде этого:Javascript блок сценария выполнения

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

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

ответ

3

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

Firefox, Chrome, Safari, Opera и IE все поддерживают свойство 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 

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

+0

Я согласен, что это плохо, но я думаю, что это единственный способ. Возможно, я могу дать пользователю возможность выбирать между выполнением сценария блокировки и вызвать функцию загрузки при загрузке изображения. – mck89

+0

@ mck89: Мне трудно поверить, что это единственный способ. Я могу честно сказать, что я никогда не сталкивался с ситуацией в JavaScript, которая требует блокировки скрипта; всегда есть способ (например, временно переопределяющие функции) делать асинхронно. В конце концов, вы контролируете скрипт на своей странице. Возможно, вы могли бы опубликовать еще один вопрос, который будет более подробно посвящен вашей проблеме? –

+0

@ mck89: свойство 'complete' существует для Gecko и IE и может работать и в других браузерах. Если вы настаиваете на блокировании выполнения сценария, см. Мое обновление. –

1

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

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

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

+0

@ mck89: После предварительной обработки вы получаете чистый Javascript. – kennytm

+0

Да, я знаю, но я предпочитаю использовать только javascript – mck89

1

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

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

+0

Да, это может быть хороший метод предварительной загрузки изображений, но я не загружаю изображение в начале приложения. – mck89

+0

Я понимаю, но если вы создали класс CSS с атрибутом background-image, назначенный этому классу для фиктивного DIV, вы бы загрузили изображение в начале приложения. – Upperstage

1

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

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

Пример:

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; 
    } 
} 
+0

Вы уверены, что можете остановить выполнение с помощью setTimeout? – mck89

+0

Это не останавливает выполнение кода, это позволяет подождать, пока изображение не будет загружено, прежде чем вы сделаете больше работы. Вы прекратите выполнение своего собственного кода, переместив оставшийся код в функцию finishWork. – FlashXSFX

1

Вы можете использовать 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. В противном случае поведение может различаться в разных браузерах.

Смежные вопросы