如何绕过导航时的DOMContentLoaded

我们有一个在 DOMContentLoaded 上运行的 js 函数,document.addEventListener(“DOMContentLoaded”, OURFUNCTION)。

刷新浏览器时运行正常,但在浏览网站时却从未显示。我推测这是因为 Discourse 只加载一次 DOM,然后其余部分通过客户端导航处理,就像 SPA 一样。所以我想知道,我们如何在 Discourse 本身中导航更改时运行该函数?以前可以通过插件 API 轻松做到这一点,但那些 API 已被弃用,而且我在任何组件中都看不到它们了。是否仍有简单的方法可以做到这一点?或者我们需要创建一个完整的组件来仅在导航更改时执行一些 JavaScript?谢谢。

嘿,

如果你在寻找页面加载时触发的事件,可以使用 api.onPageChange

api.onPageChange((url, title) => {
   console.log('the page changed to: ' + url + ' and title ' + title);
});

如果你在寻找其他东西,能否详细说明一下你想实现什么?我们可以给你一个更精确的答案。

顺便说一句,你有很多文档可能对你有帮助:https://meta.discourse.org/c/documentation/developer-guides。

3 个赞

嗯……我不确定这是否能保证 DOM 内容已加载,我相信它会在路由更改时触发,这要早得多。

如果 DOM 加载很重要,您需要考虑将组件附加到插件插槽并使用 didInsert 修饰符触发。

如果仅路由更改很重要,那么是的,onPageChange 应该可以做到 :+1:

1 个赞

你说得对!:thinking:

onPageChange 会在下一个 runloop 中调用,所以我认为在大多数情况下它仍然会在 DOMContentLoaded 之后调用,但我不能保证。

我可以看到一些用法依赖于 onPageChange 并直接进行 DOM 元素操作。顺便问一下,routeDidChange 事件是从哪里触发的(编辑:它是从 ember 触发的:RouterService | 6.7.0 | Ember API Documentation

我同意 didInsert modifier,非常巧妙!

1 个赞

谢谢。我已仔细阅读了文档,根据我的评论以及 Discourse 成员的后续跟进,该插件 API 是旧版且即将弃用。因此,虽然您的代码现在可能有效,但我相信它在未来的更新中很快就会失效。这就是我正在寻找更好解决方案的原因。为此创建一个 Glimmer 组件似乎有些小题大做,所以我希望有另一个事件我们可以使用。

我不认为那是正确的。

上周已更新。

已弃用的是:

  • widget API
  • 原始模板
  • 覆盖模板(总体而言)
3 个赞

谢谢你的澄清!所以只是小部件 API。好的,我将首先尝试上面提供的 API 建议。

3 个赞

这有点像一种恩赐 :sweat_smile:,Glimmer 对开发者来说要友好得多

2 个赞

顺便说一句,我们用 api.OnPageChange 测试了它,运行正常。我们还没有遇到过在调用 OnPageChange 时 DOM 内容不可用的情况,所以它似乎是在 DomContentLoaded 之后触发的。但是,我不能百分之百确定。感谢您的帮助。

3 个赞

好的。请注意,时间不能保证。但很高兴它能满足您的用例!

1 个赞

您能更好地解释一下这是什么意思吗?didInsert 修改器是什么?我是在 decorateCookedElement 上触发的。谢谢。

1 个赞
1 个赞

文档是罗伯特指出的方法;你也可以在仓库中看到大量示例:Code search results · GitHub

1 个赞

哦,好的,所以这是一个 Ember 功能,与 Discourse 无关?代码中唯一真正与“Discourse”相关的部分是 pluginoutlet?

1 个赞

是的,它是 Glimmer 标准的一部分

pluginOutlets 只是特殊的 Components,它们被设计用来挂载其他 Components:

2 个赞