在 Greasemonkey 用户脚本中侦听 github.com PJAX 事件
Listening for github.com PJAX events in Greasemonkey user script
我正在处理的用户脚本在最初加载的 GitHub 页面上成功运行。尽管在使用 PJAX 导航 GitHub 时需要重新应用它。
所以我必须以某种方式为 PJAX 更改设置一个侦听器,然后 运行 initialize
再次运行。
由于 Greasemonkey/Firefox 安全策略,修补 unsafeWindow.history.pushState
将不起作用,它会抛出
Error: Permission denied to access object
我尝试检查页面脚本并挂钩到 unsafeWindow.require('jquery')
的 ajaxComplete
事件,但未触发侦听器(可能是因为相同的安全策略,但错误控制台为空).
在 PJAX 容器元素上有比 MutationObserver
/DOMSubtreeModified
更好的解决方案吗?
该脚本针对 Firefox/Greasemonkey,但如果它适用于 Chrome/Tampermonkey,这不会有什么坏处。
为文档中的 "pjax:end" 事件添加侦听器:
$(document).on('pjax:end', ...)
FWIW 在 vanilla js 中工作 example。如您所见,还使用了 MutationObserver,因为站点脚本 有时 更新动态容器两次(完全丢弃第一个),因此,在 pjax:end 处理程序完成后,一个附加 MutationObserver 处理程序以检测文件包装器的删除,在这种情况下重复处理:
document.addEventListener('pjax:end', pageChangedHandler);
function pageChangedHandler() {
.......................
var ovr = document.querySelector('include-fragment.file-wrap');
if (ovr) {
new MutationObserver(function(mutations) {
mutations.forEach(m => {
var removed = m.removedNodes[0];
if (removed && removed.matches('.file-wrap')) {
this.disconnect();
pageChangedHandler();
}
});
}).observe(ovr.parentNode, {childList:true});
}
}
我正在处理的用户脚本在最初加载的 GitHub 页面上成功运行。尽管在使用 PJAX 导航 GitHub 时需要重新应用它。
所以我必须以某种方式为 PJAX 更改设置一个侦听器,然后 运行 initialize
再次运行。
由于 Greasemonkey/Firefox 安全策略,修补 unsafeWindow.history.pushState
将不起作用,它会抛出
Error: Permission denied to access object
我尝试检查页面脚本并挂钩到 unsafeWindow.require('jquery')
的 ajaxComplete
事件,但未触发侦听器(可能是因为相同的安全策略,但错误控制台为空).
在 PJAX 容器元素上有比 MutationObserver
/DOMSubtreeModified
更好的解决方案吗?
该脚本针对 Firefox/Greasemonkey,但如果它适用于 Chrome/Tampermonkey,这不会有什么坏处。
为文档中的 "pjax:end" 事件添加侦听器:
$(document).on('pjax:end', ...)
FWIW 在 vanilla js 中工作 example。如您所见,还使用了 MutationObserver,因为站点脚本 有时 更新动态容器两次(完全丢弃第一个),因此,在 pjax:end 处理程序完成后,一个附加 MutationObserver 处理程序以检测文件包装器的删除,在这种情况下重复处理:
document.addEventListener('pjax:end', pageChangedHandler);
function pageChangedHandler() {
.......................
var ovr = document.querySelector('include-fragment.file-wrap');
if (ovr) {
new MutationObserver(function(mutations) {
mutations.forEach(m => {
var removed = m.removedNodes[0];
if (removed && removed.matches('.file-wrap')) {
this.disconnect();
pageChangedHandler();
}
});
}).observe(ovr.parentNode, {childList:true});
}
}