-
Notifications
You must be signed in to change notification settings - Fork 9.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
core(perf): speed up tap-target's isVisible() #9056
Changes from all commits
d7c7c39
ec81ea2
9f58389
f012ce6
19f2e55
b0d621d
0e3dace
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -37,38 +37,12 @@ const TARGET_SELECTORS = [ | |
const tapTargetsSelector = TARGET_SELECTORS.join(','); | ||
|
||
/** | ||
* @param {Element} element | ||
* @param {HTMLElement} element | ||
* @returns {boolean} | ||
*/ | ||
/* istanbul ignore next */ | ||
function elementIsVisible(element) { | ||
const {overflowX, overflowY, display, visibility} = getComputedStyle(element); | ||
|
||
if ( | ||
display === 'none' || | ||
(visibility === 'collapse' && ['TR', 'TBODY', 'COL', 'COLGROUP'].includes(element.tagName)) | ||
) { | ||
// Element not displayed | ||
return false; | ||
} | ||
|
||
// only for block and inline-block, since clientWidth/Height are always 0 for inline elements | ||
if (display === 'block' || display === 'inline-block') { | ||
// if height/width is 0 and no overflow in that direction then | ||
// there's no content that the user can see and tap on | ||
if ((element.clientWidth === 0 && overflowX === 'hidden') || | ||
(element.clientHeight === 0 && overflowY === 'hidden')) { | ||
return false; | ||
} | ||
} | ||
|
||
const parent = element.parentElement; | ||
if (parent && parent.tagName !== 'BODY') { | ||
// if a parent is invisible then the current element is also invisible | ||
return elementIsVisible(parent); | ||
} | ||
|
||
return true; | ||
return !!(element.offsetWidth || element.offsetHeight || element.getClientRects().length); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. to fix the failure can we check if any of these dimensions are 0? it feels like everything was so carefully written the first time around though I'm not sure I fully understand how these compare... There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeahh... something with a 1px height but 0x width is still invisible. doesnt matter the height. Not sure what the test case was supposed to be for. @mattzeunert There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The test failure is fixed after merging master, because the node is filtered out by
The tap target can't be tapped on because the content is hidden by the
Just because the element has a width of 0 doesn't mean the tap target is untappable, because there could be overflowing child content that the user can tap on. I added a test case for a
I think this change is fine, we have reasonable smoke test coverage and I tried it on 50 sites and didn't notice any changes. I think the new |
||
} | ||
|
||
/** | ||
|
@@ -238,7 +212,7 @@ function gatherTapTargets() { | |
// Capture element positions relative to the top of the page | ||
window.scrollTo(0, 0); | ||
|
||
/** @type {Element[]} */ | ||
/** @type {HTMLElement[]} */ | ||
// @ts-ignore - getElementsInDocument put into scope via stringification | ||
const tapTargetElements = getElementsInDocument(tapTargetsSelector); | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we could do this with https://stackoverflow.com/a/28457044/1290545. Konrad's original code actually used it, but then neither of us could figure out what it was needed for 🙂