Javascript 触摸屏 OnMouseOver 的首选替代方案
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4550427/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Preferred Alternative to OnMouseOver for touch
提问by Daniel Nill
Is there a preferred alternative or best practice for handling OnMouseOver javascript events on touch devices? All I can think is to convert all events to OnMouseClick. Unfortunately this muddles the differences between events triggered by hovering the cursor and events triggered by clicking the cursor.
在触摸设备上处理 OnMouseOver javascript 事件是否有首选的替代方法或最佳实践?我所能想到的就是将所有事件转换为 OnMouseClick。不幸的是,这混淆了悬停光标触发的事件和单击光标触发的事件之间的差异。
Are there any alternatives, or work arounds, that are less disruptive to the UX of a webpage that will be used with both mouse devices and touch devices?
是否有任何替代方法或变通方法对将与鼠标设备和触摸设备一起使用的网页的 UX 破坏性较小?
采纳答案by Michiel Kalkman
Is there a preferred alternative or best practice for handling OnMouseOver javascript events on touch devices?
在触摸设备上处理 OnMouseOver javascript 事件是否有首选的替代方法或最佳实践?
The short answer is no.
最简洁的答案是不。
Device-specific events don't have a 1:1 mapping to events from other devices. There is no proper equivalent of 'hovering' when using Touch.
特定于设备的事件与来自其他设备的事件没有 1:1 映射。使用 Touch 时没有适当的“悬停”等价物。
Mouse events (mouseover, mouseout, mousedown, mouseup, mousemove, etc) are specific to the mouse input device. The keyboard has keydown, keypressand keyup. Touch has touchstart, touchmove, touchendand touchcancel. Webkit on the iPhone/iPad/etc has additional gesture start/move/endevents that are Apple-specific.
鼠标事件(mouseover、mouseout、mousedown、mouseup、mousemove等)特定于鼠标输入设备。键盘有keydown、keypress和keyup。触摸有touchstart、touchmove、touchend和touchcancel。iPhone/iPad/etc 上的 Webkit 具有Apple 特定的附加手势开始/移动/结束事件。
Higher-level, generic events such as focus, blur, click, submit, etc can be triggered by one of these events. A clickevent, for example, can be triggered using a mouse, touch or keyboard event. (click, btw, is an event with an inappropriate name, which should more properly be called actionbut because of its Mouse history is still called click).
这些事件之一可以触发更高级别的通用事件,例如focus、blur、click、submit等。一个点击事件,例如,可以使用鼠标,触摸或键盘事件触发。(click,顺便说一句,是一个名称不合适的事件,应该更恰当地称为action但由于其鼠标历史记录仍称为click)。
The preferred (or 'One Web') approach is using the Mouse events for mouse specific things where you can't avoid them and and sticking to the generic events for everything else.
首选(或“One Web”)方法是将鼠标事件用于您无法避免的鼠标特定事件,并坚持使用通用事件处理其他所有事件。
Depending on the WebKit build and the flags used to build it you can trigger some Mouse eventson some Touch interfacesin some special cases, but you really don't want to build your UI on that because the only reason these cases exist is to allow mobile-Webkit to get traction in the market.
根据 WebKit 构建和用于构建它的标志,您可以在某些特殊情况下在某些触摸界面上触发一些鼠标事件,但您真的不想在其上构建您的 UI,因为这些情况存在的唯一原因是允许mobile-Webkit 在市场上获得吸引力。
Touch Events are also inconsistent across platforms. Take a look at ppk's work for some reference if you're doing any mobile/touch stuff, http://quirksmode.org/mobile/tableTouch.html
跨平台的触摸事件也不一致。如果您正在做任何移动/触摸操作,请查看 ppk 的工作以获取一些参考,http://quirksmode.org/mobile/tableTouch.html
回答by Nelson
The onmouseover/onmouseout javascript events would translate to the touchenter/touchleave touch events, the problem is these events are just starting to being implemented in browsers (they are part of a W3C draft), currently only firefox support it, so if you are using webkit you'll have to wait for it, or implement your onmouseover feature using touchmove event and looking at the coordinates and to see if they overlap with the coordinates of your html element.
onmouseover/onmouseout javascript 事件会转化为 touchenter/touchleave 触摸事件,问题是这些事件才刚刚开始在浏览器中实现(它们是W3C 草案的一部分),目前只有 Firefox支持它,所以如果你正在使用webkit,您将不得不等待它,或者使用 touchmove 事件实现您的 onmouseover 功能并查看坐标并查看它们是否与您的 html 元素的坐标重叠。
回答by Gustav Barkefors
Depending on your demands and targeted users, you may be interested in the touch JS APIs available (at least) on mobile Safari and Chrome. Check http://backtothecode.blogspot.com/2009/10/javascript-touch-and-gesture-events.html, for a quick (perhaps a bit dated) intro. I haven't really used these extensively (only targeting iPhone, for instance) but I've been very happy with the results I've gotten so far.
根据您的需求和目标用户,您可能对移动 Safari 和 Chrome 上可用的(至少)触摸 JS API 感兴趣。检查http://backtothecode.blogspot.com/2009/10/javascript-touch-and-gesture-events.html,快速(可能有点过时)介绍。我还没有真正广泛地使用这些(例如,仅针对 iPhone),但我对到目前为止获得的结果感到非常满意。
回答by Moshe Jonathan Gordon Radian
I think I managed to create a good simulation (at least for a specific event handler I wanted to simulate) by combining the 'touchmove' event handler and calling the elementFromPoint() method using the coordinates (stored in the clientX / clientY properties of the object) of the relevant Touch object in the event (I used e.touches[0]).
我想我设法通过组合“touchmove”事件处理程序并使用坐标调用 elementFromPoint() 方法(存储在事件中相关 Touch 对象的对象)(我使用了 e.touches[0])。
For a more detailed answer, see my answer for this user's specific use case (filling the cells of a table) based on a solution to my own problem (toggling checkbox states) here: https://stackoverflow.com/a/31711040/1941313.
有关更详细的答案,请参阅我对此用户的特定用例(填充表格的单元格)的答案,该答案基于我自己的问题(切换复选框状态)的解决方案:https: //stackoverflow.com/a/31711040/ 1941313。
Alternatively, read the full report I wrote about finding the write event handler design including the sources of for my findings in the following gist: https://gist.github.com/VehpuS/6fd5dca2ea8cd0eb0471
或者,阅读我写的关于查找写入事件处理程序设计的完整报告,包括我在以下要点中发现的来源:https: //gist.github.com/VehpuS/6fd5dca2ea8cd0eb0471
(I would have posted them in stackoverflow but my rep is too low at the moment so I can only provide two links :P)
(我会在 stackoverflow 中发布它们,但我的代表目前太低,所以我只能提供两个链接:P)
Hope this helps!
希望这可以帮助!
回答by WoodrowShigeru
Unfortunately I do not know about best practices or a preferredalternative to onmouseover
on touch-devices, but in encountering the same question I ended up developing this vanillaJS solution where I count the milliseconds between onmouseenter
and onclick
, and am therefore able to distinguish between desktop-clicking and mobile-clicking.
不幸的是我不知道的最佳做法或最佳替代onmouseover
触摸的设备,但在遇到相同的问题,我结束了开发这一vanillaJS解决方案,我算的毫秒onmouseenter
和onclick
,和我因此能够桌面点击并区分移动点击。
Upon investigating the two events in the desktop vs. mobile environments, I discovered that a mobile touch natively fires both events instantly (both within zero milliseconds), in contrast to the small desktop-delay of a few dozen milliseconds, depending on the user's trigger-happiness.
在调查桌面与移动环境中的两个事件时,我发现移动触摸本机立即触发这两个事件(均在零毫秒内),与几十毫秒的小桌面延迟形成对比,这取决于用户的触发-幸福。
;(function(){
let
hover_on_mobile = {
timer: 0,
// I don't trust the timer with this,
// so I'm counting myself:
milliseconds: 0,
// also cover the case of the user
// mouseentering, reading or otherwise
// waiting, and clicking *then*.
is_counting: false,
},
item = document.querySelector('.mobile-hoverable')
;
hover_on_mobile.reset = function(){
clearInterval(hover_on_mobile.timer);
hover_on_mobile.milliseconds = 0;
hover_on_mobile.is_counting = false;
};
// hover.
item.onmouseenter = function(){
// preparation for onclick's touch-click detection.
hover_on_mobile.is_counting = true;
// count the milliseconds starting on each
// mouseenter anew.
hover_on_mobile.timer = window.setInterval(function() {
// we only need the first few milliseconds for
// our touch-click detection.
if (hover_on_mobile.milliseconds > 50) {
hover_on_mobile.reset();
} else {
hover_on_mobile.milliseconds++;
}
}, 1);
hover_behavior();
};
// click.
item.onclick = function(ev){
let
condition1 = hover_on_mobile.milliseconds < 10,
condition2 = hover_on_mobile.is_counting
;
console.log('clicked', {
condition1: condition1,
condition2: condition2,
timer: hover_on_mobile.timer,
milliseconds: hover_on_mobile.milliseconds,
is_counting: hover_on_mobile.is_counting,
});
// touch-click detection.
if (condition1 && condition2) {
// don't do anything; let the onmouseenter
// do the hover routine unhinderedly.
//
// if this was an onclick event on an ?a? tag,
// the ev.preventDefault(); call would go here.
} else {
click_behavior();
}
hover_on_mobile.reset();
};
// ----------------------------------------
// fiddle-specfic.
// reset indicator, not hover_on_mobile.
item.onmouseout = reset_indicator;
function click_behavior() {
document.querySelector('#indicator .click-text').innerText = 'clicked';
}
function hover_behavior() {
document.querySelector('#indicator .hover-text').innerText = 'hovered';
}
function reset_indicator() {
document.querySelector('#indicator .hover-text').innerText = '-';
document.querySelector('#indicator .click-text').innerText = '-';
}
document.querySelector('#indicator .reset').onclick = reset_indicator;
})();
h1 {
font-size: 20px;
line-height: 26px;
}
#indicator {
margin-top: 15px;
padding: 20px;
background-color: #ddd;
}
.mobile-hoverable {
cursor: pointer;
background-color: antiquewhite;
border: 1px outset blanchedalmond;
border-radius: 4px;
padding: 10px;
}
.notes {
font-style: italic;
font-size: 14px;
}
<div class="root">
<h1>Imagine you wanted mobile users to click once in order to simulate a desktop-hover and twice for a desktop-click</h1>
<div class="mobile-hoverable">Hover me, click me, compare with mobile-touch device mode.</div>
<div id="indicator">
<button class="reset">Reset</button>
<span class="hover-text">-</span>
<span class="click-text">-</span>
</div>
<ul class="notes">
<li>Don't forget to reload the page after changing the mode, for optimal testing evaluation.</li>
<li>Click event console.logs hover_on_mobile object.</li>
<li>The fiddle's CSS is irrelevant for this feature.</li>
<li>Relevant JavaScript is bundled together; irrelevant JavaScript at the end.</li>
<li>Didn't test browser compatibility specifically for this fiddle but the feature works in Chrome, Firefox, Safari, IE10+.</li>
<li>Subsequent clicks without onmouseout will only fire the click event, in both environments.</li>
</ul>
</div>
(… or alternatively as a fiddle)
(......或者作为小提琴)
Here is another fiddleto showcase specifically the timing difference between desktop and mobile environments.