src/common.js 是用户上传的 sx 函数库(xueluo.cn,2019-11-05 创建,2023-07-21 更新),全局名是 window.sx 与 window.SX(同一个函数)。
它不是 jQuery。 它提供的是一套自定义的 DOM 操作 API,思路和 jQuery 类似但命名与签名都不同。飞立(plui)的所有交互组件都基于它的真实 API 编写,不引入 jQuery。
src/common.js,47 652 字节03d870e366b6c6d56525aa50fbc5838e0368e8dd49fc66a943fdfb0db0eaf474// sx(选择器) 返回一个「集合对象」:有 length,有下标,方法是原型上的
sx('p'); // 所有 p
sx('#id'); // 指定 id
sx('.cls', container); // 在 container 内查找
sx(document.getElementById('x')); // 直接包 DOM 节点
sx(document.querySelectorAll('p')); // 包 NodeList
sx(function () { /* DOM 就绪后执行 */ });
// 静态方法也可以直接用
sx.each(nodeList, fn);
sx.ajax({ url: '...' });
集合对象上可用的实例方法(sx.init.prototype):
| 方法 | 说明 | 与 jQuery 的差别 |
|---|---|---|
each(fn) | 遍历 | 回调是 (i, 元素, 集合, 总数),与 jQuery 一致 |
i(n) | 取第 n 个元素 | jQuery 用 eq() |
find(name) | 查找后代 | jQuery 同名 |
children(name) / childrens() | 直接子元素 / 全部后代 | childrens() 是 jQuery 没有的 |
parent() / parents() | 父元素 / 所有祖先 | jQuery 同名 |
siblings() / prev() / next() | 兄弟节点 | jQuery 同名 |
index() | 在父元素中的序号 | jQuery 同名 |
isChildren(el) | 是否为直接子元素 | jQuery 无 |
addCss(name) | 加类名 | jQuery 是 addClass() |
delCss(name) | 删类名 | jQuery 是 removeClass() |
hasCss(name) | 判断类名 | 语义是「列出的类名必须全部存在」,不是 jQuery 的 hasClass() |
toggleCss(a, b, fnA, fnB) | 两个类名互换 | jQuery 无直接对应 |
attr(name[, value]) | 读 / 写属性 | 读不到时返回 false,不是 undefined |
delAttr(name) | 删属性 | jQuery 同名 |
style(name[, value]) / style(obj) | 读写行内样式 | jQuery 是 css() |
getCss(attr) | 读计算样式 | jQuery 是 css() |
html([v]) | 读写 innerHTML | jQuery 同名 |
val([v]) | 读 / 写表单值 | 只作用于第一个元素 |
form() | 收集表单值成对象 | jQuery 无 |
append / prepend / before / after | 插入节点 | jQuery 同名 |
clone() | 深拷贝 | jQuery 同名 |
del() | 移除节点 | jQuery 是 remove() |
on(type, fn[, bool]) | 绑定事件 | 回调是 (i, 元素, 事件);没有 off() |
click(fn) | 绑定点击 | 回调是 (事件, i),与 on 的参数顺序不一致 |
show / hide / toggle | 显隐 | jQuery 同名 |
fadeIn / fadeOut / fadeToggle | 淡入淡出 | jQuery 同名 |
slideDown / slideUp / slideToggle | 滑动 | jQuery 同名 |
offset() | 相对位置 | jQuery 同名 |
静态方法(挂在 sx 上):
| 分类 | 方法 |
|---|---|
| 基础 | each、isFunction、isWindow、isArrayLike、toDom、c、sp(阻止冒泡)、pd(阻止默认)、isMobile、isJson |
| 取值 | getUrl、getCss、getDisplay、hasStyle、html、val、attr、offset、index、data、storage、localData、time、obj2str、str2obj |
| 设置 | style、attr、addCss、delCss、hasCss、toggleCss、html、val、setDisplay、opacity、loadJs |
| DOM | append、prepend、before、after、find、children、childrens、siblings、prev、next、parent、parents、clone、del、dom2arr、arr2dom、form |
| 事件 | on、click、keydown、scroll、scrollAni、page |
| 动画 | show、hide、toggle、fadeIn、fadeOut、fadeToggle、slideDown、slideUp、slideToggle |
| 网络 | ajax、upload、pjax |
| 界面 | pop(轻提示)、alert(模态)、prompt、confirm |
| 其他 | drag、ready、start、CONF、href、jump、import、delArticle、reply、cancelReply、delStorage、delData、delLocalData |
| jQuery 写法 | sx 等价写法 | 注意事项 |
|---|---|---|
$(sel) | sx(sel) | 一致 |
$(el) / $(nodeList) | sx(el) | 一致 |
$(fn) | sx(fn) | 都会在 DOM 就绪后执行 |
$(sel).each(fn) | sx(sel).each(fn) | 一致 |
$(sel).on('click', fn) | sx(sel).on('click', fn) | 回调参数顺序不同:sx 是 (i, el, e),jQuery 是 (e, el) |
$(sel).click(fn) | sx(sel).click(fn) | sx 的 click 回调是 (e, i),和它的 on 不一致 |
$(sel).addClass('x') | sx(sel).addCss('x') | 名字不同 |
$(sel).removeClass('x') | sx(sel).delCss('x') | 名字不同 |
$(sel).hasClass('x') | sx(sel).hasCss('x') | 语义不同:sx 要求全部类名同时存在 |
$(sel).attr('x') | sx(sel).attr('x') | 读不到时 sx 返回 false |
$(sel).css('x', v) | sx(sel).style('x', v) | 名字不同;读计算样式用 getCss() |
$(sel).html() | sx(sel).html() | 一致 |
$(sel).val() | sx(sel).val() | 一致,只取第一个元素 |
$(sel).find(x) | sx(sel).find(x) | 一致 |
$(sel).eq(2) | sx(sel).i(2) | 名字不同 |
$(html) | sx.toDom(html) / sx.c('div') | sx 不能用字符串直接造节点 |
$.ajax({...}) | sx.ajax({...}) | 返回 Promise,无全局 $ 别名 |
$(sel).closest(x) | 无 | 用原生 el.closest(x) |
$(sel).off() | 无 | 无法解绑事件,sx 只能靠 el.onclick = null 覆盖点击绑定 |
off() / 事件解绑:on() 内部是 addEventListener,没有任何移除入口。所以 plui 的事件全部只在初始化时绑定一次,不做解绑;重复初始化靠幂等处理。closest():只有 parent() 与 parents(),plui 用原生 Element.closest()。hasCss() 是「全部存在」语义,判断「有没有某一个类」用原生 classList.contains() 更准确。prop()、data() 的 DOM 语义:sx.data() 实际是 sessionStorage 包装(sx.storage(sessionStorage, ...)),跟 jQuery 的 data() 完全不是一回事。filter() / map() / not() / is() / eq()(i() 部分等价)。wrap() / unwrap() / detach()。.animate() 通用动画系统:只有 fade / slide 两组预设。$.trim / $.isNumeric / $.parseJSON 等小工具。sx.toDom(html) 会先塞进临时 div 再取 childNodes。$ 别名:只有 sx 与 SX。| 场景 | 用什么 | 原因 |
|---|---|---|
| 选择元素、限定作用域 | sx(sel) / sx(sel, root) | 原生 querySelectorAll 封装 |
| 遍历集合 | sx.each(el, fn) | 回调签名与 jQuery 一致 |
| 绑定事件(全局委托) | sx.on(document, 'click', fn) | 内部是 addEventListener,冒泡正常 |
| 加 / 删类名 | sx.addCss / sx.delCss | 框架统一走 sx |
| 单类判断与取反 | 原生 classList.contains | sx.hasCss 语义是「全部存在」,不适合单类判断 |
| 找最近的祖先 | 原生 el.closest(sel) | sx 没有 closest |
| 读 data 属性 | 原生 getAttribute | sx 的 attr 读不到时返回 false,需要区分「没有」与「值为 false」 |
| 创建元素 | sx.c('div') | sx 的节点工厂 |
| 键盘监听 | 原生 addEventListener('keydown') | sx.keydown() 有缺陷:它内部用 sx.on 的回调当事件对象,实际拿到的是索引,导致 e.keyCode 恒为 undefined,不能用于 Esc 关闭 |
| 焦点管理 | 原生 focus() | sx 没有对应方法 |
common.js 在 DOM 就绪后会自动执行 sx.start() 与一段配置拉取逻辑,这些行为与页面无关但会真实发生:
| 自动行为 | 说明 | 对 plui 的影响 |
|---|---|---|
sx('.back').click(...) | 给 .back 元素绑后退 | plui 不使用 .back 类名 |
sx('.tab') 自动选项卡 | 查找 .tab-menu a 与 .tab-content,用 active 类切换 | plui 的标签页叫 .plui-nav-tabs,类名不同,不会被它接管 |
sx('.menu a') 改写 className | 直接 el.className = 'active' 或 '',会覆盖掉 a 元素原有的 class | plui 不使用 .menu 类名 |
.header .icon-menu 切换 .sidebar | 给 .sidebar 加删 sidebar-open | plui 不使用这些类名 |
POST 当前页 getConf=1 | 向当前页面地址发一个 POST,取站点配置 | 在 ui.phli.cn 上会拿到 HTML 页面内容(不是 JSON),不会报错,但 sx.CONF 里存的是 HTML 字符串;plui 不使用 sx.CONF |
sx('#pjax-content') 局部刷新 | 若页面存在该 id 会接管 | plui 不使用该 id |
因此 plui 全部使用 plui- 前缀的类名,既避免与 common.js 的自动逻辑冲突,也避免与页面里其他第三方样式撞名。
文件头保留了原库的版权声明(该版权完全归 xueluo.cn 官方所有,可转载使用和学习,但请务必保留版权信息)。plui 只做只读引用,未改动其内容。
本页由 build/build-docs.mjs 从同名 Markdown 生成,请修改 .md 后重新生成,不要手工编辑本文件。