Open zachleat opened 7 years ago
I think this snippet does what you are asking for.
function findNodes(root) {
let nodes = [];
const children = root.childNodes;
for (let i = 0; i < children.length; i++) {
const child = children[i];
const hasHorizontalScrollbar = child.scrollWidth > child.clientWidth;
if (hasHorizontalScrollbar) {
// try hiding it
const oldDisplay = child.style.display;
child.style.display = 'none';
const afterHasHorizontalScrollbar = child.scrollWidth > child.clientWidth;
// restore
child.style.display = oldDisplay;
if (afterHasHorizontalScrollbar) {
const results = findNodes(child);
nodes = nodes.concat(results);
} else {
nodes.push(child);
}
}
}
return nodes;
}
console.log(findNodes(document.body));
It returns a list of all the elements causing horizontal scrollbars (there might be more than one on a page). Not sure how to best highlight the elements. At the moment it just prints them out in the console.
Minified it would result in a snippet like this
console.log(function(b){var c=[];b=b.childNodes;for(var d=0;d<b.length;d++){var a=b[d];if(a.scrollWidth>a.clientWidth){var e=a.style.display;a.style.display="none";var f=a.scrollWidth>a.clientWidth;a.style.display=e;f?(a=findNodes(a),c=c.concat(a)):c.push(a)}}return c}(document.body));
Let me know what you think and if you have any ideas to improve it.
Hey @JMPerez this is great! I think it needs a little love though, looks like the check for a scrollbar are only specific to a single element, which isn’t quite what I was going for. Close though!
Check this: https://jsbin.com/nureliz/edit?html,console,output
You can see two divs there, one overflowing the viewport and one not. The “Overflowing” div should show in the results.
I have changed the snippet. This one does work with your example. It checks whether toggling the visibility of a child toggles also the presence of a horizontal scrollbar:
function findNodes(root) {
let nodes = [];
const hasHorizontalScrollbar = root.scrollWidth > root.clientWidth;
if (hasHorizontalScrollbar) {
const children = root.childNodes;
for (let i = 0; i < children.length; i++) {
const child = children[i];
if (child.style) {
// try hiding it
const oldDisplay = child.style.display;
child.style.display = 'none';
const afterHasHorizontalScrollbar = root.scrollWidth > root.clientWidth;;
// restore
child.style.display = oldDisplay;
if (afterHasHorizontalScrollbar) {
const results = findNodes(child);
nodes = nodes.concat(results);
} else {
nodes.push(child);
}
}
}
}
return nodes;
}
console.log(findNodes(document.body));
When working on a responsive design, it’s somewhat common during integration testing to find rendering issues that cause horizontal overflow and horizontal scrollbars.
A lot of the time it isn’t immediately obvious what node is causing the issue (especially if it’s not immediately visible).
I want a bookmarklet that iterates (top down, optimized search) through nodes at the current viewport size to hide the current node and see if the scrollbar goes away. If it does, reinstate the node and iterate over its children. Keep going until you find a leaf node that does this.
This will isolate the node(s) causing the scrollbars, making it easier to debug.