13.4.3 Mouse and Wheel Events [Advanced JavaScript Programming 3rd Edition]

Mouse events are the most commonly used type of events in Web development, after all, the mouse is still the most important pointing device. Nine mouse events are defined in DOM3 level events, and the introduction is as follows.
click: Fired when the user clicks the primary mouse button (usually the left button) or presses the Enter key. This is important to ensure accessibility, and means that the onclick event handler can be executed from both the keyboard and the mouse.

  • dblclick: Fired when the user double-clicks the primary mouse button (usually the left button). Technically, this event is not specified in the DOM2-level event specification, but given its widespread support, DOM3-level events include it in the standard.
  • mousedown: Fired when the user presses any mouse button. This event cannot be triggered by the keyboard.
  • mouseenter: Fired when the mouse cursor first moves from outside the element to within the bounds of the element. This event does not bubble and does not fire when the cursor is moved over a descendant element. DOM2-level events do not define this event, but DOM3-level events put it into the specification. IE, Firefox 9+ and Opera support this event.
  • mouseleave: Fired when the mouse cursor over the element moves outside the bounds of the element. This event does not bubble and does not fire when the cursor is moved over a descendant element. DOM2-level events do not define this event, but DOM3-level events put it into the specification. IE, Firefox 9+ and Opera support this event.
  • mousemove: Fired repeatedly when the mouse pointer moves inside the element. This event cannot be triggered by the keyboard.
  • mouseout: Fired when the mouse pointer is over an element and the user moves it into another element. Another element that is moved in may be outside the previous element, or it may be a child of this element. This event cannot be triggered by the keyboard.
  • mouseover: Fired when the mouse pointer is outside an element and then the user first moves it within the boundaries of another element. This event cannot be triggered by the keyboard.
  • mouseup: Fired when the user releases the mouse button. This event cannot be triggered by the keyboard.

All elements on the page support mouse events. With the exception of mouseenter and mouseleave, all mouse events are bubbled and can be canceled, and canceling mouse events will affect the browser's default behavior. Canceling the default behavior of mouse events also affects other events, because mouse events are inextricably linked to other events.
The click event will only fire if the mousedown and mouseup events are fired in succession on the same element; the click event will not fire if either mousedown or mouseup is canceled. Similarly, a dblclick event will only fire once if the click event is fired twice. If there is code that prevents the click event from being fired twice in a row (either directly by canceling the click event, or indirectly by canceling mousedown or mouseup), then the dblclick event will not fire. The order in which these 4 events are fired is always as follows:

  • (1) mousedown
  • (2) mouseup
  • (3) click
  • (4) mousedown
  • (5) mouseup
  • (6) click
  • (7) dblclick

Obviously, the click and dblclick events depend on the firing of other preceding events; mousedown and mouseup are not affected by other events.
The implementation in IE8 and earlier has a small bug, so in the double click event, the second mousedown and click events are skipped, in the following order:

  • (1) mousedown
  • (2) mouseup
  • (3) click
  • (4) mouseup
  • (5) dblclick

IE9 fixes this bug, and the order is correct after that. Use the following code to detect if the browser supports the above DOM2 level events (except dbclick, mouseenter and mouseleave):

var isSupported = document.implementation.hasFeature("MouseEvents", "2.0");

To detect if the browser supports all the events above, you can use the following code:

var isSupported = document.implementation.hasFeature("MouseEvent", "3.0")

Note that the feature name for DOM3 level events is "MouseEvent", not "MouseEvents".
There is also a class of scroll wheel events in mouse events. Said to be a class of events, in fact, is a mousewheel event. This event tracks the mouse wheel, similar to a Mac's trackpad.

1. Client area coordinates

Mouse events all happen at specific locations in the browser's viewport. This location information is stored in the clientX and clientY properties of the event object. All browsers support these two properties, and their values ​​represent the horizontal and vertical coordinates of the mouse pointer in the viewport when the event occurred. Figure 13-4 shows the meaning of the coordinates of the client area in the viewport.

Client coordinate information for mouse events can be obtained using code similar to the following:

var div = document.getElementById("myDiv");
EventUtil.addHandler(div, "click",
function(event) {
	event = EventUtil.getEvent(event);
	alert("Client coordinates: " + event.clientX + "," + event.clientY);
});

Run it
This specifies the onclick event handler for a <div> element. When the user clicks on this element, they see the client-side coordinate information for the event. Note that these values ​​do not include the distance the page is scrolled, so this position does not represent the position of the mouse on the page.

2. Page coordinate position

The client area coordinates can tell you where the mouse is in the viewport, and the page coordinates can tell you where the event occurs on the page through the pageX and pageY properties of the event object. In other words, these two properties represent the position of the mouse cursor on the page, so the coordinates are calculated from the page itself rather than the left and top edges of the viewport.
The following code can get the coordinates of the mouse event on the page:

var div = document.getElementById("myDiv");
EventUtil.addHandler(div, "click",
function(event) {
	event = EventUtil.getEvent(event);
	alert("Page coordinates: " + event.pageX + "," + event.pageY);
});

Run it
. When the page is not scrolled, the values ​​of pageX and pageY are equal to the values ​​of clientX and clientY.
IE8 and earlier do not support page coordinates on event objects, but can be calculated using client area coordinates and scroll information. At this time, you need to use the scrollLeft and scrollTop properties in document.body (promiscuous mode) or document.documentElement (standard mode). The calculation process is as follows:

var div = document.getElementById("myDiv");
EventUtil.addHandler(div, "click",
function(event) {
	event = EventUtil.getEvent(event);
	var pageX = event.pageX,
	pageY = event.pageY;
	if (pageX === undefined) {
		pageX = event.clientX + (document.body.scrollLeft || document.documentElement.scrollLeft);
	}
	if (pageY === undefined) {
		pageY = event.clientY + (document.body.scrollTop || document.documentElement.scrollTop);
	}
	alert("Page coordinates: " + pageX + "," + pageY);
});

run it

3. Screen coordinates

When a mouse event occurs, there is not only a position relative to the browser window, but also a position relative to the entire computer screen. And through the screenX and screenY properties, you can determine the coordinate information of the mouse pointer relative to the entire screen when the mouse event occurs. Figure 13-5 shows the meaning of screen coordinates in the browser.

The screen coordinates of a mouse event can be obtained using code similar to the following:

var div = document.getElementById("myDiv");
EventUtil.addHandler(div, "click",
function(event) {
	event = EventUtil.getEvent(event);
	alert("Screen coordinates: " + event.screenX + "," + event.screenY);
});

Running it
Similar to the previous example, here is an onclick event handler specified for the <div> element. When the element is clicked, the screen coordinates of the event are displayed.

4. Modifier keys

Although mouse events are primarily triggered using the mouse, the state of certain keys on the keyboard can also affect the action to be taken when the mouse is pressed. These modifier keys are Shift, Ctrl, Alt, and Meta (the Windows key on Windows keyboards and the Cmd key on Macs), and they are often used to modify the behavior of mouse events. The DOM defines four properties for this, representing the state of these modifier keys: shiftKey, ctrlKey, altKey, and metaKey. These properties contain boolean values ​​that are true if the corresponding key was pressed, false otherwise. When a mouse event occurs, by checking these properties, it can be determined whether the user presses any of the keys at the same time. Take a look at the example below.

var div = document.getElementById("myDiv");
EventUtil.addHandler(div, "click",
function(event) {
	event = EventUtil.getEvent(event);
	var keys = new Array();
	if (event.shiftKey) {
		keys.push("shift");
	}
	if (event.ctrlKey) {
		keys.push("ctrl");
	}
	if (event.altKey) {
		keys.push("alt");
	}
	if (event.metaKey) {
		keys.push("meta");
	}
	alert("Keys: " + keys.join(","));
});

Running it
In this example, we detect the state of the different modifier keys through an onclick event handler. The array keys contains the names of the modifier keys that were pressed. In other words, if any property value is true, the name of the corresponding modifier key is added to the keys array. At the end of the event handler, there is an alert box that displays information about the detected keys to the user.

IE9, Firefox, Safari, Chrome and Opera all support these 4 keys. The metaKey attribute is not supported in IE8 and earlier.

5. Related elements

There are more elements involved when mouseover and mouseout events occur. Both events involve moving the mouse pointer from within the bounds of one element to within the bounds of another element. For the mouseover event, the main target of the event is the element that got the cursor, and the related element is the element that lost the cursor. Similarly, for mouseout events, the primary target of the event is the element that lost the cursor, and the related element is the element that gained the cursor. Take a look at the example below.

<!DOCTYPE html>
<html>
<head>
<title>Related Elements Example</title>
</head>
<body>
<div id="myDiv" style="background-color:red;height:100px;width:100px;"></div>
</body>
</html>

Running
this example will display a <div> element on the page. If the mouse pointer is initially on the <div> element and then moves out of the element, the mouseout event is fired on the <div> element, which is the <body> element. At the same time, the mouseover event is fired on the <body> element, and the associated element becomes a <div>.
The DOM provides information about related elements through the relatedTarget property of the event object. This property contains a value only for mouseover and mouseout events; for other events, the value of this property is null. IE8 and earlier do not support the relatedTarget property, but provide a different property that holds the same information. When the mouseover event is triggered, the related elements are stored in the fromElement property of IE; when the mouseout event is triggered, the related elements are stored in the toElement property of IE. (IE9 supports all of these properties.) The following cross-browser method for getting the relevant element can be added to the EventUtil object.

var EventUtil = {
	//Omit other code
	getRelatedTarget: function(event) {
		if (event.relatedTarget) {
			return event.relatedTarget;
		} else if (event.toElement) {
			return event.toElement;
		} else if (event.fromElement) {
			return event.fromElement;
		} else {
			return null;
		}
	},
	//Omit other code
};

EventUtil.js
, like the previously added cross-browser method, also uses feature detection to determine which value to return. The EventUtil.getRelatedTarget() method can be used like this:

var div = document.getElementById("myDiv");
EventUtil.addHandler(div, "mouseout",
function(event) {
	event = EventUtil.getEvent(event);
	var target = EventUtil.getTarget(event);
	var relatedTarget = EventUtil.getRelatedTarget(event);
	alert("Moused out of " + target.tagName + " to " + relatedTarget.tagName);
});

Running
this example registers an event handler for the mouseout event of the <div> element. When the event fires, there will be an alert box showing information about the elements the mouse was moved out and in.

6. Mouse buttons

The click event is only fired when the primary mouse button is clicked (or the keyboard's enter key is pressed), so detecting the button's information is not necessary. But for mousedown and mouseup events, there is a button property in its event object, which means the button that is pressed or released. The button property of the DOM may have the following 3 values: 0 for the primary mouse button, 1 for the middle mouse button (mouse wheel button), and 2 for the secondary mouse button. In a normal setup, the primary mouse button is the left mouse button, and the secondary mouse button is the right mouse button.
IE8 and earlier also provided the button attribute, but the value of this attribute is very different from the DOM's button attribute.

  • 0: Indicates that the button is not pressed.
  • 1: Indicates that the primary mouse button is pressed.
  • 2: Indicates that the mouse button is pressed the second time.
  • 3: Indicates that the primary and secondary mouse buttons are pressed at the same time.
  • 4: Indicates that the middle mouse button is pressed.
  • 5: Indicates that the primary mouse button and the middle mouse button are pressed at the same time.
  • 6: Indicates that the secondary mouse button and the middle mouse button are pressed at the same time.
  • 7: Indicates that three mouse buttons are pressed simultaneously.

It's not hard to imagine that the button property in the DOM model is simpler and more useful than the button property in the IE model, because it is rare to press multiple mouse buttons at the same time. The most common way to do this is to normalize the IE model to the DOM method, after all browsers other than IE8 and earlier natively support the DOM model. The mapping of the main, middle and secondary buttons is not difficult, as long as the other options of IE are converted to press one of these three buttons respectively (at the same time, the main button is used as the preferred object). In other words, 5 and 7 returned in IE will be converted to 0 in the DOM model.
Since the difference cannot be determined using capability detection alone (both models have a button property with the same name), a different approach has to be found. We know that browsers that support mouse events in the DOM version can be detected by the hasFearture() method, so we can add the following getButton() method to the EventUtil object.

var EventUtil = {
	//Omit other code
	getButton: function(event) {
		if (document.implementation.hasFeature("MouseEvents", "2.0")) {
			return event.button;
		} else {
			switch (event.button) {
			case 0:
			case 1:
			case 3:
			case 5:
			case 7:
				return 0;
			case 2:
			case 6:
				return 2;
			case 4:
				return 1;
			}
		}
	},
	//Omit other code
};

By detecting the "MouseEvents" property, EventUtil.js
can determine whether the button property that exists in the event object contains the correct value. If the test fails, indicating IE, the corresponding value must be normalized. Below is an example of using this method.

var div = document.getElementById("myDiv");
EventUtil.addHandler(div, "mousedown",
function(event) {
	event = EventUtil.getEvent(event);
	alert(EventUtil.getButton(event));
});

Run it
In this example, we add an onmousedown event handler to a <div> element. When the mouse button is pressed on this element, there will be an alert box showing the code for the button.

When using the onmouseup event handler, the value of button indicates which button was released. Also, Opera does not fire mouseup or mousedown events unless the primary mouse button is pressed or released.

7. More event information

The "DOM2 Level Events" specification also provides a detail property on the event object to give more information about the event. For mouse events, detail contains a number indicating how many clicks occurred at a given location. A mousedown and a mouseup event in succession on the same element count as a single click. The detail property starts counting from 1 and increments each time a click occurs. If the mouse moves between mousedown and mouseup, detail is reset to 0.
IE also provides more information for mouse events through the following properties.

  • altLeft: Boolean value indicating whether the Alt key is pressed. If the value of altLeft is true, the value of altKey is also true.
  • ctrlLeft: Boolean value indicating whether the Ctrl key is pressed. If the value of ctrlLeft is true, then the value of ctrlKey is also true.
  • offsetX: The x-coordinate of the cursor relative to the bounds of the target element.
  • offsetY: The y coordinate of the cursor relative to the bounds of the target element.
  • shiftLeft: Boolean value indicating whether the Shift key is pressed. If the value of shiftLeft is true, the value of shiftKey is also true.

These properties are not very useful, both because only IE supports them, and because the information they provide is either of little value or can be calculated in some other way.

8. Mouse wheel event

IE 6.0 first implemented the mousewheel event. Since then, Opera, Chrome and Safari have also implemented this event. The mousewheel event is fired when the user interacts with the page via the mouse wheel, scrolling the page vertically (whether up or down). This event can be fired on any element and will eventually bubble up to the document (IE8) or window (IE9, Opera, Chrome and Safari) object. The event object corresponding to the mousewheel event contains a special wheelDelta property in addition to all the standard information for the mouse event. When the user rolls the mouse wheel forward, wheelDelta is a multiple of 120; when the user rolls the mouse wheel backward, wheelDelta is a multiple of 120. Figure 13-6 shows this property.

Assign the mousewheel event handler to any element or document object in the page to handle mouse wheel interaction. Take a look at the example below.

EventUtil.addHandler(document, "mousewheel", function(event){
    event = EventUtil.getEvent(event);
    alert(event.wheelDelta);
});

This example will display the value of wheelDelta when the mousewheel event occurs. In most cases, it is enough to know the direction in which the mouse wheel is scrolling, which can be determined by checking the sign of wheelDelta.
One thing to note: in versions prior to Opera 9.5, the sign of the wheelDelta value was reversed. If you plan to support earlier Opera versions, you will need to use browser detection techniques to determine the actual value, as shown in the following example.

EventUtil.addHandler(document, "mousewheel",
function(event) {
	event = EventUtil.getEvent(event);
	var delta = (client.engine.opera && client.engine.opera < 9.5 ? -event.wheelDelta: event.wheelDelta);
	alert(delta);
});

Running
the above code uses the client object created in Chapter 9 to detect whether the browser is an earlier version of Opera.

Since the mousewheel event is so popular and all browsers support it, HTML 5 added it as well.

Firefox supports a similar event called DOMMouseScroll, which is also fired when the mouse wheel is scrolled. Like the mousewheel event, DOMMouseScroll is treated as a mouse event and thus contains all properties related to mouse events. The information about the mouse wheel is stored in the detail property. When the mouse wheel is scrolled forward, the value of this property is a multiple of -3, and when the mouse wheel is scrolled backward, the value of this property is a multiple of 3. Figure 13-7 shows this property.

The DOMMouseScroll event can be added to any element on the page, and the event will bubble up to the window object. Therefore, an event handler can be added for this event as follows.

EventUtil.addHandler(window, "DOMMouseScroll",
function(event) {
	event = EventUtil.getEvent(event);
	alert(event.detail);
});

Running
this simple event handler will display the value of the detail property when the mouse wheel is scrolled.
To give a solution in a cross-browser environment, the first step is to create a method that gets the delta of the mouse wheel. Here's the method we've added to the EventUtil object.

var EventUtil = {
	//Omit other code
	getWheelDelta: function(event) {
		if (event.wheelDelta) {
			return (client.engine.opera && client.engine.opera < 9.5 ? -event.wheelDelta: event.wheelDelta);
		} else {
			return - event.detail * 40;
		}
	},
	//Omit other code
};

Here in EventUtil.js
, the getWheelDelta() method first detects whether the event object contains the wheelDelta attribute, and if so, determines the correct value through the browser detection code. If wheelDelta does not exist, the corresponding value is assumed to be stored in the detail attribute. Since Firefox's value is different, first reverse the sign of this value and multiply it by 40 to guarantee the same value as other browsers. With this method in place, the same event handler can be assigned to the mousewheel and DOMMouse-Scroll events, for example:

(function() {
	function handleMouseWheel(event) {
		event = EventUtil.getEvent(event);
		var delta = EventUtil.getWheelDelta (event);
		alert(delta);
	}
	EventUtil.addHandler(document, "mousewheel", handleMouseWheel);
	EventUtil.addHandler(document, "DOMMouseScroll", handleMouseWheel);
})();

Run it
We put the relevant code in a private scope, so that the newly defined function does not interfere with the global scope. The handleMouseWheel() function defined here can be used as a handler for both events (if the specified event does not exist, the code specifying a handler for that event fails silently). Because of the EventUtil.getWheelDelta() method, the event handler function we defined can work in either situation.

9. Touch Devices

The implementation for iOS and Android devices is very special because these devices do not have a mouse. Here are a few things to keep in mind when developing for Safari on the iPhone and iPod.

  • The dblclick event is not supported. Double-clicking the browser window zooms in, and there is no way to change that behavior.
  • Tapping the clickable element fires the mousemove event. If this action causes the content to change, no other events will occur;

If the screen does not change as a result, mousedown, mouseup, and click events occur in sequence. Tapping on a non-clickable element doesn't fire any events. Clickable elements are those that, when clicked, result in a default action (such as a link), or those that have been assigned an onclick event handler.

  • The mousemove event also fires the mouseover and mouseout events.
  • The mousewheel and scroll events are fired when two fingers are placed on the screen and the page scrolls as the fingers move.

10. Accessibility issues

If your web application or website is to be accessible to people with disabilities, especially those using screen readers, be careful when using mouse events. As mentioned earlier, the click event can be triggered by the Enter key on the keyboard, but other mouse events cannot be triggered by the keyboard. For this reason, we do not recommend using mouse events other than click to demonstrate functionality or trigger code execution. Because this can cause great inconvenience to blind or visually impaired users. Here are a few accessibility issues you should be aware of when using mouse events.

  • Use the click event to execute code. It has been pointed out that executing code via onmousedown feels faster, which is true for sighted people. However, in a screen reader, the mousedown event cannot be fired, and as a result, the code cannot be executed.
  • Do not use onmouseover to present new options to the user. For the same reason as above, screen readers cannot trigger this event. If this is the way to display new options, consider adding a keyboard shortcut that displays the same information.
  • Do not use dblclick to perform important operations. The keyboard cannot trigger this event.

Following the above tips can greatly improve the accessibility of your web application or website for people with disabilities.

wrote
Download the offline tutorial: http://www.shouce.ren/api/view/a/15218

 

To learn how to implement accessible content in your web pages, visit www.webaim.org and http://yaccessibilityblog.com/.

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=326804272&siteId=291194637
Recommended