本仓库的目标是做一套可用于生产环境的 JS + CSS 框架,最终在业务项目中只需要引入:
xjs.js(单文件 JS)xjs.css(单文件 CSS)但在本仓库内,为了保持可维护性,开发源码仍然分散在多个文件中(例如 animal.js、layer.js),再通过构建脚本合并为单文件产物。
本文档用于统一后续完善/开发的目录约定、命名规范、编码习惯、测试方式、发布流程。请把它当成项目的“团队约定”。
当前结构(关键文件):
animal.js:动画/选择器核心(Selection / animate / svg / timeline / scroll / inView 等能力)layer.js:弹出层组件(UI + 交互逻辑)xjs.css:库运行时需要的所有 UI 样式(例如 Layer 的 .layer-*)xjs.js:
animal.js + layer.js)dist/xjs.js:生产合并产物(由构建命令生成)doc/index.html:统一测试/文档入口(支持点击导航直接进入示例页面)main.go:构建与本地静态服务脚本animal.js / layer.js / xjs.css / doc/**dist/xjs.js(以及任何由构建生成的合并文件)dist/xjs.js + xjs.css 为准仓库自带 Go 静态服务(默认端口 8080):
go run main.go serve
然后在浏览器打开:
http://localhost:8080/doc/index.html说明:
doc/index.html会作为“测试总控台”,左侧导航/中间列表/右侧 iframe 组合用于快速打开各类测试页面。
将 animal.js + layer.js 合并输出到 dist/xjs.js:
go run main.go build
或指定输出路径:
go run main.go build path/to/xjs.js
对外承诺以下全局变量:
window.$:主入口(jQuery 风格选择器 + 链式能力)window.xjs:兼容别名(与 $ 等价)window.animal:兼容别名(与 $ 等价)window.Layer:Layer 构造/工厂入口$(selector) 返回的 Selection 链式对象进入$.config(xjs/animal 为别名)Promise(例如 animate().then(...))Selection 以支持链式调用(例如 .layer(...).addClass(... ) 未来扩展)animal.js、layer.js,新增模块保持一致)animal.js:核心选择器与动画体系(不直接引入 UI 样式)layer.js:UI 组件(允许依赖 xjs.css)camelCasePascalCaseUPPER_SNAKE_CASE_fire、_onKeydown)$(selector) 返回 Selection(继承 Array 的可链式集合)animate / draw / inViewAnimate / layer / unlayerparams.options(现有实现已倾向此策略)xjs.css)xjs.css<style>(可接受“确保已引入 CSS”的兜底逻辑,但不把完整样式写入 JS)目前 Layer 使用 .layer-*,后续新增组件建议遵循:
x-<component>-* 或沿用当前 layer-*(但需保持一致)xjs-,则逐步迁移)目标是:业务 CSS 不会因为类名冲突而被库“意外影响”,也不会轻易覆盖库样式。
新增 UI 组件时,尽量通过 CSS 变量暴露可定制项:
--xjs-color-primary--xjs-radius-md--xjs-shadow-lg--layer-...(若继续沿用 layer 命名空间)并保证:
doc/)doc/index.html 进入doc/layer/、doc/svg/、doc/tween_*)doc/index.html 的导航树中挂入口,保证“可点击直达”目标:我只说“改哪个功能的演示”,你能精准找到对应页面、路由和引用的库。
/doc/#<token> → 映射到 doc/<path>.html
/doc/#layer_test__dom__steps → doc/layer/test_dom_steps.html...、伪代码或省略写法(如隐藏 DOM 块也要完整展示)doc/demo.css(示例通用样式)、xjs.css(组件运行时样式)doc/highlight_css.js(代码高亮)animal.js + layer.js(调试时直接加载源码,避免缓存覆盖)落地示例(当前对照页):
/doc/#layer_test__dom__stepsdoc/layer/test_dom_steps.htmlanimal.js)典型落点:
Selection.prototype.xxx = function (...) { ... }Selection 类体内增加方法(更推荐,保持结构统一)$.xxx = ...(xjs/animal 为别名)推荐方式:
component_xxx.js(或未来统一 components/xxx.js)xjs.css 增加 xxx-*(或 xjs-xxx-*)样式main.go build() 的拼接顺序)当前
main.go固定合并animal.js + layer.js,当模块增长时建议升级为“配置式列表”。
每次准备对外发布(或业务项目更新版本)前建议走一遍:
doc/index.html,对本次变更相关页面逐个验证go run main.go builddist/xjs.js 更新(不要手改)xjs/animal/Layer 是否都存在$ 是否仍然是“显式开关才导出”xjs.css 的类名是否避免与业务冲突当模块越来越多时,建议逐步引入以下工程化能力(仍保持“最终只发两个文件”的目标):
src/animal/、src/layer/、src/core/main.go 从“硬编码拼接两个文件”升级为“按清单拼接多个文件”dist/xjs.js 注入版本号、构建时间、变更摘要(便于定位线上问题)如果本文档与源码现状出现不一致:
Layer 现在支持把“页面里已有的 DOM(可默认隐藏)”挂载到弹窗内容区域展示:
dom: '#selector' | Element | <template>content: '#selector' | Element(历史用法仍可用)hidden / style.display)domMode:'clone' 或 content:{ dom:'#el', clone:true } 克隆节点展示(不移动原节点)示例:
// 页面中一个默认隐藏的 DOM
// <div id="my_form" style="display:none">...</div>
$.layer({
title: 'Edit profile',
dom: '#my_form',
showCancelButton: true,
confirmButtonText: 'Save'
});
Layer 支持“同一弹窗内”的步骤流:点击确认按钮不关闭,而是平滑切换到下一步;最后一步确认后 resolve。
演示:/#layer_test__dom__steps
推荐写法(链式):
$.layer({
icon: 'info',
closeOnClickOutside: false,
closeOnEsc: false
})
.step({
title: 'Step 1',
dom: '#step1',
showCancelButton: true,
cancelButtonText: 'Cancel',
preConfirm(popup) {
// return false 阻止进入下一步(用于校验)
const v = popup.querySelector('input[name="name"]').value.trim();
if (!v) return false;
return { name: v };
}
})
.step({
title: 'Step 2',
dom: '#step2',
preConfirm(popup) {
return { plan: popup.querySelector('select[name="plan"]').value };
}
})
.run()
.then((res) => {
if (res.isConfirmed) {
// res.value 是每一步 preConfirm 的返回值数组
console.log(res.value);
}
});
也支持便捷写法:
Layer.flow([
{ title: 'Step 1', dom: '#step1' },
{ title: 'Step 2', dom: '#step2' }
], { icon: 'info' });