有一些 HTML 如下:
<p>Some Text</p>
然后添加以下 CSS:
p {
color:black;
}
p:hover {
color:red;
}
如何在触控设备上允许长按来复制悬停效果?我可以更改标记/使用JS等,但是想不到一个简单的方法来实现这一点。
有一些 HTML 如下:
<p>Some Text</p>
然后添加以下 CSS:
p {
color:black;
}
p:hover {
color:red;
}
如何在触控设备上允许长按来复制悬停效果?我可以更改标记/使用JS等,但是想不到一个简单的方法来实现这一点。
好的,我已经弄明白了!它涉及到稍微更改一下CSS并添加一些JS。
使用jQuery可以使其更容易:
$(document).ready(function() {
$('.hover').on('touchstart touchend', function(e) {
e.preventDefault();
$(this).toggleClass('hover_effect');
});
});
hover_effect
的样式。element:hover {
rule:properties;
}
使用
element:hover, element.hover_effect {
rule:properties;
}
为了增加实用性,还可以将以下内容添加到您的CSS中:
.hover {
-webkit-user-select: none;
-webkit-touch-callout: none;
}
toggle
会使事情变得混乱。 - Jacksonkrtouchstart
监听器,但我想知道是否有更好的方法。谢谢! - Darryl Younguser-select
和 touch-callout
的修复功能。大约一年前,我曾经拼命寻找这种功能,但却无处可找。 - myfunkyside你所需做的就是在父元素上绑定touchstart事件。像下面这样写即可:
$('body').on('touchstart', function() {});
你不需要在函数中做任何事情,将其留空即可。这样就足以获得触摸悬停效果,因此触摸行为更像:hover而不是:active。iOS魔法。
试试这个:
<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 类!
然后在CSS的:active事件中添加一个小计时器:
tr:active {
background-color:#118aab;
transition:all .2s linear;
-webkit-tap-highlight-color:rgba(0,0,0,0);
-webkit-user-select:none;
-webkit-touch-callout:none
} - Kozyhover
事件即可。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/
如果你想使用“长按”来触发悬停效果,你可以以上面的代码片段为起点,玩弄定时器等东西 :)
起初我采用了Rich Bradshaw 的方法,但问题开始出现。通过在'touchstart'事件上使用e.preventDefault(),页面不再滚动,长按也无法触发选项菜单,双击缩放也无法完成执行。
一个解决方案是找出正在被调用的事件,并仅在后续事件'touchend' 中使用 e.preventDefault()。由于滚动的'touchmove' 在'touchend' 之前进行,默认情况下保持不变,而'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');
});
但是,当选项菜单出现时,它不再触发负责切换类的'touchend'事件,下一次悬停行为将完全混乱无序。
解决方案是,再次条件性地找出我们处于哪个事件中,或者只是分别使用 addClass() 和 removeClass() 在 'touchstart' 和 'touchend' 上,确保始终通过添加和删除来开始和结束,而不是有条件地决定。最后,我们还将把删除回调绑定到 '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(不混合使用.hover类和伪类:hover),您可以直接在通用(移动和桌面)的'click'事件上调用您的ajax行为。我发现了一个回答得相当好的问题,最终理解了如何将触摸和鼠标事件混合在一起,而不需要多个事件回调必然改变彼此在事件链上的回调函数。下面是具体实现方法:
$('.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's the chain's last event we only prevent it from making HTTP request
if (e.type == 'click') {
e.preventDefault ? e.preventDefault() : e.returnValue = false;
// Ajax behavior here!
}
});
p:active {
color:red;
}
添加以下代码,然后将类“tapHover”设置为您希望以此方式工作的元素。 第一次轻触元素时,它将获得伪类“:hover”和类“tapped”。单击事件将被阻止。 第二次轻触相同的元素-单击事件将被触发。
// 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>
我个人的喜好是将:hover
样式也应用到:focus
状态,例如:
p {
color: red;
}
p:hover, p:focus {
color: blue;
}
<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's a double tap
$elem.blur()
}
else {
$elem.focus();
}
});
没有特定于设备(或浏览器)的JS,我相信你运气不佳。
编辑:我以为你想避免这种情况,直到我重新阅读了你的问题。在移动Safari的情况下,您可以注册以获取所有触摸事件,类似于您可以使用本机UIView-s做的事情。现在找不到文档,但会尝试。
一种方法是在触摸开始时执行悬停效果,然后在触摸移动或结束时删除悬停效果。
这是苹果关于触摸处理的一般说法,因为您提到了iPhone。