volantis-x / hexo-theme-volantis

A Wonderful Theme for Hexo.
https://volantis.js.org
MIT License
2.07k stars 600 forks source link

【建议】:使用 onerror 事件来改善外部引用 cdn 资源失败时切回内部本地文件 #902

Open Tikas opened 1 year ago

Tikas commented 1 year ago

检查清单

需求描述

想法来源

昨天在开发主题时,给局域网的设备访问,由于局域网并没有开启 "正确" 上网方式,导致使用 cdnjs 引用的 js 和 css 文件无法正常加载,为此想到了为何不在加载失败后切回本地文件呢?

实现原理

好吧,其实我根本没学 js,全程是和 chatGPT 对话以达到最终实现。

实现代码例子

2023 年 8 月 28 日修改了判断语句,之前的判断语法不正确,非常抱歉,首次开发,很多还不是很了解,修改内容具体示例如下:

if theme.swiper_cdnjs.js.src !== ''

//- 改正:

if theme.swiper_cdnjs.js.src

JS 部分我是这样写的,在 cdn 文件加载失败后能正常切换回本地文件,并执行 Swiper 成功

(修改:在此处增加提示,此为 PUG 格式)

if homePage && theme.slide.enable
  script.
    function loadSwiperJS() {
      const script = document.createElement('script')
      script.src = '/js/swiper-bundle.min.js'
      script.onload = () => {
        initSwiperConfig()
      }
      document.body.appendChild(script)
    }
    function initSwiperConfig() {
      let homeSwiper = new Swiper('.home-swiper', {
        spaceBetween: 30,
        centeredSlides: true,
        effect: 'fade',
        loop: true,
        autoplay: {
          delay: 8000,
          disableOnInteraction: false
        }
      })
    }

  //- import swiper js
  if theme.swiper_cdnjs.enable && theme.swiper_cdnjs.js.src
    if theme.swiper_cdnjs.js.integrity
      script(src=url_for(theme.swiper_cdnjs.js.src) integrity=theme.swiper_cdnjs.js.integrity crossorigin='anonymous' referrerpolicy='no-referrer' onerror='loadSwiperJS()' onload='initSwiperConfig()')
    else
      script(src=url_for(theme.swiper_cdnjs.js.src) crossorigin='anonymous' referrerpolicy='no-referrer' onerror='loadSwiperJS()' onload='initSwiperConfig()')
  else
    script(src=url_for(theme.slide.js) onload='initSwiperConfig()')

CSS 部分的代码:(修改:在此处增加提示,此为 PUG 格式)

if theme.slide.enable && homePage
  script.
    function loadSwiperCSS() {
      const link = document.createElement('link')
      link.rel = 'stylesheet'
      link.href = '/css/swiper-bundle.min.css'
      document.head.appendChild(link)
    }
  if theme.swiper_cdnjs.enable && theme.swiper_cdnjs.css.href
    if theme.swiper_cdnjs.css.integrity
      link(rel='stylesheet' href=url_for(theme.swiper_cdnjs.css.href) integrity=theme.swiper_cdnjs.css.integrity crossorigin='anonymous' referrerpolicy='no-referrer' onerror='loadSwiperCSS()')
    else
      link(rel='stylesheet' href=url_for(theme.swiper_cdnjs.css.href) crossorigin='anonymous' referrerpolicy='no-referrer' onerror='loadSwiperCSS()')
  else
    link(rel='stylesheet' href=url_for(theme.slide.css))

主题配置文件参考:

# 启用后,本地的 slide js 和 css 将会在 cdn 加载出错时调用,请确保 slide 里的 js 和 css 有设置
swiper_cdnjs:
  enable: true
  js:
    src: https://cdnjs.cloudflare.com/ajax/libs/Swiper/10.2.0/swiper-bundle.min.js
    integrity: sha512-QwpsxtdZRih55GaU/Ce2Baqoy2tEv9GltjAG8yuTy2k9lHqK7VHHp3wWWe+yITYKZlsT3AaCj49ZxMYPp46iJQ==
  css:
    href: https://cdnjs.cloudflare.com/ajax/libs/Swiper/10.2.0/swiper-bundle.min.css
    integrity: sha512-s6khMl5GDS1HbQ5/SwL1wzMayPwHXPjKoBN5kHUTDqKEPkkGyEZWKyH2lQ3YO2q3dxueG3rE0NHjRawMHd2b6g==

slide:
  enable: true
  js: /js/swiper-bundle.min.js # 当 swiper_cdnjs 开启时,只有出错时才会加载本地 swiper js
  css: /css/swiper-bundle.min.css # 当 swiper_cdnjs 开启时,只有出错时才会加载本地 swiper css

额外求助

2023年9月8号修改了此部分,求助的内容是想把引入的 script 代码里 js 文件使用变量去取代,具体可以看上面的代码。

现在已经找到了实现的办法,使用 pug 的插值去实现,具体代码如下:

if homePage && theme.slide.enable
  script.
    function loadSwiperJS() {
      const script = document.createElement('script')
      script.src = '/js/swiper-bundle.min.js'
      script.onload = () => {
        initSwiperConfig()
      }
      document.body.appendChild(script)
    }

//- 改正:

if homePage && theme.slide.enable
  script.
    function loadSwiperJS() {
      const script = document.createElement('script')
      script.src = '#{theme.slide.js}'
      script.onload = () => {
        initSwiperConfig()
      }
      document.body.appendChild(script)
    }

参考链接

暂无

xaoxuu commented 10 months ago

很好的想法,可以提高用户体验。但是我觉得这额外的投入不太值得,在 Stellar 主题中,我没有借鉴 Volantis 对于 cdn 的便捷性方面的支持(也就是说用户想改的话需要自己逐个修改)因为这些东西都需要额外的时间和精力去维护,不太适合个人或小团队的开源作品。

Tikas commented 10 months ago

是的,也正是因为我有许多这些想法,导致越发觉得 hexo 并不是很理想,当发现 Astro 时,才深深发现,这才是我想要的

xaoxuu commented 10 months ago

我看了文档介绍觉得很酷,但是看了几个示例博客感觉实际表现却不怎么样,我以为能做到切换像SPA一样的文档树切换体验,但是没有(例如官网切换页面后左侧列表不能记住位置)

Docs
入门指南
简单介绍 Astro。
Tikas commented 10 months ago

做到切换像 SPA 一样的文档树切换体验,虽然不知道是什么样的体验,个人猜想应该是无缝切换的体验。

很明确回答,可以的,详情可以来这查看:https://www.bilibili.com/video/BV1Zp4y1j7jv/

只是这样的操作,会使页面加载 JS 代码,而很多 Astro 页面并不喜欢 JS 代码存在。

Astro 3.0 有哪些新功能?_哔哩哔哩_bilibili
https://www.youtube.com/watch?v=wHkZ4hY-3zkAstro 3.0 包含两项令人惊叹的功能: 视图转换和图像优化, 视频播放量 1355、弹幕量 0、点赞数 15、投硬币枚数 0、收藏人数 10、转发人数 0, 视频作者 前端亮亮, 作者简介 微信号:FrontEnd1984 WordPress皮肤+插件资源:http://mtw.so/6gc3So,相关视频:CSS 新功能 | CSS Anchor,购买Macbook之后,一定要改变的设置 & 必装软件!(2024最新)feat. 隐藏功能 |大耳朵TV,您应该知道的 7 种常用的 TypeScript 类型,用CSS从0高度过渡到自动高度的简单技巧,使用HTML和CSS创建水滴效果的登录界面,使用HTML、CSS和JavaScript创建范围选择滑块,如何使用HTML和CSS制作下拉菜单 | HTML网站教程,使用HTML和CSS创建简单的科幻卡片悬停效果 | 源码下载,使用HTML、CSS和JavaScript构建音乐播放器,新的3D动画无代码工具Dora
xaoxuu commented 10 months ago

你对比一下这两个:

https://github.com/volantis-x/hexo-theme-volantis/assets/16400144/25408fcd-c683-4c1e-9389-e2263d4b2158

https://github.com/volantis-x/hexo-theme-volantis/assets/16400144/bd968a75-4dca-4b2f-a11e-03e34e5ab7a5

Docs
入门指南
简单介绍 Astro。
Next.js Image – Nextra
Make beautiful websites with Next.js & MDX.
Tikas commented 10 months ago

非常直观,感谢录制视频,Astro 感觉可以做这样的效果,只是我也没研究,不知道能不能把文档树也加进如同导航栏里,这样就能有这样的效果了。

很抱歉,我对 Astro 只在了解层,连理论层都没达到,实践经验更是没有。

这个回复并不能代表了准确的答案。

Tikas commented 10 months ago

看之前提供的 B站 3.0 视频里演示,03:30 里点击菜单时,菜单并没有刷新,Astro 是可以增加多个群岛进来的,完全可以把文档树也加进来,为此,理论上是能做到这效果的。

看了 Astro 的文档,在关于【Astro 群岛】已经明确写明了单个页面内可以存在多个群岛,为此,文档树的效果完全可以实现。

这次是肯定的回复

xaoxuu commented 10 months ago

我翻了翻 showcase 也没有找到有这样效果的,所以还在观望中,等啥时候有了再迁移。

Tikas commented 10 months ago

再次罗嗦一下,请见谅,因为这个视频进一步达到了我想要的效果。

https://www.youtube.com/watch?v=acgIGT0J99U

Astro 的组件化功能实在是我的大爱,完全不用担心和别的地方冲突。

它能生成最小的体积,默认是无 js 代码的,理论上只要自己不引入外部文件,就能达到最小的 html 体积。

同时它也实现了我一直想要的 svg 内联。

哈哈,竟然翻遍了也没能看到这效果,为此,我必需相信你的判断,因为我并不是专业的开发人员。

同时也抱有是否没人去做这效果,而不是说 Astro 不能做这效果,这个观望也是明智的。

我的 js 还在学习中,css 运用也不是很理想,一切都还是新人阶段,不能自己去验证了,非常抱歉

xaoxuu commented 10 months ago

Astro 设计理念确实很优秀,现在因为不确定能不能解决我最关心的那个长目录切换体验问题,如果有案例确定支持的话,我还是很乐意尽快学习一下的。现在官网本身都没有那个效果,所以我猜测大概是暂时不支持的。期待后续更新~

Tikas commented 9 months ago

今天看完 Astro 的搭建教程,怀着兴奋的心态,优先尝试了 SPA 文档切换的效果,为了节省时间,直接把 Astro 官方的文档仓下载回来,只需要增加一个视图过渡动画效果,就实现了理论上的效果。

是的,理论上的效果,因为左侧的目录滚动条会回滚上去,或许,您有时间来研究研究一下?

(因为 Astro 官方也是点击会回滚到前面,我怀疑这是另一个东西在控制着,这句话比较重要也复制在前面)

以下是实现过程,非常简单:

1、下载 Astro 官方文档仓:https://github.com/withastro/docs 2、安装依赖,如:pnpm i 3、在 src > components > starlight > Head.astro 这个文件增加以下内容:

---
// 文件头部内容加下面内容
import { ViewTransitions } from 'astro:transitions';
---

<!-- 在文件内容区域后面加以下内容 -->
<ViewTransitions />

4、预览体验,如:pnpm run dev

进一步了解具体可以参考 https://docs.astro.build/zh-cn/guides/view-transitions/

可能是我 JS 还没学完,没有想到如何解决回滚问题(因为 Astro 官方也是点击会回滚到前面,我怀疑这是另一个东西在控制着)

GitHub
GitHub - withastro/docs: Astro documentation
Astro documentation. Contribute to withastro/docs development by creating an account on GitHub.
Docs
视图过渡动画
在 Astro 中通过视图过渡动画实现页面之间的无缝导航。
xaoxuu commented 9 months ago

体验好的话发布完 volantis 6.0 就开发个 astro 版的主题

Tikas commented 6 months ago

最近一直在研究 Astro ,现已经实现了多语言,分类页面,接下来还要处理标签页面以及单独页面,等这次的完成,后续我们找大家一起看看怎么弄个 Astro 的版本,让 Volantis 的下一个主题,使用 Astro,此计划或许会在 6 月或者 7 月开始。

到时我可以先做个 demo 出来