第三方通用库

重要通知

作为一枚杰出的前端架构设计者,除了基础的前端技术栈外,还需要涉猎其他诸如常用第三方工具库、video、audio、SVG、canvas、WebRTC、WebGL、WebAssembly、C++、Python、mysql、mongodb、redis、docker、K8S等生态体系。

JS工具库

Rx.js

RxJS 是一个使用可观察序列编写异步和基于事件的程序的库。它提供了一种核心类型,即ObservableArray 、卫星类型(Observer、Scheduler、Subjects)和受方法启发的操作符( map、filter、reduce、every等),以允许将异步事件作为集合处理。

import { fromEvent } from 'rxjs';
fromEvent(document, 'click').subscribe(() => console.log('Clicked!'));

Lodash

Lodash是一个一致性、模块化、高性能的 JavaScript 实用工具库,高度封装了常用JS基本类型与引用类型的方法。

const { merge, mergeWith } = require('lodash/object');
  • 按需加载
// lodash-es 是 Lodash 的一个 ES 模块版本,专为 tree-shaking 设计。
import { cloneDeep } from 'lodash-es';


// Lodash 提供了模块化的构建版本,允许你只导入需要的函数。
import cloneDeep from 'lodash/cloneDeep';
  • 防抖函数
const debounce = require('lodash/debounce');
window.addEventListener('resize', debounce(() => {
  // 防抖任务程序
}, 150), false);
  • 节流函数
const throttle = require('lodash/throttle');
document.querySelector('#text').addEventListener('resize', throttle(() => {
  // 节流任务程序
}, 1000), false);
  • 对比两个对象
import transform from 'lodash/transform';
import isEqual from 'lodash/isEqual';
import isObject from 'lodash/isObject';

function diff(data) {
  function changes(object, base) {
    return transform(object, function(result, value, key) {
      if (!isEqual(value, base[key])) {
        result[key] = (isObject(value) && isObject(base[key])) ? changes(value, base[key]) : value;
      }
    });
  }
  // 对比数据
  return changes(data.default, data.contrast);
}
console.log(Object.keys(diff(contrast.UserUpload)).length );
  • 深拷贝
const cloneDeep = require('lodash/cloneDeep');

var objects = [{ 'a': 1 }, { 'b': 2 }];
var deep = cloneDeep(objects);
console.log(deep[0] === objects[0]);
  • 合并两个对象,非覆盖式

_.mergeWith( object, sources, customizer )

import { mergeWith, isArray } from 'lodash'


// 加工数据
const mergeOptions = mergeWith({ ...defaultOptions }, { ...options }, customizer)
const mergeOptions = mergeWith({ ...defaultOptions }, { ...options })
console.info('mergeOptions: ', mergeOptions)

function customizer(obj: Record<string, any>, src: Record<string, any>) {
	if (isArray(obj)) {
		return obj.concat(src)
	}
}


// 示例二
function customizer(obj, src) {
  if (lodash.isArray(obj)) {
    return obj.concat(src);
  }
}

var object = {
  name: '张三',
  students,
  'amit': [{ 'susanta': 20 }, { 'durgam': 40 }]
};

var other = {
  name: '李四',
  students: { history: { name: '张鸣' } },
  'amit': [{ 'chinmoy': 30 }, { 'kripamoy': 50 }]
};

console.log(lodash.mergeWith(object, other, customizer));

Prototype

Prototype 是一个 JavaScript 框架,旨在简化动态 Web 应用程序的开发。它提供了熟悉的类风格的 OO 框架、广泛的 Ajax 支持、高阶编程结构和简单的 DOM 操作。


deep-diff

用于nodejs 和浏览器中计算深度差异、捕获更改和跨对象应用更改的 Javascript 实用程序。

const diff = require('deep-diff');

const lhs = {};
const rhs = {};
const differences = diff(lhs, rhs);

功能管理库

tributejs

tribute.js 是一个轻量级的 JavaScript 库,用于实现类似 Twitter 的提及(mention)功能。

import Tribute from "tributejs";


const tribute = new Tribute({
  values: [
    { key: 'user1', value: 'User One' },
    { key: 'user2', value: 'User Two' },
    // ...其他提及项
  ],
  onSelect: (e, item) => {
    console.log('用户选择了:', item.original.value);
    // 在这里可以执行自定义行为,比如更新输入框的值、发送请求等
  }
});

document.getElementById('input').addEventListener('tribute-selected', tribute.onSelect);

字体管理库

fontmin

第一个纯 JavaScript 字体子集化方案

var Fontmin = require('fontmin');

var fontmin = new Fontmin()
  .src('fonts/*.ttf')
  .dest('build/fonts');
fontmin.run(function (err, files) {
  if (err) throw err;
  console.log(files[0]);
  // => { contents: <Buffer 00 01 00 ...> }
});

lottie-web

Lottie 是一个适用于 Android、iOS、Web 和 Windows 的库,它解析Adob​​e After Effects动画,使用Bodymovin以 json 格式导出,并在移动设备和 Web 上本地呈现它们!

lottie.loadAnimation({
  container: element, // the dom element that will contain the animation
  renderer: 'svg',
  loop: true,
  autoplay: true,
  path: 'data.json' // the path to the animation json
});

文档管理

SheetJS

SheetJS 社区版提供了久经考验的开源解决方案,用于从几乎任何复杂的电子表格中提取有用的数据,并生成适用于传统和现代软件的新电子表格。

// { CFB, SSF, parse_xlscfb, parse_zip, read, readFile, readFileSync, set_cptable, set_fs, stream, utils, write, writeFile, writeFileAsync, writeFileSync, writeFileXLSX, writeXLSX }
import XLSX from 'xlsx';

const fileSelector = document.querySelector("input[type='file']");
fileSelector.onchange = function(e) {
  const file = e.target.files[0];
  const reader = new FileReader();
  
  console.log(file.size);
  reader.onload = function() {
    const result = e.target.result || this.result;
    xlsxHandler(result);     
  }
  // reader.readAsArrayBuffer(file);
  reader.readAsBinaryString(file);
}

// xlsx解析
function xlsxHandler(data) {
  // console.log(data);

  const workbook = XLSX.read(data, { type: 'binary' });
  console.log(workbook);
  workbook.SheetNames.forEach((sheet) => {
    const item = workbook.Sheets[sheet];

    document.querySelector('section').innerHTML = XLSX.utils.sheet_to_html(item);
  });
}

文档预览功能对比分析

LibreOffice

OpenOffice

文档预览: ONLYOFFICE

最新的onlyoffice自带了jwt验证,我们只需要用于文档预览,没必要使用jwt,而关闭jwt需要在启动容器中加参数。

sudo docker run -i -t -d -p 8051:80 --restart=always -e JWT_ENABLED=false -e HTTP_PROXY=http://14.103.138.13:8058 onlyoffice/documentserver

sudo docker run -i -t -d -p 8051:80 --restart=always -e JWT_ENABLED=false onlyoffice/documentserver

访问地址:http://[ip]:8051 // ip:主机IP js脚本:http://[ip]:8051/web-apps/apps/api/documents/api.js

  • Adding fonts to ONLYOFFICE Docs: https://helpcenter.onlyoffice.com/installation/docs-community-install-fonts-linux.aspx

    • 默认字体估计不满足,需要重新添加字体
    • 进入ONLYOFFICE容器环境:docker exec -it [containerID] /bin/bash
    • 拷贝相关字体,到ONLYOFFICE容器的目录:/usr/share/fonts/
    • 进入ONLYOFFICE容器目录:/usr/bin
    • 执行该指令:./documentserver-generate-allfonts.sh
    • 清除浏览器缓存,并重新加载即可。
  • 在线Office文档预览的加载速度太慢,Issue:https://github.com/ONLYOFFICE/CommunityServer/issues/228

    • Docker DNS配置问题,因为默认的 Docker DNS 指向Google DNS,限制因素等会导致很慢
    • vim /etc/resolv.conf 修改 DNS地址
  • 关于onlyoffice在docker里用非80无法访问,是moodle里设置的,安全-http安全-cURL允许的端口列表,删除或添加即可。

  • 文档缓存问题,需要实时更新key标识

  • 自定义UI

  • 二次开发经验

  • 编辑器/查看器配置

const docEditor = new DocsAPI.DocEditor("placeholder", {
  // 文档
  document: {
    fileType: '',  // 定义已查看或编辑的源文档的文件类型。 必须为小写。
    key: '', // 定义服务用于识别文档的唯一文档标识符。
    title: '', // 为查看或编辑的文档定义所需的文件名,下载文档时该文件名也将用作文件名。 长度限制为 128 个符号。
    url: '', // 定义存储源查看或编辑的文档的绝对 URL。 请务必在使用本地链接时添加令牌。

    // 文档权限部分允许更改要编辑和下载的文档的权限。
    permissions: {
      chat: false,
      comment: false,
      fillForms: false,
      edit: false,
      copy: false,
      deleteCommentAuthorOnly: false,
      download: false,
      editCommentAuthorOnly: false,
      modifyContentControl: false,
      modifyFilter: false,
      print: false,
      protect: false,
      review: false
    }
  },

  // 编辑器配置
  editorConfig: {
    // 自定义部分允许自定义编辑器界面,使其看起来像您的其他产品(如果有),并更改附加按钮、链接、更改徽标和编辑器所有者详细信息的存在与否。
    customization: {
      anonymous: {
        request: false
      },
      comments: false, // 定义是显示还是隐藏“注释”菜单按钮。
      help: false,
      hideRightMenu: true,
      hideNotes: true,
      review: false,
      plugins: false,
      compactToolbar: false,
      toolbarNoTabs: true,
      logo: {
        image: 'https://cos-imgx.feierfit.com/erp-static/image/favicon.ico',
        imageEmbedded: 'https://cos-imgx.feierfit.com/erp-static/image/favicon.ico',
        url: 'https://erp.feierfit.com/'
      }
    },

    actionLink: ACTION_DATA,
    callbackUrl: "https://example.com/url-to-callback.ashx",
    coEditing: {
      "mode": "fast",
      "change": true
    },
    createUrl: "https://example.com/url-to-create-document/",
    lang: "en", // 默认语言,可选"zh" "" ""
    location: "",
    mode: "edit", // 模式,可选 "view" "edit"
    recent: [
      {
        "folder": "Example Files",
        "title": "exampledocument1.docx",
        "url": "https://example.com/exampledocument1.docx"
      }
    ],
    region: "en-US",
    templates: [
      {
        "image": "https://example.com/exampletemplate1.png",
        "title": "exampletemplate1.docx",
        "url": "https://example.com/url-to-create-template1"
      }
    ],
    user: {
      "group": "Group1",
      "id": "78e1e841",
      "name": "John Smith"
    }
  },
  // 定义浏览器窗口中的文档宽度(默认为 100%)。
  width: "100%",
  // 在浏览器窗口中定义文档高度(默认为 100%)
  height: "100%",
  // 定义以令牌形式添加到文档服务器配置的加密签名。
  token: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.e30.LwimMJA3puF3ioGeS-tfczR3370GXBZMIL-bdpu4hOU",
  // 定义用于访问文档的平台类型。
  type: "desktop" // desktop-桌面 mobile-移动设别 embedded-形成为易于嵌入到网页中-嵌入
});
  • 预览配置
<body>
<!-- 占位元素 -->
<div id="placeholder"></div>
</body>

<!-- onlyoffice服务器地址 -->
<script src="http://192.168.1.22:9002/web-apps/apps/api/documents/api.js"></script>

<script type="text/javascript">
  /**
   * 详细配置文档:https://api.onlyoffice.com/editors/config/
   * @param url 要预览的文档地址
   * @param filename 要预览的文档文件名
   */
  function preview(url, filename) {
    const config = {
      "document": {
        "permissions": {
          comment: false,
          fillForms: false,
          "edit": false,
        },
        "fileType": "docx",
        "title": filename,
        "url": url,
        // "key": this.md5,
        "lang": "zh-CN"
      },
      "width": '100%',
      "editorConfig": {
        mode: 'view',
        "lang": "zh-CN"
      }
    };
    document.title = filename;
    const docEditor = new DocsAPI.DocEditor("placeholder", config);
  }

  // 调用方法
  let filename = "123.docx"
  let url = "http://192.168.1.3000:5100/123.docx"
  preview(url, filename);
</script>

文档预览: kkFileView

kkFileView为文件文档在线预览解决方案。

> 下载镜像: docker pull keking/kkfileview:4.3.0
> 运行: docker run -i -t -d -p 8052:8012 --restart=always keking/kkfileview:4.3.0
  • 手动下载最新版本, 更新版本后部署
# 加载镜像
docker load -i kkFileView-4.3.0-docker.tar
# 运行
docker run -i -t -d -p 8052:8012 --restart=always keking/kkfileview:4.3.0
docker run -i -t -d -p 8053:8011 --restart=always keking/kkfileview:4.3.0.1
docker run -i -t -d -p 8054:8012 --restart=always keking/kkfileview:4.3.0.2

# 如果使用Nginx代理,则需求重新配置如下
upstream svrsrmTest {
  server 110.41.4.150:8052;
}
server {
  listen           8059;
  server_name      110.41.4.150;
  location / {
    proxy_pass     http://svrsrmTest;
  }
}

# 运行
docker run -i -t -d -p 8053:8012 --restart=always keking/kkfileview:4.3.0.1
  • 自定义源码打包镜像
# 环境要求
+ Java: 1.8+
+ Maven: 3.4+

# 从码云仓库拉取代码
git clone https://gitee.com/kekingcn/file-online-preview.git

# 使用Maven编译打包
cd file-online-preview
/usr/local/apache-maven-3.9.3/bin/mvn clean package -DskipTests

# 使用docker构建镜像
cd file-online-preview
docker build -t keking/kkfileview:4.3.0.2 .
  • 自定义源码内容
> server/src/main/resources/web/officeweb.ftl
> server/src/main/java/cn/keking/ServerMain.java

# 传输镜像给ERP服务器
get /home/download/kkfileview-4.3.0.2-docker.tar.gz /data/home/wangjun

server/src/main/resources/web/officeweb.ftl

<div id="button-area">
    <label><button onclick="tiaozhuan()">跳转HTML预览</button></label>
    <button id="confirm-button" onclick="print()">打印</button>
</div>
<div id="luckysheet" style="margin:0px;padding:0px;position:absolute;width:100%;left: 0px;top: 20px;bottom: 0px;outline: none;"></div>

<script>
  LuckyExcel.transformExcelToLuckyByUrl(value, name, function(exportJson, luckysheetfile) {
    console.info('exportJson:', exportJson)
    console.info('luckysheetfile:', luckysheetfile)
  }
</script>

server/src/main/resources/static/xlsx/luckysheet.umd.js

function luckysheetDrawgridRowTitle(scrollHeight, drawHeight, offsetTop) {
  let luckysheetTableContent = $("#luckysheetTableContent").get(0).getContext("2d");
}

server/src/main/resources/static/xlsx/luckyexcel.umd.js

LuckyExcel.transformExcelToLuckyByUrl = function(url, name, callBack, errorHandler) {
  var handleZip = new HandleZip_1.HandleZip();
  handleZip.unzipFileByUrl(url, function (files) {
    console.info(files?.["xl/worksheets/sheet1.xml"])
  }
}

var method_1 = require("./common/method");
var jszip_1 = __importDefault(require("jszip"));

HandleZip.prototype.unzipFileByUrl = function (url, successFunc, errorFunc) {
  method_1.getBinaryContent(url, function (err, data) {
    jszip_1["default"].loadAsync(data).then(function (zip) {
      zip.forEach(function (relativePath, zipEntry) {
        zipEntry.async(fileType).then(function (data) {
          // 这里数据源与返回数据内容不匹配,会出现数据错误问题
        })
      })
    })
  })
}

server/src/main/java/cn/keking/ServerMain.java

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class ServerMain {
  public static void main(String[] args) {
    private static final Logger logger = LoggerFactory.getLogger(ServerMain.class);

    logger.info("日志记录: {},{} ", "", "");
  }
}

server/src/main/java/cn/keking/web/controller/OnlinePreviewController.java

public String onlinePreview(String url, Model model, HttpServletRequest req) {
  logger.info("预览文件url:{},previewType:{}", fileUrl, fileAttribute.getType());
  return filePreview.filePreviewHandle(fileUrl, model, fileAttribute);
}

server/src/main/java/cn/keking/service/FilePreview.java

public interface FilePreview {
  String EXEL_FILE_PREVIEW_PAGE = "html";
  String filePreviewHandle(String url, Model model, FileAttribute fileAttribute);
}

server/src/main/java/cn/keking/service/FileHandlerService.java

public class FileHandlerService {
  public void doActionConvertedFile(String outFilePath) {
    // 添加sheet控制头
    sb.append("<script src=\"js/jquery-3.6.1.min.js\" type=\"text/javascript\"></script>");
    sb.append("<script src=\"js/excel.header.js\" type=\"text/javascript\"></script>");
    sb.append("<link rel=\"stylesheet\" href=\"bootstrap/css/xlsx.css\">");
  }
}

OfficeWeb365

永中Docs

https://www.yozodcs.com/page/help.htmlopen in new window

金山WPS

collabora

handsontable

canvas-datagrid

微软预览

https://view.officeapps.live.com/op/view.aspx?src=https://test.ysunlight.com/ServerCore/STATIC/files/excel.xlsx

xlsx、xls SheetJS js-xlsx

import XLSX from 'xlsx';


const file = await createFile();
const fileReaderData = await getFileReaderData(file, 'binary');

const workbook = XLSX.read(fileReaderData, { type: 'binary' });

// 获取Sheets选项
const sheets = Object.values(workbook.Sheets);
let curentSheet = {};

for (let i = 0; i < sheets.length; i++) {
  const sheet = sheets[i];
  const cells = Object.values(sheet);
  const cellList = (cells || []).filter(((item: Record<string, any>) => item.w === ruleForm.title));

  if (cellList.length) {
    curentSheet = sheet;
    break;
  }
}

const curentCells = Object.entries(curentSheet);


// 创建文件
export async function createFile(options = {} as Record<string, any>) {
  const { accept } = options;

  const input = document.createElement("input");
  input.setAttribute("type", "file");

  if (accept) {
    input.setAttribute("accept", accept);
  }

  input.click();

  const fileData = await getFileData(input);
  return fileData;
}

// 获取文件数据
export function getFileData(fileInput: HTMLInputElement) {
  return new Promise((resolve) => {
    fileInput.onchange = async function (e: { target: any }) {
      resolve(e.target.files[0]);
    };
  });
}

/**
 * 读取文件流
 * @param fileData 文件数据:e.target.files[0]
 * @param type 返回流类型:'arraybuffer'|'binary'|'text'|'dataurl'
 * @returns
 */
export function getFileReaderData(fileData: any, type = "text" as string) {
  const reader = new FileReader();

  return new Promise((resolve) => {
    reader.onload = function () {
      resolve(this.result);
    };

    // 转换为小写
    switch (String(type).toLowerCase()) {
      case "arraybuffer":
        reader.readAsArrayBuffer(fileData);
        break;
      case "binary":
        reader.readAsBinaryString(fileData);
        break;
      case "dataurl":
        reader.readAsDataURL(fileData);
        break;
      default:
        reader.readAsText(fileData);
    }
  });
}

PDF.js

PDF.js是一个用于解析和呈现PDF 的通用、基于 Web 标准的平台。

async function init() {
  await doLoadScriptCallback('/public/source/pdf/modern/pdf.js');

  try {
    // 如果pdfjsLib异常,则触发catch逻辑并执行loadOldPdfSDK()旧有浏览器补丁
    // 如果pdfjsLib存在但非有效值则直接执行loadOldPdfSDK()旧有浏览器补丁
    if (!pdfjsLib) {
      await doLoadScriptCallback('/public/source/pdf/legacy/pdf.min.js');
    }
  } catch(e) {
    await doLoadScriptCallback('/public/source/pdf/legacy/pdf.min.js');
  }

  if (!pdfjsLib) return;

  
  const agreementUrl = 'https://test.ysunlight.com/ServerCore/STATIC/files/threejs.pdf';
  const loadingTask = pdfjsLib.getDocument(agreementUrl);
  
  loadingTask.promise.then(function(pdf) {
    const numPages = pdf._pdfInfo;
    
    pdf.getPage(1).then(function(page) {
      // 取消动画
      const ratio = window.devicePixelRatio;
      const viewport = page.getViewport({ scale: ratio });
      const canvas = document.createElement('canvas');
      const context = canvas.getContext('2d');
      canvas.height = viewport.height;
      canvas.width = viewport.width;

      const renderContext = {
        canvasContext: context,
        viewport,
      };
      page.render(renderContext);
      document.body.appendChild(canvas);
    });
  });
}
init();

PDFObject

常见问题

  • 解决跨域问题, 报错 "file origin does not match viewer's"

注释掉web/viewer.js中部分代码

// var fileOrigin = new URL(file, window.location.href).origin;
// if (fileOrigin !== viewerOrigin) {
//   throw new Error("file origin does not match viewer's");
// }
  • pdf.js中身份认证

找到build下的pdf.js文件,加上请求头token的设置代码即可

var params = Object.create(null);
var rangeTransport = null,
  worker = null;

// 添加设置token代码
params['httpHeaders'] = {
  "Authentication": window.localStorage.getItem('TOKEN')
}
  • 分段加载

web下viewer.js

disableAutoFetch: true,
disableStream: true

build/pdf.js

var DEFAULT_RANGE_CHUNK_SIZE = 65536*16

Gantt Chart

dhtmlxGantt是一个开源的 JavaScript 甘特图,可以帮助您在漂亮的图表中说明项目进度,基于甘特图的在线项目管理解决方案。

代码高亮

Prism.js

Highlight.js

语言类型

  • language-javascript
  • language-typescript
  • language-scss
  • language-less
  • language-css
  • language-html
  • language-c
  • language-c++

代码示例

<template>
  <pre>
    <code class="language-javascript">
const name = "";

function doXxxFn() {
  //
}
    </code>
  </pre>
</template>


<script lang="ts" setup>
// 第三方资源类库或插件
import { onMounted } from 'vue';
import hljs from 'highlight.js';
import 'highlight.js/styles/default.min.css';


/**
 * @当前业务
 * 具体逻辑实现代码
 */
onMounted(() => {
	hljs.highlightAll();
});
</script>

Rainbow.js

UI组件

popper.js

提供Tooltip、Popover等浮悬提示框的基础功能。

nprogress

进度条控件

Swiper

Swiper是纯javascript打造的滑动特效插件,面向手机、平板电脑等移动终端。

new Swiper('#swiper3', {
  autoplay: true,              // 可选选项,自动滑动
  initialSlide: 2,             // 设定初始化时slide的索引, 默认为0
  direction : 'vertical',
  loop: true,                  // 循环模式选项
  speed: 300,                  // 切换速度,即slider自动滑动开始到结束的时间(单位ms),也是触摸滑动时释放至贴合的时间。
  watchOverflow: true,         // 当没有足够的slide切换时,例如只有1个slide,swiper会失效且隐藏导航等。默认不开启这个功能。loop模式无效,因为会复制slide。
  on: {                        // 注册事件,Swiper4.0开始使用关键词this指代Swiper实例。
    slideChange: function () {
      console.log(this.activeIndex);
    },
  },
  init: false,                 // 当你创建一个Swiper实例时是否立即初始化。
});



document.addEventListener("DOMContentLoaded", function () {
  //
});





const swiper = new Swiper('.swiper', {
  loop: true,
  speed: 500,

  autoplay: false,
  pagination: {
    el: '.swiper-pagination',
    clickable: true,
  },
  navigation: {
    nextEl: '.swiper-button-next',
    prevEl: '.swiper-button-prev',
  },
  keyboard: {
    enabled: true,
    onlyInViewport: true,
  },
  mousewheel: {
    invert: false,
    forceToAxis: true,
  },
}); 

Typing.js

Typing.js是一个史上最华丽的打字效果JS插件

var typing = new Typing({
  source: document.getElementById('source'),
  output: document.getElementById('output'),
  delay: 80,
  done: function() {} //完成打印后的回调事件
});
typing.start();

impress.js

impress.js是基于CSS3转换和过渡的表现层框架,工作于现代浏览器(Google Chrome或Safari (或 Firefox 10 或 IE10))的创建在线演示的JS库, 可以让开发者轻松创建杀手级在线演示PPT。

Cropper.js

Cropper.js是一个JavaScript 图像裁剪器。

import Cropper from 'cropperjs';
import 'cropperjs/dist/cropper.css';

iScroll

iScroll是一个高性能,资源占用少,无依赖,多平台的javascript滚动插件,具备滚动,缩放,平移,无限滚动,视差滚动、轮播、旋转功能。

const scroll = new IScroll('#wrapper');

不同的 iScroll 类型

  • iScroll.js:这是一个通用脚本,包括最常用的功能,以确保以较小的占用空间实现最佳性能。

  • iScroll-lite.js:这是主脚本的最小化版本。如果您只需要滚动,想想移动网站,iScroll Lite 就是您所需要的。本质上,您不会获得其他功能,例如滚动条、对齐、鼠标滚轮和键绑定。总而言之,iScroll Lite 提供强大的性能,其中仅包含必备功能。

  • iScroll-probe.js:如果您需要探测当前滚动位置,也可以使用 iScoll。iScroll-probe.js 可让您在任何时间点确定滚动位置。

  • iScroll-zoom.js:您想为标准滚动添加缩放吗?这是您需要的 iScroll 版本。

  • iScroll-infinite.js:如果您希望拥有可以支持无限和缓存滚动的滚动功能,iScroll Infinite 将适合该位。此版本基于缓存机制,可让您快速滚动无限数量的元素。

  • 完整案例

import IScroll from '@/plugins/iscroll/iscroll-probe.js';

const iscroll = new IScroll('#wrapper', {
  probeType: 3,     // 必须设置,否则监听scroll失效
  mouseWheel: true,  // 跟踪鼠标滚轮事件。
  mouseWheelSpeed: Number,    // 定义鼠标滚轮的速度。
  scrollbars: true,
  bounce: 
  bounceTime   // 以毫秒为单位定义反弹动画的持续时间。
  click: 
  eventPass: 
  keyBindings:   // 激活键盘交互
  invertWheelDirection: 
  mouseWheel: 
  momentum: 
  preventDefault: 
  scrollX: 
  scrollY: 
  freeScroll: 
  Tap: 
  bindToWrapper: 
  deceleration:   // 定义了动画动量在速度和持续时间方面的变化。
  resizePolling:   // 当需要调整窗口大小时,iScroll 会重新计算元素的尺寸和位置。
});

// 一旦用户触摸屏幕但在滚动开始之前执行。
iscroll.on('beforeScrollStart', (e) => {});

// 滚动已启动但未发生。
iscroll.on('scrollCancel', (e) => {});

// 滚动开始。
iscroll.on('scrollStart', (e) => {});

// 内容正在滚动。scroll-probe.js仅在版本中可用。请参阅onScroll 事件。
iscroll.on('scroll', (e) => {});

// 内容停止滚动。
iscroll.on('scrollEnd', (e) => {});

// 用户向左/向右轻弹。
iscroll.on('flick', (e) => {});

// 用户开始缩放。
iscroll.on('zoomStart', (e) => {});

// 缩放结束。
iscroll.on('zoomEnd', (e) => {});

better-scroll

better-scroll是一个为移动端(已支持 PC)各种滚动场景提供丝滑的滚动效果的原生 JS 库。它的核心是借鉴的 iscroll (opens new window)的实现,它的 API 设计基本兼容 iscroll,在 iscroll 的基础上又扩展了一些 feature 以及做了一些性能优化。

基本语法

import BetterScroll from 'better-scroll'

const hbs = BetterScroll.createBScrolll('.wrapper', {
  mouseWheel: true,  // 支持鼠标滚动
  stopPropagation: true,
  bounce: false,
  probeType: 3
});



bs.on('scrollStart', (e) => {
  console.log('鼠标 滚动开始: ', e)
});

bs.on('scroll', (e) => {
  console.log('鼠标 滚动过程: ', e)
});

bs.on('mousewheelStart', (e) => {
  console.log('滚轮 滚动开始: ', e)
});

bs.on('mousewheelMove', (e) => {
  console.log('滚轮 滚动过程: ', e)
});

bs.on('mousewheelEnd', (e) => {
  console.log('滚轮 滚动结束: ', e)
});

代码示例一:上下滚动

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <meta
      name="viewport"
      content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"
    />
    <meta name="mobile-web-app-capable" content="yes" />

    <title>Better Scroll</title>

    <link rel="icon" href="/public/favicon.ico" />
    <link rel="stylesheet" href="/public/style/default.css" />
    <link rel="stylesheet" href="/public/style/public.css" />

    <style>
      .better-scroll-layout {
        overflow: hidden;
        position: relative;
        width: 100%;
        height: 500px;
        border: 1px solid #ccc;
      }
      .better-scroll-wrapper {
        overflow: hidden;
        position: relative;
        width: 100%;
        height: 100%;
      }
      .better-scroll-content {
        overflow: hidden;
        position: relative;
        width: 100%;
      }
      .better-scroll-content li {
        position: relative;
        width: 100%;
      }
    </style>
  </head>
  <body>
    <section class="better-scroll-layout">
      <div class="com-frame better-scroll-wrapper">
        <ul class="better-scroll-content">
          <li style="height: 100px; background-color: #f00"></li>
          <li style="height: 300px; background-color: #f06292"></li>
          <li style="height: 300px; background-color: #8e24aa"></li>
          <li style="height: 300px; background-color: #5e35b1"></li>
          <li style="height: 400px; background-color: #6200ea"></li>
          <li style="height: 500px; background-color: #303f9f"></li>
        </ul>
      </div>
    </section>

    <script src="/public/source/better-scroll/better-scroll.min.js"></script>
    <script type="text/javascript">
      const bs = BetterScroll.createBScroll(".better-scroll-wrapper", {
        mouseWheel: true,
      });
    </script>
  </body>
</html>

代码示例一:左右滚动

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <meta
      name="viewport"
      content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"
    />
    <meta name="mobile-web-app-capable" content="yes" />

    <title>Better Scroll</title>

    <link rel="icon" href="/public/favicon.ico" />
    <link rel="stylesheet" href="/public/style/default.css" />
    <link rel="stylesheet" href="/public/style/public.css" />

    <style>
      .better-scroll-layout {
        overflow: hidden;
        position: relative;
        width: 100%;
        height: 500px;
        border: 1px solid #ccc;
      }
      .better-scroll-wrapper {
        overflow: hidden;
        position: relative;
        width: 100%;
        height: 100%;
        white-space: nowrap;
      }
      .better-scroll-content {
        overflow: hidden;
        position: relative;
        display: inline-block;
        height: 100%;
      }
      .better-scroll-content li {
        position: relative;
        display: inline-block;
        height: 100%;
      }
    </style>
  </head>
  <body>
    <section class="better-scroll-layout">
      <div class="better-scroll-wrapper">
        <ul class="better-scroll-content">
          <li style="width: 100px; background-color: #f00"></li>
          <li style="width: 300px; background-color: #f06292"></li>
          <li style="width: 300px; background-color: #8e24aa"></li>
          <li style="width: 300px; background-color: #5e35b1"></li>
          <li style="width: 400px; background-color: #6200ea"></li>
          <li style="width: 500px; background-color: #303f9f"></li>
        </ul>
      </div>
    </section>

    <script src="/public/source/better-scroll/better-scroll.min.js"></script>
    <script type="text/javascript">
      const bs = BetterScroll.createBScroll(".better-scroll-wrapper", {
        scrollX: true,
        mouseWheel: true,
      });
    </script>
  </body>
</html>

实现轮播图


Mock数据

Last Updated:
Contributors: 709992523, Eshen