Last active
August 29, 2015 14:05
-
-
Save mistadikay/f4a4665757b109582341 to your computer and use it in GitHub Desktop.
focusin/focusout polyfill
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
/** | |
* usage: NAMESPACE.addFocusInEvent($node, listener); | |
* replace comments containing [code] with your code | |
*/ | |
(function(NAMESPACE, global){ | |
var document = global.document, | |
$body = document.body, | |
focusInEvent = 'focusin', | |
focusOutEvent = 'focusout', | |
$testInputContainer, | |
$testInput, | |
focusInspectionsDestructor, | |
$activeElement, | |
activeElementFakeEvent, | |
inputsInInspection = 0, | |
isNative = false; | |
function testNativeFocusInOutEvents(){ | |
$testInputContainer = document.createElement('div'); | |
$testInputContainer.setAttribute('style', 'width:10xp;height:10px;overflow:hidden;position:fixed;top:-10px;left:-10px;'); | |
$body.appendChild($testInputContainer); | |
$testInput = document.createElement('input'); | |
$testInput.type = 'text'; | |
$testInput.addEventListener('focusin', initNativeFocusInOutEvents); | |
$testInputContainer.appendChild($testInput); | |
$testInput.focus(); | |
$testInput.removeEventListener('focusin', initNativeFocusInOutEvents); | |
// [code] remove $testInputContainer | |
if (!isNative){ | |
initCustomFocusInOutEvents(); | |
} | |
} | |
function initNativeFocusInOutEvents(){ | |
isNative = true; | |
NAMESPACE.addFocusInEvent = function($element, listener){ | |
$element.addEventListener(focusInEvent, listener); | |
}; | |
NAMESPACE.removeFocusInEvent = function($element, listener){ | |
$element.removeEventListener(focusInEvent, listener); | |
}; | |
NAMESPACE.addFocusOutEvent = function($element, listener){ | |
$element.addEventListener(focusOutEvent, listener); | |
}; | |
NAMESPACE.removeFocusOutEvent = function($element, listener){ | |
$element.removeEventListener(focusOutEvent, listener); | |
}; | |
} | |
function initCustomFocusInOutEvents(){ | |
NAMESPACE.addFocusInEvent = function($node, listener){ | |
addEventForInspection(); | |
// [code] add event listener for focusInEvent to $node | |
}; | |
NAMESPACE.removeFocusInEvent = function($node, listener){ | |
removeEventForInspection(); | |
// [code] remove event listener for focusInEvent to $node | |
}; | |
NAMESPACE.addFocusOutEvent = function($node, listener){ | |
addEventForInspection(); | |
// [code] add event listener for focusOutEvent to $node | |
}; | |
NAMESPACE.removeFocusOutEvent = function($node, listener){ | |
removeEventForInspection(); | |
// [code] remove event listener for focusOutEvent to $node | |
}; | |
} | |
function addEventForInspection(){ | |
if (inputsInInspection === 0){ | |
$activeElement = document.activeElement; | |
activeElementFakeEvent = {target: $activeElement}; | |
focusInspectionsDestructor = focusInspectionsInit(); | |
} | |
inputsInInspection += 1; | |
} | |
function removeEventForInspection(){ | |
inputsInInspection -= 1; | |
if (inputsInInspection <= 0){ | |
inputsInInspection = 0; | |
focusInspectionsDestructor(); | |
} | |
} | |
function focusInspectionsInit(){ | |
function check(){ | |
if ($activeElement !== document.activeElement){ | |
// [code] generate focusOutEvent event for $activeElement and pass activeElementFakeEvent as an argument | |
$activeElement = document.activeElement; | |
activeElementFakeEvent.target = $activeElement; | |
// [code] generate focusInEvent event for $activeElement and pass activeElementFakeEvent as an argument | |
} | |
} | |
// [code] add check to global timeout | |
return function(onDestruction){ | |
activeElementFakeEvent.target = null; | |
activeElementFakeEvent = $activeElement = null; | |
// [code] remove check from global timeout | |
} | |
} | |
testNativeFocusInOutEvents(); | |
})(window, window); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment