fix(ngAria): do not scroll when pressing spacebar on custom buttons

By default, pressing spacebar causes the browser to scroll down.
However, when a native button is focused, the button is clicked instead.

`ngAria`'s `ngClick` directive, sets elements up to behave like buttons.
For example, it adds `role="button"` and forwards `ENTER` and `SPACEBAR`
keypresses to the `click` handler (to emulate the behavior of native
buttons).

Yet, pressing spacebar on such an element, still invokes the default
browser behavior of scrolling down.

This commit fixes this, by calling `preventDefault()` on the keyboard
event, thus preventing the default scrolling behavior and making custom
buttons behave closer to native ones.

Closes #14665

Closes #16604
This commit is contained in:
George Kalpakas
2018-06-16 12:56:41 +03:00
parent af1e6a38b7
commit 6c224a2a60
2 changed files with 9 additions and 5 deletions
+4 -1
View File
@@ -387,7 +387,10 @@ ngAriaModule.directive('ngShow', ['$aria', function($aria) {
if ($aria.config('bindKeydown') && !attr.ngKeydown && !attr.ngKeypress && !attr.ngKeyup) {
elem.on('keydown', function(event) {
var keyCode = event.which || event.keyCode;
if (keyCode === 32 || keyCode === 13) {
if (keyCode === 13 || keyCode === 32) {
// Prevent the default browser behavior (e.g. scrolling when pressing spacebar).
event.preventDefault();
scope.$apply(callback);
}
+5 -4
View File
@@ -929,11 +929,12 @@ describe('$aria', function() {
clickEvents = [];
scope.onClick = jasmine.createSpy('onClick').and.callFake(function(evt) {
var nodeName = evt ? evt.target.nodeName.toLowerCase() : '';
clickEvents.push(nodeName);
var prevented = !!(evt && evt.isDefaultPrevented());
clickEvents.push(nodeName + '(' + prevented + ')');
});
});
it('should trigger a click from the keyboard', function() {
it('should trigger a click from the keyboard (and prevent default action)', function() {
compileElement(
'<section>' +
'<div ng-click="onClick($event)"></div>' +
@@ -948,7 +949,7 @@ describe('$aria', function() {
divElement.triggerHandler({type: 'keydown', keyCode: 32});
liElement.triggerHandler({type: 'keydown', keyCode: 32});
expect(clickEvents).toEqual(['div', 'li', 'div', 'li']);
expect(clickEvents).toEqual(['div(true)', 'li(true)', 'div(true)', 'li(true)']);
});
it('should trigger a click in browsers that provide `event.which` instead of `event.keyCode`',
@@ -967,7 +968,7 @@ describe('$aria', function() {
divElement.triggerHandler({type: 'keydown', which: 32});
liElement.triggerHandler({type: 'keydown', which: 32});
expect(clickEvents).toEqual(['div', 'li', 'div', 'li']);
expect(clickEvents).toEqual(['div(true)', 'li(true)', 'div(true)', 'li(true)']);
}
);