Игнорировать jQuery hover (mouseenter, mouseleave) на сенсорных устройствах

Не имея ни мыши, ни указателя, концепция наведения элементов экрана на экране не применима для сенсорных устройств. Со многими веб-сайтами, использующими навигацию по событиям JavaScript или другими целями, некоторые сенсорные устройства 1 реализуют mouseenter, которые будут запускаться одним нажатием. Если обработчик событий также привязан к click, это будет только поднято на втором касании элемента.

Так как функция jQuery hover() внутренне использует mouseenter и mouseleave, элементы с регистрами hover() и click() требуют двух кранов для запуска последнего 2. Для многих случаев использования это именно то, что вы захотите. Тем не менее, в приложениях, где обработка hover() добавляет акцент (всплывающую подсказку, свечение и т.д.) К нависшему элементу, может иметь смысл пропустить событие вместе со всеми сенсорными устройствами, перейдя к обработчику onclick.

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

Есть ли у jQuery такой метод? Любые плагины? Или я что-то не замечаю здесь?


1 Поведение подтверждено на iPad, iPhone и нескольких телефонах Android.

2 Запустите эту JsFiddle demo на рабочем столе и сенсорном устройстве, чтобы увидеть, о чем я говорю.

Ответы

Ответ 1

Мне всегда интересно, что будет с этим делать на гибридных устройствах, поддерживающих события Touch и click/hover. В этом случае, как только вы коснетесь, на странице не будет больше событий наведения или клика. Что происходит, когда пользователь один раз касается экрана (по какой причине когда-либо), а затем, возможно, захочет вернуться с помощью мыши или тачпада? Сайт сломан для него (по крайней мере, если он не решает, следовательно, продолжать с прикосновениями).

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

var touched = false;

$("#someElement")
    .mouseenter( function() {
        if ( !touched ) {
            // some hover action
            // also secure to be in NO WAY triggered on touch device
        };
    }
    .mouseleave( function() {
        if ( !touched ) {
            // some mouse leave reset hover action
            // also secure to be in NO WAY triggered on touch device
        };
    }
    .click( function() {
        if ( !touched ) {
            // do something
            // no double trigger on touch device
        };
    }
    .on( 'touchstart', function() {
        touched = true;
        setTimeout( function() {
            touched = false;
        }, 300 );
        // do touchstart stuff (similar to click or not)
    };

Я не профессиональный кодер. Любому из них предлагается оптимизировать это. На моей веб-странице это, кажется, единственный способ избежать скрытых (двойных) триггеров на сенсорном устройстве (iPad протестирован).

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

В любом случае, это поможет на его пути.

Ответ 2

Я рекомендую использовать Modernizr для обнаружения трогательности устройства и просто не связывать обработчик зависания, если элемент html не имеет класса "без касания":

$('selector').click(...)
$('.no-touch selector').hover(...)

проверить http://jsfiddle.net/juYf8/17/