我的页面上有许多第三方JS脚本。当我加载页面时,它会向下滚动到特定的div。
我已经花了2个小时试图找出导致滚动的代码。
是否有办法找出哪个脚本/部分代码触发了滚动?
答案 0 :(得分:5)
哇,这很难调试。似乎调试器缺少一些功能,例如跟踪事件的发射器。
问题是WooCommerce。具体而言,似乎WooCommerce正在autofocus
输入字段上设置billing_last_name
。然后,浏览器将自动滚动页面以显示该字段。
人们希望有一个配置选项可以关闭自动对焦,但是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
事件上放置了一个事件断点,并试图确定在哪里生成滚动事件。尽管我发现了滚动事件,但没有找到它的来源。在此阶段,我只能确定滚动事件的目标是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引起的。
不幸的是,我的Google Fu使我失败了,我没有立即通过Google搜索发现问题。相反,我发现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表单,并发现在autofocus
字段上设置的billing_first_name
属性。
奇怪的是,我无法通过删除autofocus
属性来阻止滚动。我不知道为什么,但是我猜想这与浏览器内部以及DOM不是ready
有关。但是,我可以通过CSS隐藏billing_first_name
in put元素来防止滚动,这使我确信这是滚动的原因。
在我的Google搜索中添加“自动对焦”功能后,我对WooCommerce的其他类似行为也提出了投诉,而合并帖子后,我想到了我发布的PHP解决方案。
答案 1 :(得分:3)
已更新
由于我没有OP的测试页面,因此以下查找已注册事件监听器的方法实际上请勿解决OP正在解决的问题。
但是,这是我要查找特定事件的通用方法,仅供参考。
如果我正确理解了您的意思,则需要一种方法来告诉您特定事件在哪里发生。请告诉我这是否没有满足您的要求。
您可以尝试在chrome调试器上添加断点。
F12->源->事件侦听器断点(在这些断点,范围等列表中)->控制->单击
scroll
框。
当然,它可能会捕获您不感兴趣的其他滚动事件,但是您可以下一步进行下一步,直到找到所需的滚动事件为止。
此外,可能还会有与scroll
不相关的事件,您可能还需要尝试focus
或DOM Mutation -> DOMFocusIn
。