Last active
May 6, 2019 12:41
-
-
Save peponi/8fc691a26cc83abfe5c24027f20cb98c to your computer and use it in GitHub Desktop.
details element polyfill for IE11, supoorts elements inside summary
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
/** | |
* based on | |
* @url https://github.com/rstacruz/details-polyfill | |
* @todo https://www.sitepoint.com/fixing-the-details-element/ | |
* @todo https://www.smashingmagazine.com/2014/11/complete-polyfill-html5-details-element/ | |
*/ | |
const detailsPolyfillEs6 = ({ | |
CSS_CLASS = 'no-details', | |
CSS_STRING = false, | |
APPEND_CSS = true, | |
DEBUG = false | |
} = {}) => { | |
const DETAILS = 'details'; | |
const SUMMARY = 'summary'; | |
/* | |
* Checks for support for `<details>` | |
*/ | |
const checkSupport = () => { | |
const el = document.createElement(DETAILS); | |
if (!('open' in el)) return false; | |
el.innerHTML = '<' + SUMMARY + '>a</' + SUMMARY + '>b'; | |
document.body.appendChild(el); | |
const diff = el.offsetHeight; | |
el.open = true; | |
const result = (diff !== el.offsetHeight); | |
document.body.removeChild(el); | |
return result; | |
}; | |
// check if passed element is a <summary> else take parent element and check again | |
const getSummary = (el) => { | |
// I saw on IE11 that e.target can be null in some case | |
if (el === null) return false; | |
return el.nodeName.toLowerCase() !== SUMMARY ? getSummary(el.parentNode) : el; | |
}; | |
/* | |
* Click handler for `<summary>` tags | |
*/ | |
const clickHandler = (e) => { | |
// INFO: this is maybe performance relevant for you | |
// because I use a recursive function, | |
// the clickHandler will loop up the tree ON EVERY CLICK IN THE INTERNET EXPLORER, | |
// until a <summary> or the end of the node tree has been found | |
const summaryEl = getSummary(e.target); | |
if (summaryEl && summaryEl.nodeName && summaryEl.nodeName.toLowerCase() === SUMMARY) { | |
const detailsEl = summaryEl.parentNode; | |
// if parent element of <summary> is a <details> toggle the state | |
if (detailsEl && detailsEl.nodeName && detailsEl.nodeName.toLowerCase() === DETAILS) { | |
// toggle the visual state | |
if (detailsEl.getAttribute('open')) { | |
detailsEl.open = false; | |
detailsEl.removeAttribute('open'); | |
} else { | |
detailsEl.open = true; | |
detailsEl.setAttribute('open', 'open'); | |
} | |
} | |
} | |
}; | |
/* | |
* Injects styles (idempotent) | |
*/ | |
const injectStyle = (id, style) => { | |
if (document.getElementById(id)) return; | |
const el = document.createElement('style'); | |
el.id = id; | |
el.innerHTML = style; | |
document.getElementsByTagName('head')[0].appendChild(el); | |
}; | |
/** | |
* INIT | |
*/ | |
const detailsIsSupported = checkSupport(); | |
DEBUG && console.log('detailsIsSupported = ', detailsIsSupported); | |
// if details element is support in the current browser, do nothing | |
if (detailsIsSupported) return; | |
// just add event listener & CSS for IE | |
window.addEventListener('click', clickHandler); | |
// if customDetailsPolyfill has been initialized with APPEND_CSS = false | |
// do not write the styles for the <summary> marker in the <head> | |
// | |
// usefull if you don't need the marker by default | |
// you can hide the marker with CSS for chrome & firefox | |
// | |
// summary::-webkit-details-marker { display: none; } | |
// summary::-moz-list-bullet { list-style-type: none; } | |
// | |
if (APPEND_CSS === false) return; | |
document.documentElement.className += ` ${CSS_CLASS}`; | |
const cssString = CSS_STRING || ` | |
.${CSS_CLASS} ${DETAILS} * { | |
display: none; | |
} | |
.${CSS_CLASS} ${DETAILS} ${SUMMARY}, | |
.${CSS_CLASS} ${DETAILS} ${SUMMARY} * { | |
display: block; | |
} | |
.${CSS_CLASS} ${DETAILS}[open] * { | |
display: block; | |
}`; | |
DEBUG && console.log(cssString); | |
injectStyle('details-polyfill-es6-style has been injected following styles to HEAD', cssString); | |
}; | |
export default detailsPolyfillEs6; |
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
import detailsPolyfillEs6 from './polyfill/details-polyfill-es6'; | |
// show console logs in IE11 | |
detailsPolyfillEs6({DEBUG: true}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment