Closed GaHoWong closed 3 years ago
pjax刷新确实是一个很有用的功能,但使用它需要修改大量代码。我会试着进行修改,但很难在短期内添加pjax的支持 UwU
pjax刷新确实是一个很有用的功能,但使用它需要修改大量代码。我会试着进行修改,但很难在短期内添加pjax的支持 UwU
好,这是个长期且困难的计划,短期内确实很难实现,有你这句话我就放心。love it and just do It! 加油
大部分的修改已经做完了,但是一直没有能够解决一个非常关键的问题。
类似于这个 issue https://github.com/MoOx/pjax/issues/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 的日志中 oldEl
和 newEl
也没有问题,不知道是在哪一步做的过滤。我尝试了不同的 switch callbacks,但并没有能解决这个问题。
我现在正在试着重写 switch callback,手动将 newEl
中的元素添加到 pjax-asssets
里,不知道能否解决这个问题。
想请教一下,有没有同学知道如何解决这个问题,或是有相关的博客文章,感谢!
在更新后,
<div>
中所有的<script>
tag 都会被移除,而其他 tag (如<link>
)则不受影响
这是因为动态执行脚本需要 JS 中构造全新脚本元素(可见 执行 - Pjax 的 2021 重构),MoOx/pjax 大多数时候选择将构造的新 <script>
放到 <head>
里(不清楚动机,而且的确会影响一些依赖自身 DOM 位置的脚本)。
具体到源码,
各元素 switch 完成后(afterAllSwitches
),对 selectors
选择的每个元素调用一次 executeScript
:
https://github.com/MoOx/pjax/blob/480334b18253c721ba648675e90261f948e2bca0/index.js#L208-L213
executeScript
获取传递元素内部 <script>
,将其从其父元素移除,执行(evalScript
):
https://github.com/MoOx/pjax/blob/480334b18253c721ba648675e90261f948e2bca0/lib/execute-scripts.js#L10-L17
evalScript
在传递的 <script>
无父元素时,放到 <head>
等元素里执行:
https://github.com/MoOx/pjax/blob/480334b18253c721ba648675e90261f948e2bca0/lib/eval-script.js#L4-L5
只要 .pjax-asssets
中的脚本不依赖自身所属的 DOM 元素位置,虽然在 .pjax-asssets
里看不到了,其执行不会受到什么影响。如果有那样的依赖,就需要改写 MoOx/pjax 源码,或换其他的 Pjax 库这样子。
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