Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feature(element/blur): interface to remove focus from an element
- Loading branch information
1 parent
bc13efd
commit 707fe88
Showing
8 changed files
with
174 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
--- | ||
layout: doc-api.html | ||
tags: argument-list | ||
--- | ||
|
||
# ally.element.blur | ||
|
||
Shifts focus away from an element if it currently has focus. | ||
|
||
|
||
## Description | ||
|
||
The [`blur()`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/blur) method is available on all [`HTMLElement`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement). But this is not necessarily true for [`SVGElement`](https://developer.mozilla.org/en-US/docs/Web/API/SVGElement). Only Blink and WebKit expose the `blur()` method on SVG elements, Gecko, Trident and Edge do not. This will likely change once [SVG 2](http://www.w3.org/TR/SVG2/interact.html#Focus) is a thing. Until then `ally.element.blur()` tries to apply `HTMLElement.prototoype.blur` to `SVGElement`s. This only works for Internet Explorer 9 - 11, as Gecko and Edge actively prevent this. | ||
|
||
According to [jQuery Bug 9420](https://bugs.jqueryui.com/ticket/9420) calling `blur()` on the `body` element may make the browser window lose focus. `ally.element.blur()` guards against this. | ||
|
||
|
||
## Usage | ||
|
||
```js | ||
var element = document.getElementById('victim'); | ||
var result = ally.element.blur(element); | ||
``` | ||
|
||
### Arguments | ||
|
||
| Name | Type | Default | Description | | ||
| ---- | ---- | ------- | ----------- | | ||
| element | [`<selector>`](../concepts.md#Selector) | *required* | The Element to blur. First element of the collections is used. | | ||
|
||
### Returns | ||
|
||
[`HTMLElement`](https://developer.mozilla.org/en/docs/Web/API/HTMLElement) that received focus (usually `document.body`) or `null` if focus could not be shifted. | ||
|
||
### Throws | ||
|
||
[`TypeError`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypeError) if `element` argument does not resolve to an `HTMLElement`. | ||
|
||
|
||
## Examples | ||
|
||
|
||
## Changes | ||
|
||
* Added in `v#master`. | ||
|
||
|
||
## Notes | ||
|
||
|
||
## Related resources | ||
|
||
* [`ally.element.focus`](./focus.md) shifts focus to an element if it does not already have focus. | ||
|
||
|
||
## Contributing | ||
|
||
* [module source](https://github.com/medialize/ally.js/blob/master/src/element/blur.js) | ||
* [document source](https://github.com/medialize/ally.js/blob/master/docs/api/element/blur.md) | ||
* [unit test](https://github.com/medialize/ally.js/blob/master/test/unit/element.blur.test.js) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1,11 @@ | ||
|
||
// exporting modules to be included the UMD bundle | ||
|
||
import blur from './blur'; | ||
import disabled from './disabled'; | ||
import focus from './focus'; | ||
export default { | ||
blur, | ||
disabled, | ||
focus, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
|
||
import isActiveElement from '../is/active-element'; | ||
import contextToElement from '../util/context-to-element'; | ||
import getWindow from '../util/get-window'; | ||
|
||
export default function(context) { | ||
const element = contextToElement({ | ||
label: 'element/blur', | ||
context, | ||
}); | ||
|
||
if (!isActiveElement(element)) { | ||
return null; | ||
} | ||
|
||
const nodeName = element.nodeName.toLowerCase(); | ||
if (nodeName === 'body') { | ||
// prevent the browser window from losing focus in IE9 | ||
// according to https://bugs.jqueryui.com/ticket/9420 | ||
return null; | ||
} | ||
|
||
if (element.blur) { | ||
element.blur(); | ||
return document.activeElement; | ||
} | ||
|
||
const _window = getWindow(element); | ||
|
||
try { | ||
// The element itself does not have a blur method. | ||
// This is true for SVG elements in Firefox and IE, | ||
// as well as MathML elements in every browser. | ||
// IE9 - 11 will let us abuse HTMLElement's blur method, | ||
// Firefox and Edge will throw an error. | ||
_window.HTMLElement.prototype.focus.call(element); | ||
return document.activeElement; | ||
} catch (e) { | ||
// we may want to try focusing <body> before giving up. | ||
// not sure how this works for an SVG document, though. | ||
return null; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
define([ | ||
'intern!object', | ||
'intern/chai!expect', | ||
'../helper/fixtures/focusable.fixture', | ||
'../helper/supports', | ||
'ally/util/platform', | ||
'ally/element/focus', | ||
'ally/element/blur', | ||
], function(registerSuite, expect, focusableFixture, supports, platform, elementFocus, elementBlur) { | ||
|
||
registerSuite(function() { | ||
var fixture; | ||
|
||
return { | ||
name: 'element/blur', | ||
|
||
beforeEach: function() { | ||
fixture = focusableFixture(); | ||
}, | ||
afterEach: function() { | ||
fixture.remove(); | ||
fixture = null; | ||
}, | ||
|
||
invalid: function() { | ||
expect(function() { | ||
elementBlur(null); | ||
}).to.throw(TypeError, 'element/blur requires valid options.context'); | ||
}, | ||
|
||
'non focusable element': function() { | ||
var element = document.getElementById('inert-div'); | ||
var result = elementBlur(element); | ||
expect(result).to.equal(null); | ||
}, | ||
'not active element': function() { | ||
var activeElement = document.getElementById('tabindex-1'); | ||
activeElement.focus(); | ||
|
||
var element = document.getElementById('tabindex-0'); | ||
var result = elementBlur(element); | ||
expect(result).to.equal(null); | ||
}, | ||
'blur active element': function() { | ||
var element = document.getElementById('tabindex-0'); | ||
element.focus(); | ||
|
||
var result = elementBlur(element); | ||
expect(result).to.equal(document.body); | ||
}, | ||
'blur body element': function() { | ||
var result = elementBlur(document.body); | ||
expect(result).to.equal(null); | ||
}, | ||
'focusable svg element': function() { | ||
var element = document.getElementById('svg-link'); | ||
var result = elementFocus(element); | ||
var canFocusSvg = supports.svgFocusMethod || platform.is.TRIDENT && platform.majorVersion < 13; | ||
expect(result).to.equal(canFocusSvg ? element : null); | ||
}, | ||
}; | ||
}); | ||
}); |