Here is a use case:
Assume we have a web page that has an issue, which results in the page to be scrolled up on a mobile device at some point after DOMContentLoaded has fired.
We can legitimately assume there is something, which operates on document.documentElement.scrollTop (e.g. assigns it a value of 0).
Suppose we also know there are hundreds of places, where this can happen.
To debug the issue we can think of the following strategies:
check each event handler, which can set a value of 0 scrollTop, one by one
try to use debug function available in Chrome DevTools
- Override a native scrollTop as:
var scrollTopOwner = document.documentElement.__proto__.__proto__.__proto__;
var oldDescr = Object.getOwnPropertyDescriptor(scrollTopOwner, 'scrollTop');
Object.defineProperty(scrollTopOwner, '_oldScrollTop_', oldDescr);
Object.defineProperty(scrollTopOwner, 'scrollTop', {
get:function(){
return this._oldScrollTop_;
},
set: function(v) {
debugger;
this._oldScrollTop_ = v;
}
});
function someMethodCausingAPageToScrollUp() {
document.scrollingElement.scrollTop = 1e3;
}
setTimeout(someMethodCausingAPageToScrollUp, 1000);
The issue with the second approach is that it doesn't work with native getters/setters.
The issue with the third approach is that even though now we can easily track what is assigning a value to the scrollTop property, we monkey patch a native getters/setters and risk to cause unnecessary side effects.
Hence the question: is there a more elegant solution to debug native getters and setters for web browser host objects (e.g. document, window, location, etc)?
Turns out it is possible to use
debug
function forset
method on ascrollTop
property descriptor.The code is as follows:
After that, we'll automatically stop in any function that tries to set a value to
scrollTop
. If you need to automatically stop only on those functions which assign a value within a certain threshold (for example, between 0 and 500), you can easily do that too sincedebug
function accepts a second argument (condition) where you can specify your condition logic.For example:
Pros:
Cons:
Many thanks to Aleksey Kozyatinskiy (former Googler on DevTools team) for the detailed explanation.