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

时间:2018-12-03 20:31:44

标签: javascript jquery html google-chrome debugging

我的页面上有许多第三方JS脚本。当我加载页面时,它会向下滚动到特定的div。

我已经花了2个小时试图找出导致滚动的代码。

是否有办法找出哪个脚本/部分代码触发了滚动?

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不相关的事件,您可能还需要尝试focusDOM Mutation -> DOMFocusIn

Sample