简体   繁体   English

如何检测onscroll事件是否以编程方式生成?

[英]How to I detect if an onscroll event was programmatically generated?

I'd like to have a handler fire whenever the user scrolls, but I don't want it to happen when the browser scrolls on behalf of the user. 我想在用户滚动时触发处理程序,但是当浏览器代表用户滚动时我不希望它发生。 For example, the document below scrolls itself as part of onload. 例如,下面的文档将自身滚动为onload的一部分。 This fires my onscroll handler, but I don't want it to. 这会触发我的onscroll处理程序,但我不希望它。 Even if I remove the onload, there's still a problem: if the user scrolls and then reloads the page, the handler fires upon reload. 即使我删除了onload,仍然存在一个问题:如果用户滚动然后重新加载页面,则处理程序会在重新加载时触发。 Again, I don't want that. 再说一遍,我不希望如此。

Can the handler detect who caused it to be fired? 处理程序可以检测是谁导致它被解雇了吗?

<html>
 <body onscroll="alert('scroll detected')"
       onload="window.scrollBy(0, document.height)">
  aaa<br/>bbb<br/>ccc<br/>ddd<br/>eee<br/>fff<br/>ggg<br/>hhh<br/>iii<br/>
  jjj<br/>kkk<br/>lll<br/>mmm<br/>nnn<br/>ooo<br/>ppp<br/>qqq<br/>rrr<br/>
  sss<br/>ttt<br/>uuu<br/>vvv<br/>www<br/>xxx<br/>yyy<br/>zzz
 </body>
</html>

How about setting a (boolean) flag whenever you move the screen programmatically, and unsetting again, when the move is finished? 每当您以编程方式移动屏幕时设置(布尔)标志,并在移动完成时再次取消设置怎么样? Then your scroll-listener would first check against that flag, and make its actions based on that? 那么你的滚动侦听器会首先检查该标志,并根据它做出它的动作?

On examining the result of an action only (the document has been scrolled), you can't determine what cause the action. 在仅检查操作的结果(文档已滚动)时,您无法确定导致操作的原因。

Examining a change in state of certain properties before and after an action will help you in determining the cause of the action, assuming such relevant properties change differently depending on the cause of the change. 检查操作之前和之后某些属性的状态更改将帮助您确定操作的原因,假设此类相关属性根据更改的原因而有所不同。

You should consider properties that may be relevant to the action of scrolling a document, and then consider how these properties may change: 您应该考虑可能与滚动文档的操作相关的属性,然后考虑这些属性可能如何更改:

  • as a result of a document being scrolled 作为滚动文档的结果
  • when a person performs the scrolling 当一个人进行滚动时
  • when a browser performs the scrolling 当浏览器执行滚动时

When a person scrolls a document they may: 当一个人滚动文档时,他们可以:

  • hit a key (down arrow, up arrow, page down, page up, ctrl-end, ctrl-home) 点击一个键(向下箭头,向上箭头,向下翻页,向上翻页,ctrl-end,ctrl-home)
  • move the pointer to the scrollbar, click around a bit, move away from the scrollbar 将指针移动到滚动条,单击一下,远离滚动条

The following event pattern would indicate a person scrolling: 以下事件模式表示某人滚动:

  • a scroll-relevant key is pressed OR the mouse moves off the browser canvas (on to the scrollbar) 按下滚动相关键鼠标移出浏览器画布(在滚动条上)
  • the document scrolls 文件滚动

In the case of a browser performing the action, the document merely scrolls without any preceding relevant key or mouse event. 在浏览器执行动作的情况下,文档仅滚动而没有任何先前的相关键或鼠标事件。

In observing what happens before a scroll event occurs, you should be able to determine if the action was initiated by a person. 在观察滚动事件发生之前发生的事情时,您应该能够确定该动作是否是由人发起的。 Whilst this certainly may be tricky to implement, the logic is sound. 虽然这可能很难实现,但逻辑是合理的。

How about adding the onscroll event during the document.onReady event, instead of inline on the body command? 如何在document.onReady事件期间添加onscroll事件,而不是在body命令上内联? I think this should allow for the browser to scroll to the position, before you've added the onScroll event. 我认为这应该允许浏览器在添加onScroll事件之前滚动到该位置。

Another option is to add a setTimeout() to call a function to add the onscroll event a few hundred milliseconds after the document is completely rendered. 另一种选择是添加一个setTimeout()来调用一个函数,在文档完全呈现后的几百毫秒内添加onscroll事件。

In short: you can't 简而言之:你做不到

Although, doing something like this with the help of a javascript library such as Prototype would be very easy using custom events: 虽然,在Prototype等javascript库的帮助下做这样的事情会很容易使用自定义事件:

<script language="javascript">
    document.observe('user:scrolling', function() { alert('yay!'); });
</script>
...
<body onscroll="document.fire('user:scrolling')">

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM