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

use*_*961 2 html javascript debugging jquery google-chrome

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

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

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

Old*_*Pro 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');
Run Code Online (Sandbox Code Playgroud)

如果这不起作用,则可以创建CSS规则以隐藏帐单名称字段,然后在页面完全加载后运行延迟的JS函数以显示帐单名称字段。


我如何调试它

根据OP的请求,并考虑提供的赏金,我将描述如何调试此功能。

我不只是对自己说:“嗯,页面向上滚动到表单,光标在表单的第一个字段中,我想知道它是否设置了自动对焦,这让我有些尴尬。” 不幸的是,我主要不是前端程序员,autofocus起初没有想到。

我首先想到的是它是通过JavaScript滚动的,或者是显式调用滚动函数,或者是通过设置scrollTop某种东西。我在事件上放置了一个事件断点,scroll并试图确定在何处生成滚动事件。尽管我发现了滚动事件,但没有找到它的来源。在此阶段,我所能确定的只是滚动事件的目标是document,而不是其中的任何内容。

我过去一直monitorEvents在监听事件document,发现只有3个,单击和2个滚动,最后一个滚动是由OP插入的延迟滚动到顶部功能导致的,以解决第一个滚动。我将执行断点设置为设置超时(不执行功能),以尝试“分而治之”,即查看滚动是在此之前还是之后进行。我将在其余的调试工作中维护该断点。

奇怪的是,通常页面在到达该断点之前不会滚动,但有时会滚动。我以为这很奇怪,尽管我不知道该怎么做,但它使我一直在寻找与众不同的东西。

我尝试在所有JavaScript中搜索“滚动”和“更新”(文本),以查找要设置的更多断点,并在JavaScript上设置了一些滚动但没有成功的断点。

我注意到有很多JavaScript动态地更新页面,并认为滚动可能是由于某种形式的更新所致。

我试图把一个jQuery的事件侦听器记录的所有事件document(因为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>
Run Code Online (Sandbox Code Playgroud)

关于此脚本标签的怪异之处在于,在处理完此脚本标签后立即发生了滚动,但是jQuery已经加载,因此该脚本实际上什么也没做。我还可以通过控制台确认在此脚本标记之前和之后(滚动之前和之后),DOM均未标记为ready。这意味着ready在滚动发生时,所有jQuery 处理程序都尚未运行。这消除了很多JavaScript,并且让我思考了为什么滚动发生在此标记之后而不是之前。

我猜想,在内部,浏览器看到了document.write调用,并确定DOM在传递该标记之前是不完整的,但是一旦它过去,DOM就完整了,它可以开始处理页面级属性了。这与早期的观察结果一起,使我更加仔细地查看了WooCommerce表单,并发现了autofocusbilling_first_name字段上设置的属性。

奇怪的是,我无法通过删除autofocus属性来阻止滚动。我不知道为什么,但是我猜想这与浏览器内部以及DOM并非有关ready。但是,我可以billing_first_name通过CSS 隐藏in put元素来防止滚动,这使我确信这是滚动的原因。

在我的Google搜索中添加“自动对焦”功能导致我对WooCommerce的类似行为提出了其他投诉,而合并帖子使我想到了我发布的PHP解决方案。


MT-*_*ong 5

更新

由于我没有OP的测试页面做的,找到注册事件侦听器的下面的方法其实不要解决问题的任择议定书正在解决。

但是,这是我想查找特定事件时的通用方法,仅供参考。


如果我正确理解您的意思,您需要一种方法来告诉您特定事件发生在哪里。请告诉我这是否不是您想要的。

您可以尝试在 chrome 调试器上添加断点。

F12 -> Sources -> Event Listener Breakpoints(在那些断点、范围等列表中)-> Control -> 单击scroll.

当然,它可能会捕获一些您不感兴趣的其他滚动事件,但是您可以逐个浏览它,直到找到您想要的那个。

此外,可能还有与 无关的事件scroll,您可能还需要尝试focusDOM Mutation -> DOMFocusIn

样本