Chrome 是什么原因导致此网页在加载时向下滚动?

ybzsozfc  于 2023-05-20  发布在  Go
关注(0)|答案(2)|浏览(216)

我有一个第三方JS脚本堆页面。当我加载页面时,它会向下滚动到一个特定的div。
我已经花了两个小时试图找出是哪一个代码导致了滚动。
有没有办法找出是哪个脚本/代码的哪一部分触发了滚动?

crcmnpdw

crcmnpdw1#

哇,这么难调试。似乎调试器缺少一些功能,比如跟踪事件的发射器。
问题是WooCommerce。具体来说,WooCommerce似乎在billing_last_name输入字段上设置了autofocus。然后浏览器会自动滚动页面,将字段显示在视图中。
人们希望有一个配置选项来关闭自动对焦,但似乎WooCommerce没有提供这一点。
您可以尝试将此添加到您的主题

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记录的自定义事件,并且我已经确定documentscroll事件的目标)来发出所有事件,并查看它是否是一些自定义更新事件。有一堆自定义事件,我后来在控制台中生成了这些事件,以查看页面是否会滚动作为响应。由于我无法让页面以这种方式滚动,我得出结论,事件很可能是一个死胡同。
我改变了策略。我看了看页面滚动到哪里,看到它正在滚动WooCommerce表单。因此,在执行断点处停止(如上所述)时,我从DOM中删除了整个WooCommerce表单,并验证页面不再滚动。这让我相信,无论问题是什么,它都是由WooCommerce引起的。
不幸的是,我的谷歌福辜负了我,我没有立即通过谷歌搜索找到问题。相反,我发现WooCommerce如何在错误时滚动页面,以确保错误消息可见。这让我回到了JavaScript。
尽管如此,还是有很多JavaScript,其中很多是动态创建表单的(动态本地化),还有一堆德语(我不会说),我没有发现任何导致滚动的JavaScript。我真的很想缩小导致滚动的JS文件的范围。
Chrome允许你在“脚本第一条语句”上设置断点(在事件监听器断点->脚本下),所以我这样做了。除了在每个脚本文件的第一行停止外,它还在页面上每个<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,并让我思考为什么滚动发生在这个标记之后而不是之前。

我猜测,在内部,浏览器看到了document.write调用,并确定DOM在通过该标记之前是不完整的,但一旦通过该标记,DOM就完成了,它可以开始处理页面级属性。这与之前的观察沿着,让我更仔细地查看了WooCommerce表单,并发现了billing_first_name字段上设置的autofocus属性。
奇怪的是,我无法通过删除autofocus属性来防止滚动。我不知道为什么,但我猜这与浏览器内部以及DOM不是ready的事实有关。然而,我能够通过CSS隐藏billing_first_name输入元素来防止滚动,这使我相信这是滚动的原因。
在我的谷歌搜索中添加“自动聚焦”导致我对WooCommerce的类似行为提出了其他投诉,并将帖子组合在一起,使我找到了我发布的PHP解决方案。

pn9klfpd

pn9klfpd2#

已更新

由于我没有OP的页面进行测试,以下查找注册事件侦听器的方法实际上解决OP正在解决的问题。
然而,这是当我想找到一个特定的事件时的一般方法,只是为了某人的参考而保留。
如果我正确理解了你的意思,你需要一个方法来告诉你具体的事件发生在哪里。如果这不是你想要的,请告诉我。
您可以尝试在chrome调试器上添加断点。
F12 -> Sources -> Event Listener Breakpoints(在那些Breakpoints,Scope等的列表中)-> Control -> Click the box of scroll.
当然,它可能会捕获一些其他的滚动事件,你不感兴趣,但你可以通过它下一个下一个,直到你找到一个你想要的。
此外,也可能有与scroll无关的事件,您可能还需要尝试focusDOM Mutation -> DOMFocusIn

相关问题