注意 有关这些主题的最新概述,请参阅指针事件和手势事件主题。
小心 W3C 指针事件规范自从在 Internet Explorer 10 中实施以来,已经经历了多次修订。此外,截止到 Internet Explorer 11,已弃用了指针事件 API 上的 MS 供应商前缀。请参阅指针事件更新以了解更改和兼容性最佳做法的摘要。
Internet Explorer 10 和适用于 Windows 8 的使用 JavaScript 的 Windows 应用商店应用在 Web 平台中引入了对触控和笔输入处理的支持。Internet Explorer 10 并没有要求你创建代码以分别处理每种类型的输入,而是引入了“指针”的概念。
指针是指屏幕上的任何接触点:可以是鼠标、手指或笔。现在,你只需编写一组封装了鼠标输入、触控输入和笔输入的指针事件,即可轻松地在不同的输入硬件和形式中提供一致的输入体验。
指针事件
与鼠标事件相似,指针事件为每个指针触发向下、移动、向上、悬停和离开等事件:
与鼠标相比,在屏幕上同时可能有多个指针(例如,使用多点触控硬件)。在这些方案中,每个指针事件分别针对每个接触点进行触发,从而更易于构建支持多点触控的网站和应用程序。
指针取消
在使用触控或笔输入时,有时屏幕上的指针可能被取消。例如,如果你的屏幕不支持超过两个同时触控点,而你在屏幕上添加了第三个手指,那么其中一个触控点将被取消,因为硬件不能跟踪三个点。 指针取消由 MSPointerCancel 事件来指定。
鼠标兼容性
在触发指针事件后,Internet Explorer 10 为主触控点触发鼠标事件(例如,屏幕上的第一个手指)。这使现有的基于鼠标事件的网站能够继续运行。
功能检测
以下是检测对指针事件的支持的最佳方法:
if (window.navigator.msPointerEnabled) { // Pointer events are supported. }
请注意此功能检测并不表明设备支持触控或笔输入。相反,它指示该平台将会触发指针事件,无论系统中存在何种硬件。
下面的示例是一个基本的手指绘图应用,该应用通过指针事件来处理鼠标、触控和笔。
<!DOCTYPE html> <html> <head> <title>Scribble touch example</title> <style> html { -ms-touch-action: none; /* Direct all pointer events to JavaScript code. */ } </style> <script> window.addEventListener(‘load‘, function () { var canvas = document.getElementById("drawSurface"), context = canvas.getContext("2d"); if (window.navigator.msPointerEnabled) { canvas.addEventListener("MSPointerMove", paint, false); } else { canvas.addEventListener("mousemove", paint, false); } function paint(event) { // paint a small rectangle every time the event fires. context.fillRect(event.clientX, event.clientY, 5, 5); } }); </script> </head> <body> <canvas id="drawSurface" width="500px" height="500px" style="border:1px solid black;">Canvas isn‘t supported by this browser or document mode</canvas> </body> </html>
触控优化的一般经验
Internet Explorer 10 提供了针对基本触控交互的一般默认处理方式,例如:
- 平移可滚动区域
- 收缩缩放
- 长按上下文菜单
- 触控选择
这些功能可自动工作,从而使网站和应用在默认情况下都提供最佳的触控体验。但是,你可能需要禁用它们以更利于你的体验。
测试触控支持
测试触控功能,并使用 msMaxTouchPoints 属性检测是否支持多点触控。若要检查设备是否支持触控,以及如果支持,支持多少点触控,请使用以下方法:
// To test for touch capable hardware if(navigator.msMaxTouchPoints) { ... } // To test for multi-touch capable hardware if(navigator.msMaxTouchPoints && navigator.msMaxTouchPoints > 1) { ... } // To get the maximum number of points the hardware supports var touchPoints = navigator.msMaxTouchPoints;
平移和缩放
在执行平移和缩放期间,不会触发指针事件。在类似前面的画图应用程序示例的方案中,你可以在一个区域上禁用平移和缩放,这样就可以根据自己的需要使用这些事件。例如,这可通过使用级联样式表 (CSS) 来实现。
.disablePanZoom { -ms-touch-action: none; /* Disables all pan/zoom behaviors and fire pointer events in JavaScript instead. */ }
触控选择
在 Internet Explorer 10 中,你可以通过在文本上方或附近点击来选中一个字。如果你想要禁用文本选择,请按照你在 Windows Internet Explorer 9 中的操作进行。
element.addEventListener("selectstart", function(e) { e.preventDefault(); }, false); // Disables selection
上下文菜单
在 Windows Internet Explorer 中长按某些元素会显示一个固定的视件,指示将要显示的上下文菜单。如果抬起手指,将会显示上下文菜单。如果将手指拖到一边,视件将被取消且不显示该上下文菜单。
如果你想使用自己的上下文菜单,仍可以借助 Internet Explorer 10 来实现。只需在 contextmenu 事件上调用event.preventDefault 并运行代码,即可显示你的上下文菜单。Internet Explorer 自动使你的上下文菜单兼容触控,并在长按时提供相同的提示视件。此示例使用一个 contextmenu 事件检测用户何时按下某个元素、何时长按以及何时放开。当用户抬起手指时,便会引发相关的上下文菜单事件,同时显示一条消息。
<!DOCTYPE html> <html > <head> <title>Touch and hold example</title> <style> #touchspot { width:100px; height:100px; background-color:aquamarine; border:solid 2px black; } </style> </head> <body> <div id="touchspot">Touch and hold me</div> <script> var elm = document.getElementById("touchspot"); elm.addEventListener("contextmenu", function (e) { e.target.innerHTML = "Touch has pressed, held, and lifted, or mouse has been right clicked. Time to show a custom menu."; e.preventDefault(); // Disables system menu }, false); </script> </body> </html>
如果你根本不需要上下文菜单,例如要求用户按下手指持续一段时间的游戏,则可能要禁用默认的上下文菜单和提示视件。若要执行此操作,只需取消两个事件。
// Disables visual element.addEventListener("MSHoldVisual", function(e) { e.preventDefault(); }, false); // Disables menu element.addEventListener("contextmenu", function(e) { e.preventDefault(); }, false);
笔势对象和事件
除了指针事件外,Windows 8 还具有在不同应用程序中以相同的方式识别被称为笔势的复杂交互(例如,收缩、轻扫等)的能力。
注意 本部分中描述的 API 在 Windows 7 中不受支持。
前面示例中使用的 MSGesture 对象支持较高级别的笔势(例如按、平移、点击)而无需你自己捕获每个指针事件。捕获即你需要捕获 onmspointerdown 事件并使用目标(笔势事件所在的对象)配置 MSGesture 对象和 pointerId。如果不实例化及配置 MSGesture 对象,你的元素将只会出发指针事件。
除线性指针事件外,笔势事件还包含其他信息。例如,当用户触摸并立即移开其手指时,会引发 MSGestureTap 事件。如果用户触摸表面并将手指停在此处,则引发 MSGestureHold 事件。
当用户轻扫其手指,则引发 MSGestureStart、MSGestureChange 和 MSGestureEnd 事件。
如果用户快速轻扫并抬起其手指,则引发 MSInertiaStart 事件。
注意 当 MSGestureChange 事件的事件 detail 属性等于 event.MSGESTURE_FLAG_INERTIA 时,你可以检测笔势在何时处于其惯性阶段。
惯性是指你不再接触屏幕后的持续运动。Internet Explorer 10 中内置对笔势对象的惯性支持,并且无需事件处理程序以外的任何其他代码。在 MSGestureEnd 事件引发前,MSInertiaStart 事件后跟一系列 MSGestureChange 事件,具体取决于轻扫的速度。MSInertiaStart 事件仅在满足足够快的清扫速度时引发,并可帮助代码区分慢速移动和快速笔势。
以下是主要笔势事件:
- MSGestureTap 事件
- MSGestureHold 事件
- MSGestureStart 事件
- MSGestureChange 事件
- MSGestureEnd 事件
- MSInertiaStart 事件
传递到每个事件的 MSGestureEvent 对象将返回一些属性,它们可帮助确定正在操作的对象的状态。 若要查看用户是否试图缩放元素或调整元素的大小,请使用 scale 属性。如果用户在屏幕上旋转元素,则可以使用 rotation 属性获取以弧度为单位的旋转角度。这些属性都是在上次 MSGestureEvent 发生后进行了更改。
笔势标志
MSGesture 标志返回事件对象的状态,例如 MSGestureStart、MSGestureChange 或 MSGestureHold。 这些标志是:
- MSGESTURE_FLAG_NONE,无特殊状态。
- MSGESTURE_FLAG_BEGIN,标记笔势事件的开始。
- MSGESTURE_FLAG_END,标记笔势事件的结束。
- MSGESTURE_FLAG_CANCEL,标记已被取消的笔势事件。
- MSGESTURE_FLAG_INERTIA,标记计算机何时处于其惯性阶段。
例如,如果用户在屏幕上清扫其手指,事件和详细信息将做出如下响应:
- MSGestureStart 事件被触发,并会使用 MSGESTURE_FLAG_BEGIN 标志进行标记。
- 用户移动其手指时,MSGestureChange 事件会被重复触发,并且 MSGESTURE_FLAG_NONE 会通过 detail 属性传递。
- 用户抬起其手指时,将触发 MSInertiaStart 事件传递 MSGESTURE_FLAG_INERTIA 标志。
- 只要元素仍在屏幕上移动,MSGestureChange 元素将继续被触发并将传递 MSGESTURE_FLAG_INERTIA 标志。
- 当运动停止时,MSGestureEnd 事件被触发,并且 MSGESTURE_FLAG_INERTIA 和 MSGESTURE_FLAG_END 这两个标志都将通过 detail 属性传递。
如果用户触摸屏幕并按住屏幕几秒钟,然后移动其手指,则事件和详细信息将如下所示:
- 几秒后,将触发 MSGestureHold 事件传递 MSGESTURE_FLAG_BEGIN 标志。
- 用户开始移动其手指时,将触发 MSGestureHold 事件传递 MSGESTURE_FLAG_END 和 MSGESTURE_FLAG_CANCEL 标志。这表示长按已被取消。
- 用户移动其手指时,MSGestureChange 事件会被重复触发,同时 MSGESTURE_FLAG_NONE 会通过 detail 属性传递。 从此处开始,后续步骤与前面的步骤顺序类似。
- 用户抬起其手指时,将触发 MSInertiaStart 事件传递 MSGESTURE_FLAG_INERTIA 标志。
- 只要元素仍在屏幕上移动,MSGestureChange 元素将继续被触发并将传递 MSGESTURE_FLAG_INERTIA 标志。
- 当运动停止时,MSGestureEnd 事件被触发,并且 MSGESTURE_FLAG_INERTIA 和 MSGESTURE_FLAG_END 这两个标志都将通过 detail 属性传递。
有关在操作中显示笔势事件的完整示例应用,请参阅 MSGesture 参考主题。