2014-12-17 4 views
0

Я использую комбинацию jQuery и ванильного JavaScript для слайдера, над которым я работаю. Я бы, наверное, попытался поместить это в один плагин jQuery, но мне не хватало знаний о плагинах jQuery и им еще предстоит их изучить.Создание глобальной переменной settimeout

Проблема, с которой я столкнулся, заключается в том, что моя переменная settimeout не является глобальной для функций jQuery и vanilla.

Это проблема, потому что мне нужно очистить таймаут в определенных ситуациях. Пример: когда пользователь нажимает кнопку навигации или стрелку, он должен очистить текущий тайм-аут и начать его.

Вот код:

$(document).ready(function() { 

    /* slider */ 

    if ($('.slider').length) 
    { 
     // setttings 
     $caption_speed = 500; 
     $slide_speed = 5000; 

     // get slider height (px) 
     $height = $('.slider .slides').outerHeight(); 

     // set top of all captions to slider height so they can be animated upwards 
     $('.slider .slides li .caption').css('top', $height+'px'); 

     // get total slides 
     $slides = $('.slider .slides li').length - 1; 
     $active = 0; 

     // show first slide caption 
     captionActive($active, $caption_speed); 
     $timeout = setTimeout(function() { nextSlide('right', $slides, $height, $caption_speed, $slide_speed, 'null'); }, $slide_speed); 

     // pause slider if person mouses over caption, arrows, or nav 
     $('.slider .slides li .caption, .slider .slide-arrows li, .slider .slide-nav').mouseover(function() { 
      clearTimeout($timeout); 
     }); 
     $('.slider .slides li .caption, .slider .slide-arrows li, .slider .slide-nav').mouseout(function() { 
      $timeout = setTimeout(function() { nextSlide('right', $slides, $height, $caption_speed, $slide_speed, 'null'); }, $slide_speed); 
     }); 

     // do arrow actions when clicked 
     $('.slide-arrows li').click(function() { 
      $direction = $(this).attr('class'); 
      nextSlide($direction, $slides, $height, $caption_speed, $slide_speed, 'null'); 
     }); 

     // do nav actions when clicked 
     $('.slider .slide-nav li').click(function() { 
      $number = $(this).index(); 
      nextSlide('right', $slides, $height, $caption_speed, $slide_speed, $number); 
     }); 
    } 

}); 

function captionActive (active, caption_speed) 
{ 
    $caption = $('.slider .slides li:eq('+active+') .caption'); 
    $cheight = $caption.outerHeight(); 
    $top = ($height - $cheight)/2;   
    $caption.animate({opacity: 1, top: $top}, caption_speed, function() {}); 
    $('.slider .slide-nav li:eq('+active+')').addClass('active');  
} 

function nextSlide (direction, slides, height, caption_speed, slide_speed, next) 
{ 
    clearTimeout($timeout); 

    // get active slide # 
    $active = $('.slider .slide-nav .active').index(); 
    $active_slide = $('.slider .slides li:eq('+($active)+')'); 
    $('.slider .slide-nav .active').removeClass('active'); 

    if (next != 'null') 
     $next = next; 
    else if (direction == 'left')  
     $next = $active - 1; 
    else 
     $next = $active + 1; 

    // check if next exists, otherwise make first next 
    if (!$('.slider .slides li:eq('+($next)+')').length) 
     $next = 0; 

    $next_slide = $('.slider .slides li:eq('+($next)+')'); 
    $next_slide.css('z-index', '99'); 

    // fade out caption 
    $caption = $('.slider .slides li:eq('+$active+') .caption'); 
    $caption.animate({opacity: 0, top: height}, caption_speed, function() {}); 
    $active_slide.animate({opacity: 0}, caption_speed, function() { 
     $active_slide.css({'z-index' : '0', 'opacity' : '100'}); 
     $next_slide.css('z-index', '100'); 
     // fade in new caption & set nav element active 
     captionActive($next, caption_speed); 
     $timeout = setTimeout(function() { nextSlide('right', slides, height, caption_speed, slide_speed, 'null'); }, slide_speed); 
    }); 
} 

Смотрите следующую строку в функции nextSlide:

clearTimeout($timeout); 

Это не похоже, чтобы очистить тайм-аут. Тайм-ауты выглядят как укладки при нажатии на .slide-arrows li или .slider .slide-nav li.

Любая помощь была бы принята с благодарностью.

ответ

0

Ваша переменная $timeout, безусловно, доступна по всему миру - как и все ваши переменные - поскольку в вашем коде не используется ключевое слово var. Это означает, что все ваши переменные являются глобальными. (Это не очень хорошая практика, но не имеет отношения к этому вопросу.)

Кажется, что ваш вопрос на самом деле, что в вашей nextSlide функции, то setTimeout не не вызывается, пока ваш animate завершается. Если вы снова вызовете функцию до завершения animate, то отменить нечего. Затем оба анимата завершатся, создавая два таймаута.

Что вы должны сделать, это вызвать clearTimeout непосредственно перед установкой тайм-аут:

$active_slide.animate({opacity: 0}, caption_speed, function() { 
    /* ... */ 

    if($timeout) clearTimeout($timeout); 

    $timeout = setTimeout(function() { nextSlide('right', slides, height, caption_speed, slide_speed, 'null'); }, slide_speed); 
}); 

Это гарантирует, что тайм-аут очищается перед созданием нового тайм-аута.