Загрузка изображения (), не ожидающая загрузки изображения

#javascript #image #slideshow

#javascript #изображение #слайд-шоу

Вопрос:

Я разобрался с проблемами центрирования и изменения размера, но все еще не могу заставить onLoad работать должным образом. У кого-нибудь есть идеи? Я думал, onLoad предполагалось дождаться полной загрузки изображения перед запуском кода. Поскольку это происходит прямо сейчас, он изменяет размер изображения для следующего изображения и изменяет его цвет перед загрузкой, поэтому предыдущее изображение снова исчезает. После того, как показ выполняется один раз, он работает отлично, поэтому, очевидно, что он не ожидает полной загрузки изображения перед запуском imageLoad() .

 <div id="slideShow">
    <div id="slideShowImg" style="display:none; margin-right:auto; margin-left:auto;">
    </div>
    <div id="slideShowThumbs">
    </div>
    <script type="text/javascript">
        loadXMLDoc('http://www.thehoppr.com/hopspots/82/82.xml', function() {
            var slideShow = document.getElementById('slideShow');
            var items = [];
            var nl = xmlhttp.responseXML.getElementsByTagName('image');
            var i = 0;
            var t;
            var slideShowImg = document.getElementById('slideShowImg');
            var slideShow = document.getElementById('slideShow');
            var maxHeight = 300;
            var maxWidth = 800;
            var imgNode = new Image();


            function image() {
                var nli = nl.item(i);
                var src = nli.getAttribute('src').toString();
                var width = parseInt(nli.getAttribute('width').toString());
                var height = parseInt(nli.getAttribute('height').toString());
                imgNode.onLoad = imageLoad();
                imgNode.src = src;
                imgNode.height = height;
                imgNode.width = width;
                imgNode.setAttribute("style", "margin-right:auto; margin-left:auto; display:block;");

                var ratio = maxHeight / maxWidth;
                if (imgNode.height / imgNode.width > ratio) {
                    // height is the problem
                    if (imgNode.height > maxHeight) {
                        imgNode.width = Math.round(imgNode.width * (maxHeight / imgNode.height));
                        imgNode.height = maxHeight;
                    }
                } else {
                    // width is the problem
                    if (imgNode.width > maxHeight) {
                        imgNode.height = Math.round(imgNode.height * (maxWidth / imgNode.width));
                        imgNode.width = maxWidth;
                    }
                }
            }

            function imageLoad() {
                slideShowImg.appendChild(imgNode);
                Effect.Appear('slideShowImg', {
                    duration: 1
                });

                t = setTimeout(nextImage, 7000);
            }

            function nextImage() {
                slideShowImg.setAttribute("style", "display:none");
                if (i < nl.length - 1) {
                    i  ;
                    image();
                } else {
                    i = 0;
                    image();
                }
            }

            if (xmlhttp.readyState == 4 amp;amp; xmlhttp.status == 200) {
                //XML Loaded, create the slideshow
                alert(xmlhttp.responseText);
                image();
            }
        });
    </script>
  

Комментарии:

1. Достаточно интересно, что, похоже, это действительно работает в Chrome, но не в IE или Firefox. Очевидно, что скрипт извлекается из кэша еще до того, как будет назначена загрузка? Предварительная загрузка изображения во время показа другого, вероятно, будет моим лучшим выбором здесь. Если кто-нибудь может предоставить мне какой-нибудь пример кода, который мог бы ускорить это, я был бы признателен, я довольно новичок в Javascript. Уже поздно, и я собираюсь спать.

Ответ №1:

Вот некоторые из моих мыслей (это все открытое обсуждение)…

  1. Предварительная загрузка — Поскольку вы ограничены параллельной загрузкой 2 ресурсов на имя хоста, возможно, не имеет смысла предварительно загружать все. Поскольку это слайд-шоу, как насчет изменения image () для загрузки изображения i 1 через объект Image, который не добавляется к DOM? Не кажется выгодным предварительно выбирать i 2 и далее в настройках слайд-шоу.

  2. Центрирование изображений — Что касается использования автоматической ширины поля для горизонтального центрирования, я полагаю, вам придется явно установить для изображения значение display:block. Очевидно, что это не решает проблему центрирования по вертикали. Все ли изображения одинакового размера? Кроме того, будет ли div-файл slideShowImg иметь определенную высоту / ширину? Если это так, то для достижения центрирования можно применить некоторую математику.

Надеюсь, это поможет! 🙂

Комментарии:

1. Я смог разобраться с центрированием и изменением размера. Сейчас я использую событие onLoad для запуска эффекта анимации, который вызывает появление контейнера div, но, похоже, это не работает, независимо от того, какую конфигурацию я пытаюсь. я думал, что событие onLoad должно было дождаться загрузки изображения, а затем оно запускает нужный вам код. Предварительная загрузка одного изображения вперед также звучит как хорошая идея, не могли бы вы включить какой-нибудь пример кода? Смотрите мой обновленный код выше!

Ответ №2:

Хорошо, итак, я исправил проблему с загрузкой и даже добавил небольшую предварительную загрузку, чтобы облегчить слайд-шоу. Все, что мне нужно было сделать, это сначала определить загрузку, а затем сделать все остальное, кроме определения src внутри функции onload. Затем я добавил небольшую предварительную загрузку nextImg, поэтому между изображениями практически нет сбоев, даже если браузер загружает их впервые. Вот окончательный код для всех, у кого похожие проблемы с загрузкой, и он находит способ здесь:

 <div id="slideShow">
    <div id="slideShowImg" style="display:none; margin-right:auto; margin-left:auto;">
    </div>
    <div id="slideShowThumbs">
    </div>
    <script type="text/javascript">
        loadXMLDoc('/82.xml', function() {
            var slideShow = document.getElementById('slideShow');
            var items = [];
            var nl = xmlhttp.responseXML.getElementsByTagName('image');
            var i = 0;
            var t;
            var slideShowImg = document.getElementById('slideShowImg');
            var slideShow = document.getElementById('slideShow');
            var maxHeight = 300;
            var maxWidth = 800;
            var curImg = new Image();
            var nextImg = new Image();

            function image() {
                var cli = nl.item(i);
                var src = cli.getAttribute('src').toString();
                var width = parseInt(cli.getAttribute('width').toString());
                var height = parseInt(cli.getAttribute('height').toString());
                curImg.onload = function() {
                    curImg.height = height;
                    curImg.width = width;
                    curImg.setAttribute("style", "margin-right:auto; margin-left:auto; display:block;");
                    slideShowImg.appendChild(curImg);
                    var ratio = maxHeight / maxWidth;
                    if (curImg.height / curImg.width > ratio) {
                        // height is the problem
                        if (curImg.height > maxHeight) {
                            curImg.width = Math.round(curImg.width * (maxHeight / curImg.height));
                            curImg.height = maxHeight;
                        }
                    } else {
                        // width is the problem
                        if (curImg.width > maxHeight) {
                            curImg.height = Math.round(curImg.height * (maxWidth / curImg.width));
                            curImg.width = maxWidth;
                        }
                    }
                }
                curImg.src = src;
                if (i < nl.length - 1) {
                    var nli = nl.item(i   1);
                    var nsrc = nli.getAttribute('src').toString();
                    nextImg.src = nsrc;
                }
                Effect.Appear('slideShowImg', {
                    duration: 1
                });

                t = setTimeout(nextImage, 7000);
            }

            function imageLoad() {}

            function nextImage() {
                slideShowImg.removeChild(curImg);
                slideShowImg.setAttribute("style", "display:none");
                if (i < nl.length - 1) {
                    i  ;
                    image();
                } else {
                    i = 0;
                    image();
                }
            }

            if (xmlhttp.readyState == 4 amp;amp; xmlhttp.status == 200) {
                //XML Loaded, create the slideshow
                alert(xmlhttp.responseText);
                image();
            }
        });
    </script>