2.1.2 • Published 9 months ago

vis-pjax v2.1.2

Weekly downloads
-
License
MIT
Repository
-
Last release
9 months ago

Pjax


@visdoc/pjax是使用ts编写的一个pjax插件,独立单文件,无任何依赖,支持过渡动画,加载动画。

安装

  npm install @visdoc/pjax

构造参数说明

  • linkSelector
    • 类型: string | (container: Element|Document) => Element|NodeList|null
    • 描述: 连接元素选择器,支持字符串选择器,也可以是一个回调函数。回调函数可返回要监听事件的元素或null,参数container在初始化时为document对象,更新容器内容时为容器元素Element对象。
    • 默认: 无
  • containerSelectors
  • options 可选配置
    • options.debug
      • 类型: boolean
      • 描述: 是否开启调试模式,开启后请求加载页面失败,不会重定向
      • 默认: false
    • options.fetchOptions
      • 类型: RequestInit
      • 描述: fetch请求配置
      • 默认: {method: 'GET',headers: {Accept: 'text/html'}
    • options.behavior
      • 类型: 'smooth' | 'auto' | 'instant'
      • 描述: 页面滚动行为,默认为平滑滚动。用于滚动到锚点元素。
      • 默认: 'smooth'
    • options.topAnchors
      • 类型: string|undefined
      • 描述: 锚点元素,用于滚动到锚点元素id,无需添加#,如:top
      • 默认:undefined 滚动到页面顶部
    • options.eventDelegation
      • 类型: boolean
      • 描述: 允许事件委托,默认为true,如果为false,则只绑定当前元素,不处理子元素事件。
      • 默认:true
    • options.loadFailHandler
      • 类型: 'redirect' | 'reload' | 'none'
      • 描述: 页面加载失败时的,redirect重定向,reload强制刷新当前页面,none不处理。
      • 默认: 'redirect' 重定向到加载失败的url。
    • options.runInlineScript
      • 类型: boolean
      • 描述: 如果设置为true,则被替换的script标签中的内联脚本会被执行。
      • 默认: false
    • options.lock
      • 类型: boolean
      • 描述: 如果设置为true时,则加载过程中不会处理的新的click事件,直到加载完成。
      • 默认: false
    • options.cacheMaxLength
      • 类型: number
      • 描述: 缓存最大长度,默认为10,超过后,会删除最旧的缓存,0则不缓存。
      • 默认: 10
    • options.autoReplaceTitle
      • 类型: boolean
      • 描述: 自动替换页面标题,如果新文档存在title则替换。
      • 默认: true
    • options.logLevel

教程

  1. 基本使用

       import Pjax from '@visdoc/pjax'
       // Pjax.isSupported() 判断是否支持window.history.pushState,不支持会使用window.location.href重定向页面
       // 实例化
       const pjax = new Pjax('a', ['#content'])
       // 等待初始化就绪 也是在等待页面dom渲染完成
       await pjax.waitReadyState()
    
       // 更简洁的模式
       await Pjax.create('a', ['#content'])
  2. 切换页面

       // 基本使用
       await Pjax.factory.loadPage('/page2.html')
       // 传入fetch请求头示范
       await Pjax.factory.loadPage('/page2.html',{headers:{'token':'123'}})
  3. 绑定元素

       // 一般情况下无需使用bindElement方法,除非动态添加了元素
       // 注意:在创建pjax对象时传递的element会在页面切换过后自动重新绑定事件,也就是绑定一次就够了。
       // bindElement方法绑定的元素不会在页面切换后重新绑定,需自行在beforeReplace钩子中进行重新绑定
    
       // 某些动态渲染的元素,会导致事件失效,则可以用下面的方法重新绑定。
       Pjax.factory.bindElement('a')
       // 解绑
       Pjax.factory.unBindElement('a')
       // 为构造函数传入的选择器重新绑定事件
       Pjax.factory.reset()
       // 指定父容器,只会重新绑定指定容下的元素
       Pjax.factory.reset(document.querySelector('#container'))
  4. 🪝加载进度钩子

      pjax.onProgress = (percentage,end) => {
        console.log('当前进度:'+percentage+'%,是否结束:'+end?'是':'否')
      }
  5. 🪝内容替换钩子

       // oldElement类型为Element[],newElement类型为Element[]|string[]
       // 替换内容之前的钩子
       pjax.beforeReplace = async (oldElement, newElement) => {
         // 添加 fade-out 类,开始淡出动画
         oldElement.classList.add('fade-out');
         // 等待动画结束
         await new Promise(resolve => setTimeout(resolve, 500));
         // 移除 fade-out 类,添加 fade-in 类,开始淡入动画
         oldElement.classList.remove('fade-out');
       }
    
       // 后置的钩子,此时内容已经替换完成
       pjax.afterReplace = async (oldElement, newElement) => {
         oldElement.classList.add('fade-in');
         // 等待动画结束
         await new Promise(resolve => setTimeout(resolve, 500)); // 0.5秒的动画时间
         // 移除 fade-in 类
         oldElement.classList.remove('fade-in');
       }
       // 自定义替换内容
       pjax.beforeReplace = async (oldElement, newElement) => {
         // 没有从文档中获取到元素
         if (newElement === null) newElement = ''
         // 替换元素
         oldElement.innerHTML = typeof newElement === 'string' ? newElement : newElement.innerHTML
         return Promise.reject() // 返回Promise.reject()内部将不再执行默认的替换操作和afterReplace钩子
       }
  6. 状态管理

       // 强制刷新页面,等同于window.location.reload()
       Pjax.factory.reload(true)
       // 恢复到初始加载时的状态
       Pjax.factory.reload(false)
       // 保存当前页面状态
       Pjax.factory.saveState()
       // 获取页面状态
       Pjax.factory.getState()
  7. 代理点击事件
       document.getElementById('link')
         .addEventListener('click',function(e:Event){
           // 执行自定义的逻辑....
           // 把事件交给pjax处理
           Pjax.factory.handleClickEvent.call(this,e)
         })
       // 简洁写法
       document.getElementById('link').addEventListener('click', Pjax.factory.handleClickEvent)

动画示例

<!doctype html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>进度条动画示例</title>
  <style>
    #progress-bar-container {
      pointer-events: none; /*防止用户在动画期间与内容交互*/
      position: fixed;
      top: 0;
      left: 0;
      width: 100%;
      height: 1px;
      z-index: 9999; /*确保进度条显示在所有内容之上*/
      transform: translateY(-100%);
      transition: transform .3s ease-in-out;

      #progress-bar {
        height: 100%;
        width: 0;
        transition: width 0.3s ease-in-out; /* 平滑过渡效果 */
        background-color: #4caf50; /* 进度条颜色*/
      }
    }
  </style>
</head>
<body>
<div id="progress-bar-container">
  <div id="progress-bar"></div>
</div>
<div id="doc_content"></div>
<script type="module">
  import Pjax from '@visdoc/pjax'

  const pjax = new Pjax('#nav_container', ['#doc_content'], {
    debug: true,
    strictMatchClickEvent: false
  })
  // 等待初始化就绪
  await pjax.waitReadyState()
  // 进度条容器
  const progressContainer = document.getElementById('progress-bar-container')
  // 进度条元素
  const progressBar = document.getElementById('progress-bar')
  // 利用进度钩子显示进度条
  pjax.onProgress = (progress, end) => {
    if (progressBar) {
      if (end) {
        // 如果是结束,先将进度条宽度设置为100%
        progressBar.style.width = '100%'
      } else {
        progressContainer.style.transform = 'translateY(0)'
        // 更新进度条的宽度
        progressBar.style.width = `${progress}%`
      }
    }
  }
  // 内容替换完成将进度条容器移动偏移出窗口
  pjax.afterReplace = async (oldElement) => {
    if (oldElement.id === 'doc_content') {
      // 延迟500毫秒,关闭动画
      await new Promise((resolve) => setTimeout(resolve, 500))
      progressContainer.style.transform = 'translateY(-100%)'
    }
  }
  // 模拟调用 onProgress
  setTimeout(() => pjax.onProgress(30, false), 1000); // 1秒后进度为30%
  setTimeout(() => pjax.onProgress(60, false), 2000); // 2秒后进度为60%
  setTimeout(() => pjax.onProgress(100, true), 3000); // 3秒后进度为100%,并结束
</script>
</body>
</html>
2.1.2

9 months ago

2.1.1

9 months ago

2.0.0

9 months ago

1.0.1

9 months ago

1.0.0

9 months ago