Last active
March 10, 2020 18:33
-
-
Save calebergh/7077e215a6d4818acce9b8b170565e77 to your computer and use it in GitHub Desktop.
Modernized polyfill to support proper behavior for summary / details HTML elements in Edge (legacy)
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
void(function(root, factory) { | |
if (typeof define === 'function' && define.amd) define(factory) | |
else if (typeof exports === 'object') module.exports = factory() | |
else factory() | |
}(this, function() { | |
var el = document.createElement('details'); | |
if (!('open' in el)) enableSupport(); | |
// include contents with size, otherwise diff sometimes returns 0 | |
el.innerHTML = '<summary><p>a</p></summary><p></p>'; | |
// put it off the page so there's no flash of content | |
el.style.position = 'absolute'; | |
el.style.left = '-999em'; | |
document.body.appendChild(el); | |
var diff = el.offsetHeight; | |
el.open = true; | |
setTimeout(function() { | |
var result = (diff !== el.offsetHeight); | |
document.body.removeChild(el); | |
if ( ! result) enableSupport(); | |
}, 500); | |
/* | |
* Click handler for `<summary>` tags | |
*/ | |
function clickHandler(e) { | |
// use closest to capture clicks on elements within the summary as well | |
if (e.target.nodeName.toLowerCase() === 'summary' || e.target.closest('summary')) { | |
// use closest to handle click targets nested within summary | |
var details = e.target.closest('details'); | |
if (!details) return; | |
if (details.getAttribute('open')) { | |
details.open = false; | |
details.removeAttribute('open'); | |
} else { | |
details.open = true; | |
details.setAttribute('open', 'open'); | |
} | |
} | |
} | |
function enableSupport() { | |
// Add a classname | |
document.documentElement.className += ' no-details'; | |
window.addEventListener('click', clickHandler); | |
} | |
})); | |
/** | |
* Required SCSS to make polyfill work properly: | |
* | |
* html.no-details { | |
* details:not([open]) > :not(summary) { | |
* display: none; | |
* } | |
* } | |
*/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This polyfill is largely based on this: https://github.com/rstacruz/details-polyfill
However, in my use case, the
summary
element contained children elements, and the click target was not properly identifying it as being within asummary
, so this updated code does a few things differently:summary
and children ofsummary
using the modern .closest() JS method .Minified, this script comes in at a lightweight 709 bytes uncompressed, and 391 bytes gzipped