Как имитировать зависание с браузерами с сенсорным экраном?
С некоторым HTML следующим образом:
<p>Some Text</p>
Затем некоторые CSS вроде этого:
p {
color:black;
}
p:hover {
color:red;
}
Как я могу позволить длинному касанию на устройстве с сенсорным экраном реплицировать зависание? Я могу изменить разметку/использование JS и т.д., Но не могу придумать простой способ сделать это.
Ответы
Ответ 1
Хорошо, я решил это! Это предполагает небольшое изменение CSS и добавление JS.
Использование jQuery для упрощения:
$(document).ready(function() {
$('.hover').on('touchstart touchend', function(e) {
e.preventDefault();
$(this).toggleClass('hover_effect');
});
});
По-английски: когда вы начинаете или заканчиваете касание, включите или выключите класс hover_effect
.
Затем в своем HTML добавьте наведение класса ко всему, с чем вы хотите, чтобы это работало. В вашем CSS замените любой экземпляр:
element:hover {
rule:properties;
}
с
element:hover, element.hover_effect {
rule:properties;
}
И просто для большей полезности, добавьте это и в свой CSS:
.hover {
-webkit-user-select: none;
-webkit-touch-callout: none;
}
Чтобы остановить браузер, просит вас скопировать/сохранить/выбрать изображение или что-то еще.
Легко!
Ответ 2
Все, что вам нужно сделать, это привязать сенсорный запуск к родителю. Примерно так будет работать:
$('body').on('touchstart', function() {});
Вам не нужно ничего делать в функции, оставьте это пустым. Этого будет достаточно, чтобы навести курсор на прикосновение, поэтому прикосновение ведет себя больше как: hover и менее похоже: active. iOS волшебство.
Ответ 3
Попробуйте следующее:
<script>
document.addEventListener("touchstart", function(){}, true);
</script>
И в вашем CSS:
element:hover, element:active {
-webkit-tap-highlight-color: rgba(0,0,0,0);
-webkit-user-select: none;
-webkit-touch-callout: none /*only to disable context menu on long press*/
}
С помощью этого кода вам не нужен дополнительный класс .hover!
Ответ 4
Чтобы ответить на ваш основной вопрос: "Как смоделировать зависание с браузерами с сенсорным экраном?"
Просто позвольте "щелкнуть элемент (нажав экран), а затем запустить событие hover
с помощью JavaScript.
var p = document.getElementsByTagName('p')[0];
p.onclick = function() {
// Trigger the `hover` event on the paragraph
p.onhover.call(p);
};
Это должно работать, если на вашем устройстве существует событие hover
(хотя оно обычно не используется).
Обновление: Я просто тестировал эту технику на своем iPhone и, похоже, работал нормально. Попробуйте здесь: http://jsfiddle.net/mathias/YS7ft/show/light/
Если вы хотите использовать "длинное касание" для запуска наведения вместо этого, вы можете использовать приведенный выше фрагмент кода в качестве отправной точки и получать удовольствие от таймеров и прочее;)
Ответ 5
Дальнейшее усовершенствованное решение
Сначала я пошел с подходом Rich Bradshaw, но затем начали появляться проблемы. Выполняя e.preventDefault() событие "touchstart" , страница больше не прокручивается, и ни одно длинное нажатие не может запускать меню опций, а не дважды увеличивать масштаб изображения может завершить выполнение.
Решением может быть выяснение, какое событие вызывается, и только e.preventDefault() в более позднем, 'touchhend'. Поскольку прокрутка 'touchmove' предшествует 'touchhend', она остается по умолчанию, а также 'click', так как это происходит после слов в цепочка событий, применяемая к мобильному телефону, например:
// Binding to the '.static_parent' ensuring dynamic ajaxified content
$('.static_parent').on('touchstart touchend', '.link', function (e) {
// If event is 'touchend' then...
if (e.type == 'touchend') {
// Ensuring we event prevent default in all major browsers
e.preventDefault ? e.preventDefault() : e.returnValue = false;
}
// Add class responsible for :hover effect
$(this).toggleClass('hover_effect');
});
Но тогда, когда появляется меню опций, оно больше не срабатывает "touchhend" , ответственное за переключение класса, и в следующий раз поведение наведения будет наоборот, полностью перепутано.
Тогда решение также будет условно выяснять, какое событие мы находим, или просто делать отдельные, и использовать addClass() и removeClass() соответственно 'touchstart' и 'touchhend', гарантируя, что он всегда начинается и заканчивается добавлением и удалением, вместо того, чтобы условно решать его. Для завершения мы также привяжем удаление обратного вызова к типу события "focusout" , оставаясь ответственным за очистку любого класса привязки ссылок, который может оставаться включенным и никогда не повторять снова, например:
$('.static_parent').on('touchstart', '.link', function (e) {
$(this).addClass('hover_effect');
});
$('.static_parent').on('touchend focusout', '.link', function (e) {
// Think double click zoom still fails here
e.preventDefault ? e.preventDefault() : e.returnValue = false;
$(this).removeClass('hover_effect');
});
Внимание: Некоторые ошибки все еще встречаются в двух предыдущих решениях, а также думают (не тестируются), двойной щелчок по-прежнему не удается.
Упорядочить и надеяться Ошибка (не:)) Javascript Solution
Теперь, на секунду, более чистый, более аккуратный и отзывчивый подход, просто используя javascript (без сочетания между классом .hover и псевдо-зависанием), и откуда вы можете напрямую вызвать свое поведение ajax на универсальное (мобильное и настольное) событие 'click', я нашел довольно хорошо ответивший вопрос, из которого я наконец понял, как я мог бы смешивать события touch и mouse вместе без нескольких обратных вызовов событий, неизбежно изменяющих друг друга в цепочке событий. Вот как:
$('.static_parent').on('touchstart mouseenter', '.link', function (e) {
$(this).addClass('hover_effect');
});
$('.static_parent').on('mouseleave touchmove click', '.link', function (e) {
$(this).removeClass('hover_effect');
// As it the chain last event we only prevent it from making HTTP request
if (e.type == 'click') {
e.preventDefault ? e.preventDefault() : e.returnValue = false;
// Ajax behavior here!
}
});
Ответ 6
Эффект мыши hover
не может быть реализован в сенсорном устройстве. Когда я появлялся с той же ситуацией в safari
ios
, я использовал :active
в css для создания эффекта.
т.
p:active {
color:red;
}
В моем случае его работа. Может быть, это также случай, который можно использовать без использования javascript. Просто попробуйте.
Ответ 7
Добавьте этот код, а затем установите класс "tapHover" в элементы, которые вы хотели бы работать таким образом.
В первый раз, когда вы нажимаете элемент, он будет получать псевдоклассы ": hover" и class "tapped". Событие Click будет предотвращено.
Второй раз, когда вы нажимаете тот же элемент - событие click будет запущено.
// Activate only in devices with touch screen
if('ontouchstart' in window)
{
// this will make touch event add hover pseudoclass
document.addEventListener('touchstart', function(e) {}, true);
// modify click event
document.addEventListener('click', function(e) {
// get .tapHover element under cursor
var el = jQuery(e.target).hasClass('tapHover')
? jQuery(e.target)
: jQuery(e.target).closest('.tapHover');
if(!el.length)
return;
// remove tapped class from old ones
jQuery('.tapHover.tapped').each(function() {
if(this != el.get(0))
jQuery(this).removeClass('tapped');
});
if(!el.hasClass('tapped'))
{
// this is the first tap
el.addClass('tapped');
e.preventDefault();
return false;
}
else
{
// second tap
return true;
}
}, true);
}
.box {
float: left;
display: inline-block;
margin: 50px 0 0 50px;
width: 100px;
height: 100px;
overflow: hidden;
font-size: 20px;
border: solid 1px black;
}
.box.tapHover {
background: yellow;
}
.box.tapped {
border: solid 3px red;
}
.box:hover {
background: red;
}
<div class="box" onclick="this.innerHTML = Math.random().toFixed(5)"></div>
<div class="box tapHover" onclick="this.innerHTML = Math.random().toFixed(5)"></div>
<div class="box tapHover" onclick="this.innerHTML = Math.random().toFixed(5)"></div>
Ответ 8
Без устройства (или, скорее, браузера) конкретного JS я уверен, что вам не повезло.
Изменить: думал, что вы хотите избежать этого, пока я не перечитаю ваш вопрос. В случае Mobile Safari вы можете зарегистрироваться, чтобы получить все события касания, похожие на то, что вы можете делать с родными UIView-s. Невозможно найти документацию прямо сейчас, попытайтесь хотя.
Ответ 9
Один из способов сделать это - сделать эффект зависания, когда начнется прикосновение, а затем удалить эффект зависания, когда касание движется или заканчивается.
Это то, что Apple может сказать о touch handling в целом, поскольку вы упоминаете iPhone.
Ответ 10
Мой личный вкус заключается в атрибуте стилей :hover
в состоянии :focus
, например:
p {
color: red;
}
p:hover, p:focus {
color: blue;
}
Затем со следующим HTML:
<p id="some-p-tag" tabindex="-1">WOOOO</p>
И следующий JavaScript:
$("#some-p-tag").on("touchstart", function(e){
e.preventDefault();
var $elem = $(this);
if($elem.is(":focus")) {
//this can be registered as a "click" on a mobile device, as it a double tap
$elem.blur()
}
else {
$elem.focus();
}
});
Ответ 11
Сочетание собственных Javascript и jQuery:
var gFireEvent = function (oElem,sEvent)
{
try {
if( typeof sEvent == 'string' && o.isDOM( oElem ))
{
var b = !!(document.createEvent),
evt = b?document.createEvent("HTMLEvents"):document.createEventObject();
if( b )
{ evt.initEvent(sEvent, true, true );
return !oElem.dispatchEvent(evt);
}
return oElem.fireEvent('on'+sEvent,evt);
}
} catch(e) {}
return false;
};
// Next you can do is (bIsMob etc you have to determine yourself):
if( <<< bIsMob || bIsTab || bisTouch >>> )
{
$(document).on('mousedown', function(e)
{
gFireEvent(e.target,'mouseover' );
}).on('mouseup', function(e)
{
gFireEvent(e.target,'mouseout' );
});
}
Ответ 12
Самое простое решение, которое я нашел: у меня было несколько <span> с помощью правил hover css. Я переключился на < a href= "javascript: void (0)" > и voilà. Стили стирания в iOS начали работать.
Ответ 13
Использование может также использовать CSS, добавить фокус и активный (для IE7 и ниже) к скрытой ссылке. Пример меню ul внутри div с меню класса:
.menu ul ul {display:none; position:absolute; left:100%; top:0; padding:0;}
.menu ul ul ul {display:none; position:absolute; top:0; left:100%;}
.menu ul ul a, .menu ul ul a:focus, .menu ul ul a:active { width:170px; padding:4px 4%; background:#e77776; color:#fff; margin-left:-15px; }
.menu ul li:hover > ul { display:block; }
.menu ul li ul li {margin:0;}
Поздно и непроверено, должно работать; -)
Ответ 14
Решено 2019 - Hover on Touch
Теперь кажется лучше избегать использования hover вместе с ios или touch вообще. Приведенный ниже код применяет ваш CSS, пока поддерживается касание, и без других всплывающих окон ios. Сделай это;
-
Jquery add: $ ("p"). On ("touchstart", function (e) {$ (this).focus(); e.preventDefault();});
-
CSS: замените p: hover на p: focus и добавьте p: active
Опции;
-
заменить селектор jquery p на любой класс и т.д.
-
чтобы сохранить эффект, сохраните p: hover и добавьте body {cursor: ponter;}, чтобы касание в любом месте заканчивало его
-
попробуйте события click & mouseover, а также touchstart в одном и том же коде (но не тестировали)
-
удалить e.preventDefault(); чтобы пользователи могли использовать всплывающие окна ios, например, копировать
Заметки
-
только для текстовых элементов, ios может по-разному обрабатывать ввод и т.д.
-
протестировано только на iphone XR ios 12.1.12 и ipad 3 ios 9.3.5 с использованием Safari или Chrome.