Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FEATURE] Some feature:支持pjax刷新 #78

Closed
GaHoWong opened this issue May 28, 2021 · 4 comments · Fixed by #135
Closed

[FEATURE] Some feature:支持pjax刷新 #78

GaHoWong opened this issue May 28, 2021 · 4 comments · Fixed by #135
Labels
enhancement Enhance existing features

Comments

@GaHoWong
Copy link

Describe the feature you want 描述你的功能需求

你好,我最近遇到了一些棘手的问题,在我使用APlayer音乐播放器当作背景音乐时,当我点击主题的其他地方,音乐就会刷新并重新播放,这种体验很糟糕。也让我很苦恼,当我去寻找解决方法是发现使用PJAX可以完美解决我的问题,我还发现hexo最热门的那几个主题同样使用了PJAX,比如next、butterfly、sakura、material-x等等主题。

使用pjax的体验很好,在点击其它地方时,比如footer、header这些可以不用重复加载,减少服务器压力,提高加载速度,提升用户体验。

pjax具有以下优点:
按需请求,每次只需加载页面的部分内容,而不用重复加载一些公共的资源文件和不变的页面结构,大大减小了数据请求量,以减轻对服务器的带宽和性能压力,还大大提升了页面的加载速度
常规页面跳转需要重新加载画面上的内容,会有明显的闪烁,而且往往和跳转前的页面没有连贯性,用户体验不是很好。如果再遇上页面比较庞大、网速又不是很好的情况,用户体验就更加雪上加霜了。使用pjax后,由于只刷新部分页面,切换效果更加流畅,而且可以定制过度动画,在等待页面加载的时候体验就比较舒服了。

Useful reference 有价值的参考

If available, provide useful links to fulfill the feature.
如果可以的话, 提供实现这个功能的相关参考链接.
1.pjax使用小结:https://www.jianshu.com/p/557cad38e7dd
2.让你的网站实现 pjax 无刷新:https://paugram.com/coding/add-pjax-to-your-website.html
3.这是一个运用了pjax的hugo主题:https://github.com/vvc-Dream/hugo-maupassant-pjax

@GaHoWong GaHoWong added the enhancement Enhance existing features label May 28, 2021
@HEIGE-PCloud
Copy link
Owner

pjax刷新确实是一个很有用的功能,但使用它需要修改大量代码。我会试着进行修改,但很难在短期内添加pjax的支持 UwU

@GaHoWong
Copy link
Author

pjax刷新确实是一个很有用的功能,但使用它需要修改大量代码。我会试着进行修改,但很难在短期内添加pjax的支持 UwU

好,这是个长期且困难的计划,短期内确实很难实现,有你这句话我就放心。love it and just do It! 加油

@HEIGE-PCloud HEIGE-PCloud linked a pull request May 29, 2021 that will close this issue
@HEIGE-PCloud
Copy link
Owner

大部分的修改已经做完了,但是一直没有能够解决一个非常关键的问题。

类似于这个 issue MoOx/pjax#230 DoIt 主题在不同页面上会有不同数量和内容的 <script> tag,所以所有可以开关的 script(如 KaTeX,lightgallery)都需要进行 pjax-reload。

我的实现方式是将所有 script (包括部分 CSS)拆分进两个不同的 <div> 中。

<div class="assets">
    <script type="text/javascript" src="/lib/autocomplete/autocomplete.min.js"></script>
    <script type="text/javascript" src="/lib/algoliasearch/algoliasearch-lite.umd.min.js"></script>
    <script type="text/javascript" src="/lib/lazysizes/lazysizes.min.js"></script>
    <script type="text/javascript" src="/lib/topbar/topbar.min.js"></script>
    <script type="text/javascript" src="/lib/pjax/pjax.min.js"></script>
    <script type="text/javascript" src="/js/theme.min.js"></script>
</div>
<div class="pjax-assets">
    <script type="text/javascript" src="/lib/lightgallery/lightgallery.min.js"></script>
    <script type="text/javascript" src="/lib/lightgallery/lg-thumbnail.min.js"></script>
    <script type="text/javascript" src="/lib/lightgallery/lg-zoom.min.js"></script>
    <script type="text/javascript" src="/lib/clipboard/clipboard.min.js"></script>
    <script type="text/javascript" src="/lib/sharer/sharer.min.js"></script>
    <script type="text/javascript">window.config={"code":{"copyTitle":"Copy to clipboard","maxShownLines":10},"comment":{},"lightGallery":{"actualSize":false,"exThumbImage":"data-thumbnail","hideBarsDelay":2000,"selector":".lightgallery","speed":400,"thumbContHeight":80,"thumbWidth":80,"thumbnail":true},"search":{"algoliaAppID":"5YGRNRQK1G","algoliaIndex":"en_index","algoliaSearchKey":"0ff6874805de24b84aa1d5ebccad56cd","highlightTag":"em","maxResultLength":10,"noResultsFound":"No results found","snippetLength":30,"type":"algolia"},"sharerjs":true};</script>
    <link rel="stylesheet" href="/lib/lightgallery/lightgallery.min.css">
</div>

assets 中存放的是所有不需要刷新,也不会有变动的 script,而 pjax-assets 则会被整个刷新(selectors: [".pjax-assets", ...])。但是在更新后,<div> 中所有的 <script> tag 都会被移除,而其他 tag (如 <link>)则不受影响。 pjax 的日志中 oldElnewEl 也没有问题,不知道是在哪一步做的过滤。我尝试了不同的 switch callbacks,但并没有能解决这个问题。

我现在正在试着重写 switch callback,手动将 newEl 中的元素添加到 pjax-asssets 里,不知道能否解决这个问题。

想请教一下,有没有同学知道如何解决这个问题,或是有相关的博客文章,感谢!

@HEIGE-PCloud HEIGE-PCloud linked a pull request Jul 10, 2021 that will close this issue
5 tasks
@PaperStrike
Copy link

PaperStrike commented Jul 16, 2021

在更新后,<div> 中所有的 <script> tag 都会被移除,而其他 tag (如 <link>)则不受影响

这是因为动态执行脚本需要 JS 中构造全新脚本元素(可见 执行 - Pjax 的 2021 重构),MoOx/pjax 大多数时候选择将构造的新 <script> 放到 <head> 里(不清楚动机,而且的确会影响一些依赖自身 DOM 位置的脚本)。

具体到源码,

  1. 各元素 switch 完成后(afterAllSwitches),对 selectors 选择的每个元素调用一次 executeScript
    https://github.com/MoOx/pjax/blob/480334b18253c721ba648675e90261f948e2bca0/index.js#L208-L213

  2. executeScript 获取传递元素内部 <script>,将其从其父元素移除,执行(evalScript):
    https://github.com/MoOx/pjax/blob/480334b18253c721ba648675e90261f948e2bca0/lib/execute-scripts.js#L10-L17

  3. evalScript 在传递的 <script> 无父元素时,放到 <head> 等元素里执行:
    https://github.com/MoOx/pjax/blob/480334b18253c721ba648675e90261f948e2bca0/lib/eval-script.js#L4-L5

只要 .pjax-asssets 中的脚本不依赖自身所属的 DOM 元素位置,虽然在 .pjax-asssets 里看不到了,其执行不会受到什么影响。如果有那样的依赖,就需要改写 MoOx/pjax 源码,或换其他的 Pjax 库这样子。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement Enhance existing features
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants