необъяснимая математическая ошибка в javascript

#javascript

#javascript

Вопрос:

У меня есть функция, используемая для клонирования программы прокрутки статей flash на этой странице. К сожалению, я нахожусь за брандмауэром, поэтому не могу загрузить свой собственный код, но это должно навести вас на мысль. Функция:

 function select(id) {
  alert(active "n" ((active 1)%4));

  var prev  =  active;
  active    = (typeof(id) == "undefined" ? (active 1)%4 : id);

  $("#panel").animate({"top": tops[active]}, 750);
  $("#main" prev).fadeOut(750);
  $("#main" active).fadeIn(750);
}
  

Итак, если select() вызывается без идентификатора, он просто переходит к следующему элементу в последовательности, в противном случае он переходит к выбранному элементу. Выполняется по определенному таймеру:

 timer = setInterval("select()", 5000);
  

При наведении курсора мыши на объект запускается эта функция:

 $("img.thumb").mouseover(function() {
  clearInterval(timer);
  select($(this).attr("id").substr(-1));
  timer = setInterval("select()", 5000);
});
  

Проблема в том, что после наведения курсора мыши функция select завершается сбоем в течение одного цикла, при этом следующий объект не имеет отношения к предыдущему. Выбранный объект является согласованным — он остается неизменным при каждом обновлении с учетом одних и тех же начальных условий, но он никак не связан, насколько я могу определить.

Что самое странное, так это то, что предупреждение, которое я запускаю в начале select(), которое должно быть простой математической операцией, завершается с ошибкой, утверждая, что (для последовательности, которую я тестирую — дождитесь автоматической прокрутки от 0 до 1, затем наведите курсор мыши 3) (3 1)%4=3.

Я тестировал это как в Firefox, так и в Chrome, так что, похоже, это присуще javascript.

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

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

 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <meta http-equiv="Content-type" content="text/html;charset=UTF-8" />
        <meta http-equiv="imagetoolbar" content="no" />
        <script type="text/javascript" src="jquery.js"></script>
        <script type="text/javascript">
            //alter these as you please
            var thumbs  = ["images/1t.png", "images/2t.png",
                "images/3t.png", "images/4t.png"];
            var mains       = ["images/1.png", "images/2.png",
                "images/3.png", "images/4.png"];
            var links       = ["http://www.goldcoast.com.au/gold-coast-beaches.html",
                "http://www.goldcoast.com.au/gold-coast-whale-watching.html",
                "http://www.goldcoast.com.au/gold-coast-hinterland-rainforest.html",
                "http://www.goldcoast.com.au/gold-coast-history.html"];

            //don't touch these
            var timer   = null;
            var active  = 0;
            var tops    = [0, 77, 155, 234];

            function select(id) {
                alert(active "n" ((active 1)%4));

                var prev    =  active;
                active      = (typeof(id) == "undefined" ? (active 1)%4 : id);

                $("#panel").animate({"top": tops[active]}, 750);
                $("#main" prev).fadeOut(750);
                $("#main" active).fadeIn(750);
            }

            $(function() {
                for(var i = 0; i < 4; i  ) {
                    $("#thumb" i).attr("src", thumbs[i]);
                    $("#main" i).attr("src", mains[i]);
                }

                $("#main" active).show();

                $("img.thumb").mouseover(function() {
                    clearInterval(timer);
                    select($(this).attr("id").substr(-1));
                    timer = setInterval("select()", 5000);
                });

                timer = setInterval("select()", 5000);
            });
        </script>
        <style type="text/css">
            #container  {position:relative;}

            #panel      {position:absolute;left:0px;top:0px;z-index:1;}

            img.thumb   {position:absolute;left:8px;z-index:2;}
            #thumb0     {top:7px;}
            #thumb1     {top:84px;}
            #thumb2     {top:162px;}
            #thumb3     {top:241px;}

            img.main        {position:absolute;left:118px;top:2px;display:none;}
        </style>
    </head>
    <body>
        <div id="container">
            <img src="images/panel.png" id="panel" />
            <img id="thumb0" class="thumb" />
            <img id="thumb1" class="thumb" />
            <img id="thumb2" class="thumb" />
            <img id="thumb3" class="thumb" />
            <img id="main0" class="main" />
            <img id="main1" class="main" />
            <img id="main2" class="main" />
            <img id="main3" class="main" />
        </div>
    </body>
</html>
  

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

1. Чувак, используй setTimeout(select, 5000); вместо "select()" . eval() это зло.

2. Возникли проблемы с пониманием вашего кода, но я думаю, что это, скорее всего, ошибка приведения типа. parseInt(id) Где-то может просто решить проблему.

3. @timdream Хорошая мысль, приветствую. Ранее я вызывал ее с аргументом.

4. (1) Передайте функции, а не строки, в setTimeout и setInterval (это eval замаскировано!). (2) $(this).attr('id') скорее не нужен; this.id работает во всех браузерах, для ввода требуется меньше символов и он намного эффективнее. (3) По всей вероятности, существует плагин jQuery, который уже делает то, что вы хотите. Даже без использования плагина почти наверняка есть более чистый способ написания mouseover обработчиков.

5. @timdream На самом деле, этот parseInt сделал это, приветствую. Я должен перестать так лениво печатать. Если вы опубликуете это в качестве ответа, я приму это.

Ответ №1:

Используйте parseInt() , как предложено в комментарии.