it-swarm.com.ru

onclick и ontouchstart одновременно

В моем мобильном представлении сработало событие ontouchstart, связанное с этим:

function mobileLinksShow() {
    document.querySelector('.mobile-head-bar-links').classList.toggle('mobile-head-bar-links-transition');
}

На моем устройстве (iPhone 5), когда я нажимаю на кнопку, он дважды переключается, и поэтому он расширяется, а затем сжимается. Это из-за одновременного срабатывания onclick и ontouchstart. Удаление onclick решает проблему на мобильном телефоне, но теперь браузер настольного компьютера явно не работает, есть ли способ подавить onclick на мобильном телефоне?

HTML:

<span class='mobile-head-bar-left' ontouchstart='mobileLinksShow()' onclick='mobileLinksShow()' ><i class="fa fa-bars"></i></span>

CSS:

.mobile-head-bar-links {
    height: 0;
    overflow: hidden;
    background-color: #F76845;
    transition: .5s ease;
    -webkit-transition: .5s ease;
}

.mobile-head-bar-links-transition {
    height: 7em;
}

NB. Я не хочу использовать JQuery.

8
user3105607

Нашли обходной путь, протестировав тип браузера и удалив соответствующим образом: 

function removeMobileOnclick() {
    if(isMobile()) {
        document.querySelector('.mobile-head-bar-left').onclick  = '';
    }
}

function isMobile() {
    if (navigator.userAgent.match(/Android/i)
            || navigator.userAgent.match(/iPhone/i)
            || navigator.userAgent.match(/iPad/i)
            || navigator.userAgent.match(/iPod/i)
            || navigator.userAgent.match(/BlackBerry/i)
            || navigator.userAgent.match(/Windows Phone/i)
            || navigator.userAgent.match(/Opera Mini/i)
            || navigator.userAgent.match(/IEMobile/i)
            ) {
        return true;
    }
}
window.addEventListener('load', removeMobileOnclick);

Таким образом, вы можете иметь как onclick, так и ontouchstart не мешая 

функция isMobile взята из Обнаружение мобильных устройств и часть webOS удалена, поскольку браузер настольного компьютера считался мобильным.

7
user3105607

Вы можете привязать функцию к ontouchstart, которая вызывает все, что связано с onclick, но затем запрещает использование по умолчанию, чтобы она фактически не вызывала onclick.

Затем вы можете легко скопировать и вставить это событие ontouchstart во все места, где вы используете onclick.

<span class='mobile-head-bar-left' ontouchstart='touch_start(event)' onclick='mobileLinksShow()' ><i class="fa fa-bars"></i></span>

<script>
function touch_start(e){
  e.preventDefault();
  e.target.onclick();
}
</script>
2
Stuffe

Мне просто пришла в голову идея просто запомнить, когда ontouchstart когда-либо срабатывал. В этом случае мы находимся на устройстве, которое его поддерживает, и хотим игнорировать событие onclick. Поскольку ontouchstart всегда должен запускаться перед onclick, я использую это:

<script> touchAvailable = false; </script>
<button ontouchstart="touchAvailable=true; myFunction();" onclick="if(!touchAvailable) myFunction();">Button</button>

1
jakob.j

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

Правильное решение - правильно пометить событие касания как обработанное с помощью protectDefault, тогда событие щелчка не будет сгенерировано. Например.

function mobileLinksShow(event) {
  document.querySelector('.mobile-head-bar-links').classList.toggle('mobile-head-bar-links-transition');
  event.preventDefault();
}

Смотрите http://www.html5rocks.com/en/mobile/touchandmouse/ для подробностей.

0
Rick Byers

Вы можете написать это так:

var called = false;
function mobileLinksShow() {
    if(!called)
        document.querySelector('.mobile-head-bar-links').classList.toggle('mobile-head-bar-links-transition');
        called = true;
    }
}

Но: Если вы используете этот код, функция может быть вызвана только один раз, даже если вы дважды щелкнете по диапазону.

0
maja