我有一个第三方JS脚本堆页面。当我加载页面时,它会向下滚动到一个特定的div。我已经花了两个小时试图找出是哪一个代码导致了滚动。有没有办法找出是哪个脚本/代码的哪一部分触发了滚动?
crcmnpdw1#
哇,这么难调试。似乎调试器缺少一些功能,比如跟踪事件的发射器。问题是WooCommerce。具体来说,WooCommerce似乎在billing_last_name输入字段上设置了autofocus。然后浏览器会自动滚动页面,将字段显示在视图中。人们希望有一个配置选项来关闭自动对焦,但似乎WooCommerce没有提供这一点。您可以尝试将此添加到您的主题
billing_last_name
autofocus
function disable_autofocus_firstname($fields) { $fields['billing']['billing_first_name']['autofocus'] = false; return $fields; } add_filter('woocommerce_checkout_fields', 'disable_autofocus_firstname');
如果这不起作用,您可以创建一个CSS规则来隐藏账单名称字段,然后运行一个延迟的JS函数,以便在页面完全加载后显示账单名称字段。
根据OP的要求,并考虑到提供的赏金,我将描述我是如何调试的。我有点尴尬,我没有对自己说:“嗯,页面向上滚动到一个表单,光标在表单的第一个字段,我想知道它是否设置了自动对焦。”不幸的是,我主要不是一个前端程序员,一开始并没有想到autofocus。我最初的想法是通过JavaScript滚动,要么是显式调用滚动函数,要么是在某个对象上设置scrollTop。我在scroll事件上放置了一个事件断点,并试图确定在何处生成滚动事件。虽然我发现了滚动事件,但我没有找到它的来源。在这个阶段,我所能确定的是scroll事件针对的是document,而不是它内部的东西。我使用monitorEvents监听document上的事件,只发现了3个,一个点击和2个滚动,最后一个是由OP插入的延迟滚动到顶部函数引起的,以解决第一个滚动。我在设置超时时设置了一个执行断点(不执行函数),试图“分而治之”,也就是说,看看滚动是在此之前还是之后发生的。我在其余的调试工作中保持了该断点。奇怪的是,一般情况下,页面在到达断点之前不会滚动,但有时会滚动。我觉得这很奇怪,虽然我不知道该怎么办,但它让我注意到了一些不寻常的东西。我试着搜索所有的JavaScript中的“滚动”和“更新”(文本),以寻找更多的断点设置,并设置了一堆JavaScript,做滚动,但没有击中。我注意到有很多JavaScript动态更新页面,并认为滚动可能是由于某种更新。我尝试在document上放置一个jQuery event listener that logged all events(因为JS使用的是不是由monitorEvents记录的自定义事件,并且我已经确定document是scroll事件的目标)来发出所有事件,并查看它是否是一些自定义更新事件。有一堆自定义事件,我后来在控制台中生成了这些事件,以查看页面是否会滚动作为响应。由于我无法让页面以这种方式滚动,我得出结论,事件很可能是一个死胡同。我改变了策略。我看了看页面滚动到哪里,看到它正在滚动WooCommerce表单。因此,在执行断点处停止(如上所述)时,我从DOM中删除了整个WooCommerce表单,并验证页面不再滚动。这让我相信,无论问题是什么,它都是由WooCommerce引起的。不幸的是,我的谷歌福辜负了我,我没有立即通过谷歌搜索找到问题。相反,我发现WooCommerce如何在错误时滚动页面,以确保错误消息可见。这让我回到了JavaScript。尽管如此,还是有很多JavaScript,其中很多是动态创建表单的(动态本地化),还有一堆德语(我不会说),我没有发现任何导致滚动的JavaScript。我真的很想缩小导致滚动的JS文件的范围。Chrome允许你在“脚本第一条语句”上设置断点(在事件监听器断点->脚本下),所以我这样做了。除了在每个脚本文件的第一行停止外,它还在页面上每个<script>标记的开头停止。我在页面底部附近发现了这个脚本标签
scrollTop
scroll
document
monitorEvents
<script>
<script type="text/javascript"> if(typeof jQuery == 'undefined' || typeof jQuery.fn.on == 'undefined') { document.write('<script src="https://www.prored3.de/wp-includes/js/jquery/jquery.js"><\/script>'); document.write('<script src="https://www.prored3.de/wp-includes/js/jquery/jquery-migrate.min.js"><\/script>'); } </script>
这个脚本标记的奇怪之处在于,在处理完这个脚本标记之后,滚动立即发生,但是jQuery已经加载了,所以脚本实际上什么也没做。我还可以通过控制台确认,在这个脚本标记之前和之后(滚动之前和之后),DOM都没有被标记为ready。这意味着在滚动发生时,所有jQuery ready处理程序都没有运行。这消除了很多JavaScript,并让我思考为什么滚动发生在这个标记之后而不是之前。
ready
我猜测,在内部,浏览器看到了document.write调用,并确定DOM在通过该标记之前是不完整的,但一旦通过该标记,DOM就完成了,它可以开始处理页面级属性。这与之前的观察沿着,让我更仔细地查看了WooCommerce表单,并发现了billing_first_name字段上设置的autofocus属性。奇怪的是,我无法通过删除autofocus属性来防止滚动。我不知道为什么,但我猜这与浏览器内部以及DOM不是ready的事实有关。然而,我能够通过CSS隐藏billing_first_name输入元素来防止滚动,这使我相信这是滚动的原因。在我的谷歌搜索中添加“自动聚焦”导致我对WooCommerce的类似行为提出了其他投诉,并将帖子组合在一起,使我找到了我发布的PHP解决方案。
document.write
billing_first_name
pn9klfpd2#
已更新
由于我没有OP的页面进行测试,以下查找注册事件侦听器的方法实际上不解决OP正在解决的问题。然而,这是当我想找到一个特定的事件时的一般方法,只是为了某人的参考而保留。如果我正确理解了你的意思,你需要一个方法来告诉你具体的事件发生在哪里。如果这不是你想要的,请告诉我。您可以尝试在chrome调试器上添加断点。F12 -> Sources -> Event Listener Breakpoints(在那些Breakpoints,Scope等的列表中)-> Control -> Click the box of scroll.当然,它可能会捕获一些其他的滚动事件,你不感兴趣,但你可以通过它下一个下一个,直到你找到一个你想要的。此外,也可能有与scroll无关的事件,您可能还需要尝试focus或DOM Mutation -> DOMFocusIn。
focus
DOM Mutation -> DOMFocusIn
2条答案
按热度按时间crcmnpdw1#
哇,这么难调试。似乎调试器缺少一些功能,比如跟踪事件的发射器。
问题是WooCommerce。具体来说,WooCommerce似乎在
billing_last_name
输入字段上设置了autofocus
。然后浏览器会自动滚动页面,将字段显示在视图中。人们希望有一个配置选项来关闭自动对焦,但似乎WooCommerce没有提供这一点。
您可以尝试将此添加到您的主题
如果这不起作用,您可以创建一个CSS规则来隐藏账单名称字段,然后运行一个延迟的JS函数,以便在页面完全加载后显示账单名称字段。
如何调试
根据OP的要求,并考虑到提供的赏金,我将描述我是如何调试的。
我有点尴尬,我没有对自己说:“嗯,页面向上滚动到一个表单,光标在表单的第一个字段,我想知道它是否设置了自动对焦。”不幸的是,我主要不是一个前端程序员,一开始并没有想到
autofocus
。我最初的想法是通过JavaScript滚动,要么是显式调用滚动函数,要么是在某个对象上设置
scrollTop
。我在scroll
事件上放置了一个事件断点,并试图确定在何处生成滚动事件。虽然我发现了滚动事件,但我没有找到它的来源。在这个阶段,我所能确定的是scroll事件针对的是document
,而不是它内部的东西。我使用
monitorEvents
监听document
上的事件,只发现了3个,一个点击和2个滚动,最后一个是由OP插入的延迟滚动到顶部函数引起的,以解决第一个滚动。我在设置超时时设置了一个执行断点(不执行函数),试图“分而治之”,也就是说,看看滚动是在此之前还是之后发生的。我在其余的调试工作中保持了该断点。奇怪的是,一般情况下,页面在到达断点之前不会滚动,但有时会滚动。我觉得这很奇怪,虽然我不知道该怎么办,但它让我注意到了一些不寻常的东西。
我试着搜索所有的JavaScript中的“滚动”和“更新”(文本),以寻找更多的断点设置,并设置了一堆JavaScript,做滚动,但没有击中。
我注意到有很多JavaScript动态更新页面,并认为滚动可能是由于某种更新。
我尝试在
document
上放置一个jQuery event listener that logged all events(因为JS使用的是不是由monitorEvents
记录的自定义事件,并且我已经确定document
是scroll
事件的目标)来发出所有事件,并查看它是否是一些自定义更新事件。有一堆自定义事件,我后来在控制台中生成了这些事件,以查看页面是否会滚动作为响应。由于我无法让页面以这种方式滚动,我得出结论,事件很可能是一个死胡同。我改变了策略。我看了看页面滚动到哪里,看到它正在滚动WooCommerce表单。因此,在执行断点处停止(如上所述)时,我从DOM中删除了整个WooCommerce表单,并验证页面不再滚动。这让我相信,无论问题是什么,它都是由WooCommerce引起的。
不幸的是,我的谷歌福辜负了我,我没有立即通过谷歌搜索找到问题。相反,我发现WooCommerce如何在错误时滚动页面,以确保错误消息可见。这让我回到了JavaScript。
尽管如此,还是有很多JavaScript,其中很多是动态创建表单的(动态本地化),还有一堆德语(我不会说),我没有发现任何导致滚动的JavaScript。我真的很想缩小导致滚动的JS文件的范围。
Chrome允许你在“脚本第一条语句”上设置断点(在事件监听器断点->脚本下),所以我这样做了。除了在每个脚本文件的第一行停止外,它还在页面上每个
<script>
标记的开头停止。我在页面底部附近发现了这个脚本标签这个脚本标记的奇怪之处在于,在处理完这个脚本标记之后,滚动立即发生,但是jQuery已经加载了,所以脚本实际上什么也没做。我还可以通过控制台确认,在这个脚本标记之前和之后(滚动之前和之后),DOM都没有被标记为
ready
。这意味着在滚动发生时,所有jQueryready
处理程序都没有运行。这消除了很多JavaScript,并让我思考为什么滚动发生在这个标记之后而不是之前。我猜测,在内部,浏览器看到了
document.write
调用,并确定DOM在通过该标记之前是不完整的,但一旦通过该标记,DOM就完成了,它可以开始处理页面级属性。这与之前的观察沿着,让我更仔细地查看了WooCommerce表单,并发现了billing_first_name
字段上设置的autofocus
属性。奇怪的是,我无法通过删除
autofocus
属性来防止滚动。我不知道为什么,但我猜这与浏览器内部以及DOM不是ready
的事实有关。然而,我能够通过CSS隐藏billing_first_name
输入元素来防止滚动,这使我相信这是滚动的原因。在我的谷歌搜索中添加“自动聚焦”导致我对WooCommerce的类似行为提出了其他投诉,并将帖子组合在一起,使我找到了我发布的PHP解决方案。
pn9klfpd2#
已更新
由于我没有OP的页面进行测试,以下查找注册事件侦听器的方法实际上不解决OP正在解决的问题。
然而,这是当我想找到一个特定的事件时的一般方法,只是为了某人的参考而保留。
如果我正确理解了你的意思,你需要一个方法来告诉你具体的事件发生在哪里。如果这不是你想要的,请告诉我。
您可以尝试在chrome调试器上添加断点。
F12 -> Sources -> Event Listener Breakpoints(在那些Breakpoints,Scope等的列表中)-> Control -> Click the box of
scroll
.当然,它可能会捕获一些其他的滚动事件,你不感兴趣,但你可以通过它下一个下一个,直到你找到一个你想要的。
此外,也可能有与
scroll
无关的事件,您可能还需要尝试focus
或DOM Mutation -> DOMFocusIn
。