npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

vis-pjax

v2.1.2

Published

通用pjax插件,轻量无依赖,开箱即用,支持过渡动画。

Downloads

312

Readme

Pjax


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

安装

  npm install @visdoc/pjax

构造参数说明

  • linkSelector
    • 类型: string | (container: Element|Document) => Element|NodeList|null
    • 描述: 连接元素选择器,支持字符串选择器,也可以是一个回调函数。回调函数可返回要监听事件的元素或null,参数container在初始化时为document对象,更新容器内容时为容器元素Element对象。
    • 默认: 无
  • containerSelectors
    • 类型: string[]
    • 描述: 需要替换的元素选择器,支持任意选择器,如:['.content','div.box','#container']
    • 默认: 无
  • 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
      • 类型: boolean
      • 描述: 日志等级,默认为全部日志,可选值有debug、info、warn、error
      • 默认: ['debug','info','warn','error']

教程

  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>