我正在为一个站点编写一个Greasemonkey脚本,该站点在某个时候修改location.href
。
当window.location.href
在一个页面上发生变化时,我如何获得一个事件(通过window.addEventListener
或类似的东西)?我还需要访问指向新的/修改后的url的文档的DOM。
我见过其他涉及超时和轮询的解决方案,但如果可能的话,我希望避免这种情况。
我正在为一个站点编写一个Greasemonkey脚本,该站点在某个时候修改location.href
。
当window.location.href
在一个页面上发生变化时,我如何获得一个事件(通过window.addEventListener
或类似的东西)?我还需要访问指向新的/修改后的url的文档的DOM。
我见过其他涉及超时和轮询的解决方案,但如果可能的话,我希望避免这种情况。
9条答案
按热度按时间hjqgdpho1#
我在我的扩展中使用这个脚本“抓取任何媒体”,工作很好(* 像YouTube案例 *)
使用最新的javascript规范
用OpenAI压缩
7kqas0il2#
popstate event:
popstate事件在活动的历史条目发生变化时被激发。[...] popstate事件只会通过执行浏览器操作来触发,比如点击后退按钮(或者在JavaScript中调用history. back())
因此,在使用
history.pushState()
时侦听popstate
事件并发送popstate
事件应足以对href
更改采取操作:vlju58qv3#
您无法避免轮询,因为没有任何href更改事件。
如果你不过分的话,使用间隔是很轻的。如果你担心的话,每50ms左右检查一次href不会对性能有任何显著的影响。
n6lpvg4x4#
您可以使用默认的
onhashchange
事件。Documented HERE
并且可以像这样使用:
如果浏览器不支持
oldURL
和newURL
,您可以这样绑定它:nnt7mjpx5#
通过Jquery,只需尝试
通过使用javascript:
参考文件:https://developer.mozilla.org/en-US/docs/Web/Events/beforeunload
qrjkbowd6#
您是否尝试过beforeUnload?此事件在页面响应导航请求之前立即触发,这应该包括对href的修改。
但是,请注意,无论何时***您离开页面,事件都会触发,无论这是因为脚本,还是有人点击链接。您真实的的挑战是检测触发事件的不同原因。(如果这对您的逻辑很重要)
n9vozmp47#
试试这个脚本,它可以让你在URL改变时运行代码(没有页面加载,就像单页应用程序一样):
jgovgodb8#
有两种方法可以修改
location.href
。要么你可以写location.href = "y.html"
,它会重新加载页面,要么你可以使用历史API,它不会重新加载页面。我最近经常尝试第一种方法。如果你打开一个子窗口并从父窗口获取子页面的负载,那么不同的浏览器的行为会有很大的不同。唯一的共同点是,它们会删除旧文档并添加一个新文档,因此,例如,向旧文档添加readystatechange或load事件处理程序没有任何效果。大多数浏览器也会从window对象中删除事件处理程序,唯一的例外是Firefox。在带有Karma runner的Chrome和Firefox中,如果使用
unload + next tick
,则可以在加载readyState中捕获新文档。因此,您可以添加一个load事件处理程序或readystatechange事件处理程序,或者只记录浏览器正在加载带有新URI的页面。在带有手动测试的Chrome中(可能也是GreaseMonkey),而在Opera、PhantomJS、IE10、IE11中,您无法在加载状态下捕获新文档。在这些浏览器中,unload + next tick
调用回调的时间比页面的加载事件触发时间晚几百毫秒。延迟通常为100到300毫秒。但是opera simetime在下一个tick时会有750毫秒的延迟,这是很可怕的,所以如果你想在所有浏览器中得到一致的结果,那么你可以在load事件之后做你想做的事情,但是不能保证在此之前位置不会被覆盖。如果您只在Firefox中运行脚本,那么您可以使用简化版本并在加载状态下捕获文档,例如,在您记录URI更改之前,加载页面上的脚本无法导航离开:
如果我们讨论的是改变URI哈希部分的单页应用程序,或者使用历史API,那么你可以分别使用窗口的
hashchange
和popstate
事件。即使你在历史中来回移动,直到你停留在同一页,这些事件也可以捕获。文档不会被这些事件改变,页面也不会被真正重新加载。nzkunb0c9#
根据“列奥纳多Ciaccio”的答案,修改后的代码如下所示:即删除for循环,如果删除,则重新分配Body元素