Все js-слайдеры подвержены одному смешному багу: они ломаются при использовании кнопки Tab. Если на каком-то слайде есть ссылка, слайдер обязательно сломается при переходе на нее табом. Несколько примеров на слайдере, который не ломается (oh, the irony):
Дело в том, что при фокусировании ссылки, скрытой за overflow: hidden, браузер заботлибо промотает вам содержимое блока, чтобы ссылка оказалась в поле зрения. Да, у блоков с overflow: hidden тоже есть scrollLeft, и он работает так же, как и в случае с overflow: auto.
Решение: ловим событие focus внутри слайдов. Когда событие случается, переключаем слайд на тот, в котором произошло событие, и сбрасываем scrollLeft контейнера слайдов. Событие focus не бабблится, поэтому используем капчуринг, чтобы поймать его на уровне слайдов (почитать про бабблинг и капчуринг). Для старых IE используем фоллбек в виде события focusin, которое бабблится.
Выполняем для каждого слайда:
// Сначала фоллбек для старых IE slide.onfocusin=function(){ // Сбрасываем скролл _this.scrollLeft =0; // И еще раз с нулевым таймаутом, потому что в вебките скролл // выставляется позже события. Первый ресет оставляем, чтобы // в других браузерах не дергалось. setTimeout(function(){ _this.scrollLeft =0; },0);
// Переключаем на слайд, к которому привязано событие changeActiveSlide(i); };
// Используем привязанную к `onfocusin` функцию уже // в нормальном `addEventListener` if(slide.addEventListener){ // `true` включает капчуринг slide.addEventListener('focus', slide.onfocusin,true); }
Можно было бы обойтись событием focusin, но Firefox до сих пор не поддерживает его >:(
«Точки» под слайдером тоже должны дружить с клавиатурой. Чтобы не городить огород, достаточно просто сделать их доступными для табуляции (для этого выставляем им аттрибут tabindex="0") и включать нужный слайд по нажатию энтера.
Естественно, при этом нельзя отключать outline вокруг выделенной точки. Чтобы обводка вокруг точки работала при навигации с клавиатуры, но не мешалась при использовании мыши, существует два приема. Первый — убрать outline для псевдокласса :active, чтобы обводки не было во время нажатой кнопки мыши: