некоторые ошибки с объектами javascript

Я начинаю ненавидеть объекты в javascript.

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

сообщение о проблеме:
"this.Images is undefined" и другие ошибки.

HTML-файл

<div id="SlideShow" >
   <img id="img" src="images/img.jpg" alt="" /><span id="desc"></span>
</div>

<script type="text/javascript">
    meToo.Images = ['images/img.jpg','images/img2.jpg','images/img3.jpg','images/img4.jpg','images/img5.jpg'];
    meToo.Titles = ['Pic1','pic2','Pic3','Pic4','Pic5'];
    meToo.Play('img');
</script>  

Объект JavaScript

var meToo = {
     Images: [],
     Titles: [],
     counter: 0,
     Play: function(ElemID){
         var element = document.getElementById(ElemID);
         var ImgLen = this.Images.length;

         if(this.counter < ImgLen){
             this.counter++;
             element.src = this.Images[this.counter];
             element.nextSibling.innerHTML = this.Titles[this.counter];
         }else{
             this.counter = 0;
         }
         setTimeout(this.Play, 1000);
    }   
};

См. пример.


person Lion King    schedule 23.06.2012    source источник
comment
И... что это за новая ошибка?   -  person Ahamed Mustafa M    schedule 23.06.2012
comment
вот что бы я сделал   -  person T I    schedule 23.06.2012


Ответы (3)


см. этот вопрос. В противном случае setTimeout устанавливает this в объект окна. Кроме того, счетчик должен увеличиваться после установки изображений, иначе вы будете читать за пределами массива.

Наконец, при сбросе счетчика на 0 будет дополнительная задержка в одну секунду перед перезапуском цикла, потому что изображение не сбрасывается в этом блоке else. Вы можете переписать эту часть логики.

Обновлен скрипт

    if(this.counter < ImgLen){
        element.src = this.Images[this.counter];
        element.nextSibling.innerHTML = this.Titles[this.counter];
        this.counter++;
    }else{
        this.counter = 0;
    }
    var _this = this;
    setTimeout(function() { _this.Play('img') }, 1000);

Это я бы написал, чтобы цикл продолжался с одной- секундные интервалы:

Play: function(ElemID) {
    var element = document.getElementById(ElemID);
    var ImgLen = this.Images.length;

    if (this.counter == ImgLen) {
        this.counter = 0;
    }
    element.src = this.Images[this.counter];
    element.nextSibling.innerHTML = this.Titles[this.counter];
    this.counter++;

    var _this = this;
    setTimeout(function() {
        _this.Play('img')
    }, 1000);
}
person Tina CG Hoehr    schedule 23.06.2012
comment
Я хочу знать, почему мы это делаем: var _this = this; и _this.Play('img'), почему это прямое использование не работает? - person Lion King; 24.06.2012
comment
Вы хотите обратиться к Play функции meToo, но setTimeout будет вызван глобальным window объектом, у которого нет Play функции. При установке ссылки на meToo с помощью _this функция _this.Play (ссылающаяся на meToo) будет вызываться через 1000 миллисекунд. В этом случае запись meToo.Play() внутри setTimeout тоже будет работать, в вопросе, который я связал со сценарием, нужна переменная например _this нужен и работает как более общий случай. - person Tina CG Hoehr; 24.06.2012
comment
Спасибо Mr MaryAnne за помощь, у меня есть еще один простой вопрос в той же теме, как вы знаете, и я извиняюсь за беспокойство, я определил в setTimeOut функцию каждую 1 секунду будет менять изображение, но почему при переходе от последнего изображения к первому требуется больше времени, я думаю, более 1 секунды? - person Lion King; 24.06.2012
comment
Поскольку функция написана так, она следует за if или else только один раз в секунду. Поэтому, когда массив закончен, он сбрасывает счетчик обратно на ноль и больше ничего не делает (изображение остается неподвижным). Затем при следующем посещении функции изображение изменится. Я предложил изменить последнюю часть моего ответа, чтобы исправить это, другие ответы также упоминают об этом. - person Tina CG Hoehr; 24.06.2012
comment
большое спасибо Mr MaryAnne за помощь, хотя я не понимаю последнего пункта, но вы Уважаемый человек - person Lion King; 24.06.2012
comment
Какой пункт был не ясен? О сбросе счетчика? Или вариант, который я предложил? И, пожалуйста, не надо называть меня мистером, Мэри-Энн подойдет :) - person Tina CG Hoehr; 24.06.2012
comment
Хорошо, дело в том, что больше времени при переходе с последней картинки на первую. - person Lion King; 24.06.2012
comment
Функция Play будет выбирать между блоком if и блоком else в зависимости от значения counter. Обратите внимание, что только в блоке if изображение будет меняться при установке параметра element.src. Когда счетчик превысит предел массива, он обнулится, но картина не изменится. Таким образом, он находится на последнем изображении до следующего запуска функции. Помните, что setTimeout не волнует, какой счетчик, он сохранит задержку. Либо добавьте бит element.src в блок else, либо перепишите логику, отделив сброс счетчика, как это сделал я. - person Tina CG Hoehr; 24.06.2012

if(this.counter < ImgLen)

неправильно.

Что произойдет здесь, так это то, что когда вы бежите

this.counter++;

значение этой переменной теперь будет ImgLen.length

Массивы в javascript идут от 0 до длины -1. Итак, теперь вы будете превышать длину массива при запуске:

this.Images[this.counter];

и столкнуться с ошибкой.

Быстрое исправление здесь состоит в том, чтобы изменить на

if(this.counter < ImgLen -1) 

Если вы столкнулись с другими проблемами, опубликуйте точное сообщение об ошибке. (Запустите в Chrome и нажмите F12 (например), чтобы открыть консоль и увидеть ошибки).

person Nik    schedule 23.06.2012
comment
Спасибо, но это не главная проблема - person Lion King; 23.06.2012
comment
Затем вам нужно будет объяснить, в чем именно заключается ваша проблема, и ошибки, которые вы видите. - person Nik; 23.06.2012
comment
Теперь я вижу, что ваше это свойство ссылается на Window во второй раз, когда оно выполняется, поэтому оно больше не ссылается на meToo, поэтому изображения теперь будут нулевыми... - person Nik; 23.06.2012

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

    <script>
    var meToo = function(){
    var Images = ['http://www.image-upload.net/di/WMPI/img.jpg','http://www.image-upload.net/di/HPUQ/img2.jpg','http://www.image-upload.net/di/WQ9J/img3.jpg','http://www.image-upload.net/di/GIM6/img4.jpg','http://www.image-upload.net/di/0738/img5.jpg'];
    var Titles = ['Pic1','pic2','Pic3','Pic4','Pic5'];
    var counter = 0;
    return {
        Play: function(ElemID) {
            var element = document.getElementById(ElemID);
            if(element){
                var ImgLen = Images.length;

                if(counter < ImgLen) {
                    element.src = Images[counter];
                    element.nextSibling.innerHTML = Titles[this.counter];
                    counter++;
                } else {
                    counter = 0;
                }
            }
            setTimeout(callmeToo, 1000);
        }
    }
    }();

    function callmeToo(){
        meToo.Play('img');  
    }

    callmeToo();
</script>
person Harshniket Seta    schedule 23.06.2012