next-theme / hexo-theme-next

🎉 Elegant and powerful theme for Hexo.
https://theme-next.js.org
Other
2.41k stars 426 forks source link

v8.4.0(以及之后)版本 pjax 无法重新加载页面的自定义 js #334

Closed aoemon closed 3 years ago

aoemon commented 3 years ago

Please follow this Issue template to provide relevant information, such as source code repository, website URL and screenshots, which will help us investigate. 请按照此 Issue 模版提供相关信息,例如源码仓库、网站链接和屏幕截图,这将有助于我们进行调查。

Issue Checklist


v8.3.0 升级到 v8.4.0 以及之后版本,pjax 无法重新加载通过 custom_file_path 注入点 bodyEnd 向页面中注入的自定义 js

source/_data/body-end.njk

{% if page.type === 'test' %}
<script src="/js/75u5u0/test.js"></script>
{% endif %}

source/js/75u5u0/test.js

alert('test');

v8.3.0 的页面切换中 pjax 可以重新加载 js,并弹出框

image

v8.4.0 以及之后版本页面切换 pjax 无法重新加载 js,必须要刷新整个页面

请问我应该如何重新加载该自定义 js?

PaperStrike commented 3 years ago

你可以加上 data-pjax HTML 属性重载整个 <script>,在你的 source/_data/body-end.njk 中如

{% if page.type === 'test' %}
<script data-pjax src="/js/75u5u0/test.js"></script>
{% endif %}

或者, 在脚本里侦听 documentpjax:successpage:loaded 事件。前者在 Pjax 刷新后触发,后者在页面初载以及 Pjax 刷新后触发。在你的 source/js/75u5u0/test.js 中如:

document.addEventListener('page:loaded', () => {
 alert('test');
});
aoemon commented 3 years ago

@PaperStrike 感谢您的回答。我尝试了您给出的两种解决方案,但仍然存在一些问题:

如果首次进入的是 网站根目录,再切换到 /test/ 页面,问题与之前描述的一样,无法加载该 js,并且再次页面切换 pjax 也无法重新加载该 js

如果首次进入的是 /test/,js 可以加载,并且再进行页面切换,pjax 也可以重新加载该 js。另外,这种情形下我发现每切换一个页面都会重新加载该 js,而我只想在 /test/ 页面加载:

{% if page.type === 'test' %}
  <script data-pjax src="/js/75u5u0/test.js"></script>
{% endif %}
PaperStrike commented 3 years ago

这样在其他页面不一定以 <script> 元素引入的脚本,就不要放在 bodyEnd 里,可以放在 postBodyEnd。


From: 时帅 @.> Sent: Tuesday, August 3, 2021 5:23:40 PM To: next-theme/hexo-theme-next @.> Cc: 滑 @.>; Mention @.> Subject: Re: [next-theme/hexo-theme-next] v8.4.0(以及之后)版本 pjax 无法重新加载页面的自定义 js (#334)

@PaperStrikehttps://github.com/PaperStrike 感谢您的回答。我尝试了您给出的两种解决方案,但仍然存在一些问题:

如果首次进入的是 网站根目录https://hexo-blog-o7tces473-aoemon.vercel.app/,再切换到 /test/https://hexo-blog-o7tces473-aoemon.vercel.app/test/ 页面,问题与之前描述的一样,无法加载该 js,并且再次页面切换 pjax 也无法重新加载该 js

如果首次进入的是 /test/https://hexo-blog-o7tces473-aoemon.vercel.app/test/,js 可以加载,并且再进行页面切换,pjax 也可以重新加载该 js。另外,这种情形下我发现每切换一个页面都会重新加载该 js,而我只想在 /test/ 页面加载:

{% if page.type === 'test' %}

{% endif %}

― You are receiving this because you were mentioned. Reply to this email directly, view it on GitHubhttps://github.com/next-theme/hexo-theme-next/issues/334#issuecomment-891686112, or unsubscribehttps://github.com/notifications/unsubscribe-auth/AFM7XXGKZTH64LZ4MKMKYHDT26YRZANCNFSM5BDSVBFA.

aoemon commented 3 years ago

@PaperStrike postBodyEnd 不是只针对 /posts/ 下的文章页吗,菜单页根本不会加载

PaperStrike commented 3 years ago

bodyEnd 现在存放各个页面内都会固定存在的东西,像 head 注入点一样。

对于单一页面需要的额外脚本元素,最佳实践是直接放在其 markdown 里。按道理,文章里的脚本都应该被自动重载,但因为一些历史问题,现在不会,需要加上 data-pjax HTML 属性。例如

---
title: Test
---
<script data-pjax src="/js/test.js"></script>

对于某些页面不需要,而非单一的另一些页面需要的脚本元素,最佳实践是在所有页面都引入,不使用 data-pjax,改写脚本,使用第一个回复里提到的事件侦听,然后用某些条件判断是否运行。例如

document.addEventListener('page:loaded', () => {
  // 运行条件不满足时简单跳出
  if (!someCondition) return;
  alert('test');
});

如果该脚本无法改写,那就再写一个脚本,上述 “所有页面都引入” 的指这个新脚本,这个新脚本形如:

(function() {
  const loadMyScript = () => {
    if (!someCondition) return;
    const script = document.createElement('script');
    script.src = '/js/test.js'; // 那个无法改写的 “旧” 脚本
    document.head.append(script);
    document.removeEventListener('page:loaded', loadMyScript);
  });
  document.addEventListener('page:loaded', loadMyScript);
})();
aoemon commented 3 years ago

@PaperStrike 感谢!由于我只对单一页面引入额外 js,我尝试将其移入 markdown,并加上 data-pjax 属性,它可以正常工作。

github-actions[bot] commented 2 years ago

This thread has been automatically locked since there has not been any recent activity after it was closed. It is possible issue was solved or at least outdated. Feel free to open new for related bugs.