JQuery слайд-шоу - почему этот код работает? - PullRequest
2 голосов
/ 19 января 2010

Я занимался кодированием слайд-шоу в javascript с использованием jquery, когда столкнулся с чем-то, что делало то, что мои несколько строк кода делали в несколько строк.

Проблема в том, что я не понимаю, как это работает, поэтому я могу изменить его.

var imgs = [
        'image1.jpg',
        'image2.jpg',
        'image3.jpg'];
        var cnt = imgs.length;

    $(function() {
        setInterval(Slider, 4000);
    });

    function Slider() {
    $('#imageSlide').fadeOut("slow", function() {
       $(this).attr('src', imgs[(imgs.length++) % cnt]).fadeIn("slow");
    });
    }

Это строка, которая заставляет меня:

[(imgs.length++) % cnt]

Я читаю это как

3+1 % 3 = 1

Теперь каждый раз, когда он выполняется, кажется, что ни один из этого кода не модифицирует ни одну из переменных. cnt всегда будет равно imgs.length (3), imgs.length++ на самом деле не изменяет его, он просто добавляет один для этого отдельного выполнения, правильно?

Поэтому независимо от того, сколько раз он выполняется, он всегда будет imgs[1], но когда я выполняю код, он правильно проходит через все объекты массива.

EDIT:

Я просто добавил alert(imgs.length); и подтвердил, что ++ действительно меняет переменную, но для меня это все еще не имеет смысла.

Первый запуск, imgs.length = 4 после ++. 4 % 3 = 1 поэтому он должен запускать объект массива [1] не [0]?

Второй запуск, 5 % 3 = 2

Третий прогон, 6 % 3 = 0

и т. Д. И т. Д., Но он никогда не должен сбрасываться. Тем не менее, если я поставлю alert(imgs.length % cnt);, он возвращает только 0, 1, 2, а не сбрасывает.

Почему?

Ответы [ 6 ]

3 голосов
/ 19 января 2010

возвращаемое значение imgs.length++ равно 3, поэтому 3% 3 = 0, но imgs.length будет 4, а массив imgs будет содержать 4 элементов.

попробуйте в консоли:

var x = [ 1, 2, 3 ]
x.length++
=> 3
x.length++
=> 4
x.length++
=> 5
x
[1, 2, 3, undefined, undefined, undefined]

, поэтому каждый раз, когда вызывается imgs.length++, он добавляет один элемент в массив. так что не хороший код, но короткий:)

РЕДАКТИРОВАТЬ : почему легко ответить, в начале он содержит cnt количество элементов, поэтому код будет вставлять каждое изображение и начинается с его начала. поэтому, если массив imgs содержит 5 элементов, он будет проходить через элементы 5 и начинается с начала.

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

2 голосов
/ 19 января 2010

Я уверен, что вы знаете, что imgs.length++, если бы он был применен к любой другой переменной, добавил бы к ней одну, изменив исходную переменную.

var x = 1;
alert(x++); // alerts 1
alert(x); // alerts 2

Конечно, вот что происходит.

Сценарий увеличивает длину массива imgs при каждом запуске, поэтому он перемещается с 3 до 4 до 5 и т.д. оказывает какое-либо влияние на производительность, но если вы понимаете, что length на самом деле является записываемым свойством, все это имеет смысл.

0 голосов
/ 19 января 2010

Если вы хотите, чтобы ваш код стал более читабельным в будущем, я бы лично предложил вам изменить код на что-то вроде этого:

var imgs = [
    'image1.jpg',
    'image2.jpg',
    'image3.jpg'];
var i = 0;

$(function() { // This is a shortcut for $(document).ready();
    setInterval(Slider, 4000);
});

function Slider() {
   $('#imageSlide').fadeOut("slow", function() {
      i = (i+1) % imgs.length;
      $(this).attr('src', imgs[i]).fadeIn("slow");
   });
}
0 голосов
/ 19 января 2010

Ну, каждую 4-ю секунду, которую запускает функция Slider, она расширяет массив, Вы получаете:

3+1 % 3 = 1
4+1 % 3 = 2
5+1 % 3 = 0

и так далее:)

0 голосов
/ 19 января 2010

(imgs.length ++)% cnt

приведет к тому, что изображения будут проходить через каждое изображение снова и снова.

знак процента (%) в JavaScript означает, что он использует оператор модуля (остаток от деления).

Примеры:

  • 0% 3 = 0
  • 1% 3 = 1
  • 2% 3 = 2
  • 3% 3 = 0
  • 4% 3 = 1
  • 5% 3 = 2 и т.д ...
0 голосов
/ 19 января 2010

Я не уверен на 100% в javascript, но любой другой язык, который я знаю imgs.length++ - это то же самое, что сказать imgs.length = imgs.length + 1, поэтому его нужно модифицировать.

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

Так что я думаю, что на самом деле это меняет длину, но я все равно не рекомендовал бы использовать ее без документирования. Более понятным способом было бы объявить новую переменную i = 0 и заменить imgs.length++ на i++, потому что, хотя в этом случае, вероятно, не имеет значения, если вы делаете что-то еще с массивом, длина теперь, вероятно, не то, что вы ожидаете.

Относительно редактирования:
6% 3 - это 0, а не 3.
По модулю (в программировании немного отличается по математике) означает делить и брать остаток.
6/3 = 2 с остатком 0.
7/3 = 2 с остатком 1.
8/3 = 2 с остатком 2.
9/3 = 3 с остатком 0,

...