Изменить класс в течение тайм-аута, характерного для выбранного элемента

Я установил здесь jsFiddle. Но ниже код...

HTML

<div class="square square0"></div>
<div class="square square1"></div>
<div class="square square2"></div>
<div class="square square3"></div>

JavaScript

$('.square').click(function () {
    if ($(this).hasClass('square0')) {
        $(this).removeClass('square0').addClass('square1');
        return false;
    }
    if ($(this).hasClass('square1')) {
        $(this).removeClass('square1').addClass('square2');
        return false;
    }
    if ($(this).hasClass('square2')) {
        $(this).removeClass('square2').addClass('square3');
        return false;
    }
    if ($(this).hasClass('square3')) {
        $(this).removeClass('square3').addClass('square0');
        return false;
    }
});

CSS

.square { display: block; height: 100px; width: 100px; }
.square0{ background-color: #000; }
.square1{ background-color: #F00; }
.square2{ background-color: #0F0; }
.square3{ background-color: #00F; }

То, как настроена скрипка в настоящее время, в основном то, что я хочу. Пользователь щелкает цвета, и он переключается между черным, красным, зеленым, синим и снова возвращается к черному. Однако есть нюанс!

Представьте, что черный цвет является значением по умолчанию/пустым, а цвета (красный, зеленый и синий) являются различными вариантами. Если значение уже имеет цвет, когда пользователь щелкает его, оно снова становится черным. Если он черный, когда пользователь щелкает по нему, он циклически переключает цвета.

Вот в чем загвоздка...

С того момента, как они нажимают черный (и он становится красным), запускается таймер на 2 секунды. Если пользователь не нажмет в течение 2 секунд, то в следующий раз, когда он нажмет, он станет черным (значение по умолчанию/пустое). Но каждый раз, когда они продолжают нажимать, чтобы переключаться между цветами (включая возвращение к черному), этот таймер снова сбрасывается на 2 секунды.

Наконец, если вы щелкнете по черному блоку, чтобы он стал красным, а затем по другому блоку, а затем вернетесь к предыдущему, он станет черным (а не циклическим) именно потому, что вы щелкнули вдали от предыдущего блока, который получает избавиться от таймера.

Я знаю, что это много, но я чувствую, что кое-что, с такой простой концепцией, не должно быть t̲o̲o̲ h̲a̲r̲d̲ понять, но по какой-то причине я просто не могу обернуть мой разум вокруг него. Наверное, это глупо просто.

Помоги мне Оби Ван Stackoverflow (я?) ... ты моя единственная надежда!


person Scott J Freeman    schedule 24.04.2013    source источник


Ответы (1)


Вам нужно будет сделать что-то вроде этого:

$('.square').click(function(e) {
    var $this = $(this);
    if ($this.hasClass('timer-on') || $this.hasClass('square0')) {
        if ($this.hasClass('square0')) {
            $this.removeClass('square0').addClass('square1');
        } else if ($this.hasClass('square1')) {
            $this.removeClass('square1').addClass('square2');
        } else if ($this.hasClass('square2')) {
            $this.removeClass('square2').addClass('square3');
        } else if ($this.hasClass('square3')) {
            $this.removeClass('square3').addClass('square1');
        };
    } else {
        $this.addClass('square0').removeClass('square1 square2 square3');
    };

    clearTimeout($this.data('timer'));
    $this.addClass('timer-on').data('timer', setTimeout(function () {
        $this.removeClass('timer-on');
    }, 2000));
});

http://jsfiddle.net/mblase75/bF5Re/

Ваши операторы return false были совершенно ненужными и мешали последующему коду, поэтому я удалил их и заменил ваши последующие операторы if на else if.

Уловка, которую я использовал, состоит в том, чтобы добавить класс timer-on, когда запускается двухсекундный таймер, и удалить его, когда таймер закончится. Теперь нам просто нужно проверить наличие timer-on, чтобы узнать, истек ли таймер.

Функция setTimeout возвращает идентификатор, который можно очистить с помощью clearTimeout, поэтому мы сохраняем этот идентификатор в элементе, по которому щелкнули, используя .data(), и сбрасываем его при каждом щелчке, чтобы перезапустить таймер.

person Blazemonger    schedule 24.04.2013