Skip to content

Instantly share code, notes, and snippets.

@mistadikay
Last active August 29, 2015 14:05
Show Gist options
  • Save mistadikay/f4a4665757b109582341 to your computer and use it in GitHub Desktop.
Save mistadikay/f4a4665757b109582341 to your computer and use it in GitHub Desktop.
focusin/focusout polyfill
/**
* 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