mirror of
https://gitee.com/layui/layui.git
synced 2025-06-28 13:34:27 +08:00
Compare commits
32 Commits
v2.11.0-rc
...
main
Author | SHA1 | Date | |
---|---|---|---|
![]() |
77adc3d196 | ||
![]() |
5a2baf9375 | ||
![]() |
ece68e117e | ||
![]() |
c7bfc564ea | ||
![]() |
e67266260f | ||
![]() |
e3f683cdc0 | ||
![]() |
1eb01c6706 | ||
![]() |
ac8d5ccc30 | ||
![]() |
1ea5f34600 | ||
![]() |
fe7df50ce7 | ||
![]() |
1b9557cdd8 | ||
![]() |
7138198645 | ||
![]() |
a7af177223 | ||
![]() |
36a5beaa46 | ||
![]() |
c1d821d38d | ||
![]() |
008e6cb7d0 | ||
![]() |
fe5e4e1264 | ||
![]() |
4fd021e48b | ||
![]() |
5e7cbdeb30 | ||
![]() |
b3bfc92374 | ||
![]() |
985803ec09 | ||
![]() |
6d524c0674 | ||
![]() |
23a62619d9 | ||
![]() |
a7267a4b5d | ||
![]() |
3617209874 | ||
![]() |
1f2fc91431 | ||
![]() |
6fc761e63b | ||
![]() |
a1e084c6b4 | ||
![]() |
3842a98360 | ||
![]() |
a060a484e4 | ||
![]() |
d2e01d0491 | ||
![]() |
78438c3429 |
2
dist/css/layui.css
vendored
2
dist/css/layui.css
vendored
File diff suppressed because one or more lines are too long
2
dist/css/layui.css.map
vendored
2
dist/css/layui.css.map
vendored
File diff suppressed because one or more lines are too long
2
dist/layui.js
vendored
2
dist/layui.js
vendored
File diff suppressed because one or more lines are too long
2
dist/layui.js.map
vendored
2
dist/layui.js.map
vendored
File diff suppressed because one or more lines are too long
@ -299,5 +299,5 @@ Class.prototype.xxx = function() {
|
||||
|
||||
## 💖 心语
|
||||
|
||||
Layui 由于早前欠缺统筹性思维,很多组件自成一体,使得无法对组件进行很好的统一管理。随着版本的迭代,我们也一直在努力尝试改善这一问题,但很多时候,为了向下兼容而不得不保留许多旧有的特性。`component` 模块的初衷正是为了确保组件的一致性,如核心逻辑和 API 设计等,其目的也是为了让 2.x 系列版本尽可能地减少些遗憾,让 Layui 在既定的范式中保持前行。
|
||||
一直以来,Layui 的很多组件自成一体,使得无法对组件进行较好的统一管理。尽管我们也曾努力尝试改善这个问题,但很多时候为了向下兼容而又不得不保留许多旧有的特性,随着组件的增加,该问题也显得越加明显。而 component 模块的出现,将在一定程度上填补这一缺憾,它的初衷正是为了确保 Layui 组件的一致性,如核心逻辑和 API 设计等,主要意义在于:**给 Layui 2 系列版本提供一个构建通用组件的方式**,增强其「生命力」。
|
||||
|
||||
|
@ -33,7 +33,7 @@
|
||||
<textarea id="ID-tpl-data">
|
||||
{
|
||||
"title": "Layui 常用组件",
|
||||
"desc": "<a style=\"color:blue;\">一段带 HTML 内容的描述</a>",
|
||||
"desc": "<a style=\"color:blue;\">一段带 HTML 的内容</a>",
|
||||
"list": [
|
||||
{
|
||||
"title": "弹层",
|
||||
|
@ -57,8 +57,8 @@ toc: true
|
||||
<div class="layui-collapse">
|
||||
<div class="layui-colla-item">
|
||||
<div class="layui-colla-title">Collapse Title 1</div>
|
||||
<div class="layui-colla-content">
|
||||
<p>Content 1</p>
|
||||
<div class="layui-colla-content layui-show">
|
||||
<p>Content 1 (添加 layui-show 类设置初始展开)</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-colla-item">
|
||||
|
@ -38,6 +38,16 @@
|
||||
</textarea>
|
||||
</pre>
|
||||
|
||||
<h3 id="demo-shuffle" lay-toc="{level: 2}">打乱标签顺序</h3>
|
||||
|
||||
<pre class="layui-code" lay-options="{preview: true, layout: ['preview', 'code'], codeStyle: 'max-height: 520px;', tools: ['full'], done: function(obj){
|
||||
obj.render();
|
||||
}}">
|
||||
<textarea>
|
||||
{{- d.include("/tabs/examples/shuffle.md") }}
|
||||
</textarea>
|
||||
</pre>
|
||||
|
||||
<h3 id="demo-hash" lay-toc="{level: 2, title: 'HASH 匹配'}">通过 HASH 匹配选中标签</h3>
|
||||
|
||||
切换 tabs 标签项后,地址栏同步 `hash` 值,当页面刷新时,tabs 仍保持对应的切换状态。
|
||||
|
@ -89,13 +89,12 @@ layui.use(function() {
|
||||
title: 'New Tab '+ n, // 此处加 n 仅为演示区分,实际应用不需要
|
||||
content: 'New Tab Content '+ n,
|
||||
id: 'new-'+ n,
|
||||
aaa: 'attr-'+ n, // 自定义属性,其中 aaa 可任意命名
|
||||
done: function(params) {
|
||||
console.log(params); // 查看返回的参数
|
||||
done: function(data) {
|
||||
console.log(data); // 查看返回的参数
|
||||
|
||||
// 给新标签头添加上下文菜单
|
||||
dropdown.render($.extend({}, dropdownInst.config, {
|
||||
elem: params.thisHeaderItem // 当前标签头元素
|
||||
elem: data.headerItem // 新标签头元素 --- headerItem 为 2.11.2 新增
|
||||
}));
|
||||
}
|
||||
}, opts);
|
||||
|
22
docs/tabs/examples/shuffle.md
Normal file
22
docs/tabs/examples/shuffle.md
Normal file
@ -0,0 +1,22 @@
|
||||
<div class="layui-tabs" lay-options="{closable: true}">
|
||||
<ul class="layui-tabs-header">
|
||||
<li lay-id="fff">Tab6</li>
|
||||
<li lay-id="eee">Tab5</li>
|
||||
<li lay-id="ccc">Tab3</li>
|
||||
<li lay-id="bbb">Tab2</li>
|
||||
<li lay-id="aaa">Tab1</li>
|
||||
<li lay-id="ddd">Tab4</li>
|
||||
</ul>
|
||||
<div class="layui-tabs-body">
|
||||
<div class="layui-tabs-item" lay-id="aaa">Tab Content-1</div>
|
||||
<div class="layui-tabs-item" lay-id="bbb">Tab Content-2</div>
|
||||
<div class="layui-tabs-item" lay-id="ccc">Tab Content-3</div>
|
||||
<div class="layui-tabs-item" lay-id="ddd">Tab Content-4</div>
|
||||
<div class="layui-tabs-item" lay-id="eee">Tab Content-5</div>
|
||||
<div class="layui-tabs-item" lay-id="fff">Tab Content-6</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
🔔 提示:即 tabs 能通过 `lay-id` 匹配对应的标签头和标签内容。
|
||||
|
||||
<!-- import layui -->
|
@ -122,6 +122,12 @@ tabs.render({
|
||||
tabs.add('test', {
|
||||
title: 'New Tab 1',
|
||||
content: 'New Tab Content 1',
|
||||
done: function(data) {
|
||||
console.log(data); // 标签相关数据
|
||||
|
||||
// 为新标签头添加任意属性
|
||||
data.headerItem.attr('lay-tips', '111');
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
@ -130,7 +136,7 @@ tabs.add('test', {
|
||||
`tabs.close(id, index, force)`
|
||||
|
||||
- 参数 `id` : 组件的实例 ID
|
||||
- 参数 `index` : 标签索引或标签的 `lay-id` 属性值
|
||||
- 参数 `index` : 若传入 number 类型,则为标签索引;若传入 string 类型,则为标签的 `lay-id` 属性值
|
||||
- 参数 `force` : 是否强制关闭。若设置 `true` 将忽略 `beforeClose` 事件行为。默认 `false`
|
||||
|
||||
该方法用于关闭指定的标签项。
|
||||
@ -150,19 +156,23 @@ tabs.close('test', 'abc'); // 关闭 lay-id="abc" 的标签
|
||||
|
||||
| mode | 描述 |
|
||||
| --- | --- |
|
||||
| other | 关闭除当前标签外的所有标签 |
|
||||
| right | 关闭当前标签及右侧标签 |
|
||||
| other | 关闭除当前标签外的其他标签 |
|
||||
| right | 关闭当前标签的右侧所有标签 |
|
||||
| all | 关闭所有标签 |
|
||||
|
||||
- 参数 `index` : 活动标签的索引或 `lay-id` 属性值,默认取当前选中标签的索引。一般用于标签右键事件。
|
||||
|
||||
该方法用于批量关闭标签。
|
||||
该方法用于批量关闭标签,若标签项已设置不允许关闭(`lay-closable="false"`),则操作将被忽略。
|
||||
|
||||
```js
|
||||
tabs.closeMult(id, 'other'); // 关闭除当前标签外的所有标签
|
||||
tabs.closeMult(id, 'other', 3); // 关闭除索引为 3 的标签外的所有标签
|
||||
tabs.closeMult(id, 'right'); // 关闭当前标签及右侧标签
|
||||
tabs.closeMult(id, 'other'); // 关闭除当前活动标签外的其他标签
|
||||
tabs.closeMult(id, 'other', 3); // 关闭除索引为 3 的标签外的其他标签
|
||||
tabs.closeMult(id, 'other', 'ccc'); // 关闭除 lay-id="ccc" 的标签外的其他标签
|
||||
|
||||
tabs.closeMult(id, 'right'); // 关闭当前活动标签的右侧所有标签
|
||||
tabs.closeMult(id, 'right', 3); // 关闭索引为 3 的标签的右侧所有标签
|
||||
tabs.closeMult(id, 'right', 'ccc'); // 关闭 lay-id="ccc" 的标签的右侧所有标签
|
||||
|
||||
tabs.closeMult(id, 'all'); // 关闭所有标签
|
||||
```
|
||||
|
||||
@ -202,10 +212,10 @@ console.log(data);
|
||||
{
|
||||
options, // 标签配置信息
|
||||
container, // 标签容器的相关元素
|
||||
thisHeaderItem, // 当前标签头部项
|
||||
thisBodyItem, // 当前标签内容项
|
||||
index, // 当前标签索引
|
||||
length, // 当前标签数
|
||||
thisHeaderItem, // 当前活动标签头部项
|
||||
thisBodyItem, // 当前活动标签内容项
|
||||
index, // 当前活动标签索引
|
||||
length, // 标签数量
|
||||
}
|
||||
```
|
||||
|
||||
@ -214,12 +224,13 @@ console.log(data);
|
||||
`tabs.getHeaderItem(id, index)`
|
||||
|
||||
- 参数 `id` : 组件的实例 ID
|
||||
- 参数 `index` : 标签索引或标签的 `lay-id` 属性值
|
||||
- 参数 `index` : 若传入 number 类型,则为标签索引;若传入 string 类型,则为标签的 `lay-id` 属性值
|
||||
|
||||
该方法用于获取标签头部项元素。
|
||||
|
||||
```js
|
||||
var headerItem = tabs.getHeaderItem('test', 3); // 获取索引为 3 的标签头部项元素
|
||||
var headerItem = tabs.getHeaderItem('test', 'abc'); // 获取 lay-id="abc" 的标签头部项元素
|
||||
```
|
||||
|
||||
<h3 id="getBodyItem" class="ws-anchor ws-bold">获取标签内容项</h3>
|
||||
@ -227,12 +238,13 @@ var headerItem = tabs.getHeaderItem('test', 3); // 获取索引为 3 的标签
|
||||
`tabs.getBodyItem(id, index)`
|
||||
|
||||
- 参数 `id` : 组件的实例 ID
|
||||
- 参数 `index` : 标签索引或标签的 `lay-id` 属性值
|
||||
- 参数 `index` : 若传入 number 类型,则为标签索引;若传入 string 类型,则为标签的 `lay-id` 属性值 <sup>2.11.2+</sup>
|
||||
|
||||
该方法用于获取标签内容项元素。
|
||||
|
||||
```js
|
||||
var bodyItem = tabs.getBodyItem('test', 3); // 获取索引为 3 的标签内容项元素
|
||||
var bodyItem = tabs.getBodyItem('test', 'abc'); // 获取 lay-id="abc" 的标签内容项元素
|
||||
```
|
||||
|
||||
<h3 id="refresh" class="ws-anchor ws-bold">刷新标签视图</h3>
|
||||
|
@ -274,7 +274,8 @@ treeTable.addNodes('test', {
|
||||
| index | 节点对应的行下标,一般可通过 `<tr>` 元素的 `data-index` 属性获得 | number | - |
|
||||
| expandFlag | 设置展开或关闭状态,若为 `true` 则表示展开;`false` 则为关闭;`null` 则表示切换 | boolean/null | - |
|
||||
| inherit | 子节点是否继承父节点的展开或关闭状态,`expandFlag` 属性必须为 `boolean` 型时才有效。 | boolean | `false` |
|
||||
| callbackFlag | 是否触发事件(`beforeExpand,onExpand`) | boolean | `false` |
|
||||
| callbackFlag | 是否触发 tree.callback 事件(`beforeExpand,onExpand`) | boolean | `false` |
|
||||
| done <sup>2.11.3+</sup>| 节点操作完成后的回调函数 | (tableId, trData, trExpand) => void | - |
|
||||
|
||||
若操作的节点不是一个父节点,则返回 `null`,否则返回操作之后的折叠状态。
|
||||
|
||||
|
104
docs/versions.md
104
docs/versions.md
@ -11,6 +11,110 @@ toc: true
|
||||
|
||||
<h2 id="2.10+" lay-toc="{title: '2.10+'}"></h2>
|
||||
|
||||
<h2 id="v2.11.4" lay-pid="2.10+" class="ws-anchor">
|
||||
v2.11.4
|
||||
<span class="layui-badge-rim">2025-06-23</span>
|
||||
<span class="layui-badge-rim" style="color: #16b777;">稳定版</span>
|
||||
</h2>
|
||||
|
||||
- 重构 collapse 展开收缩动画的核心逻辑 #2734
|
||||
- 新增 collapse 列表项添加 `layui-show` 类设置默认展开的支持,且兼容旧版 #2734
|
||||
- 修复 collapse 列表项的内容元素添加 `layui-show` 类时的收缩异常问题 #2734
|
||||
|
||||
### 下载: [layui-v2.11.4.zip](https://gitee.com/layui/layui/attach_files/2241193/download)
|
||||
|
||||
---
|
||||
|
||||
<h2 id="v2.11.3" lay-pid="2.10+" class="ws-anchor">
|
||||
v2.11.3
|
||||
<span class="layui-badge-rim">2025-06-18</span>
|
||||
</h2>
|
||||
|
||||
- #### tabs
|
||||
- 优化 `close` 方法在标签顺序打乱时传入 `lay-id` 的支持 #2690 @sentsim
|
||||
- 优化 `closeMult` 方法的 `index` 参数值为 `lay-id` 时的无效问题 #2690 @sentsim
|
||||
- 优化 `getHeaderItem` 等方法的 `index` 参数的类型检测 #2690 @sentsim
|
||||
- #### treeTable
|
||||
- 新增 `expandNode` 方法的 `done` 回调 #2721 @Sight-wcg
|
||||
- #### collapse
|
||||
- 新增 折叠面板展开和收缩时的过渡动画 #2722 @sentsim
|
||||
|
||||
### 下载: [layui-v2.11.3.zip](https://gitee.com/layui/layui/attach_files/2233291/download)
|
||||
|
||||
---
|
||||
|
||||
<h2 id="v2.11.2" lay-pid="2.10+" class="ws-anchor">
|
||||
v2.11.2
|
||||
<span class="layui-badge-rim">2025-05-15</span>
|
||||
</h2>
|
||||
|
||||
- #### form-select
|
||||
- 修复 `<option>` 文本两端的 Unicode 空格(U+00A0)被去除的问题 #2676 @Sight-wcg
|
||||
- #### tabs
|
||||
- 优化 `header` 选项初始值的判断,允许数组为空 #2680 @sentsim
|
||||
- 优化 `tabs.getBodyItem()` 第二个参数,可接受索引或 `lay-id` 值 #2680
|
||||
- 优化 `tabs.add()` 的 `done` 回调,参数新增包含新标签项元素 #2680
|
||||
- 优化 `tabs.change()` 方法,标签项打乱顺序时仍可通过 `lay-id` 切换 #2680
|
||||
|
||||
### 下载: [layui-v2.11.2.zip](https://gitee.com/layui/layui/attach_files/2189123/download)
|
||||
|
||||
---
|
||||
|
||||
<h2 id="v2.11.1" lay-pid="2.10+" class="ws-anchor">
|
||||
v2.11.1
|
||||
<span class="layui-badge-rim">2025-05-06</span>
|
||||
</h2>
|
||||
|
||||
- 修复 select 组件的字符转义问题 #2661 @sentsim
|
||||
- 修复 checkbox/radio 在 WebKit/537.36 的异常 #2637 @Sight-wcg
|
||||
- 优化 carousel 切换时的动画性能 #2654 @SessionHu
|
||||
|
||||
### 下载: [layui-v2.11.1.zip](https://gitee.com/layui/layui/attach_files/2177069/download)
|
||||
|
||||
---
|
||||
|
||||
<h2 id="v2.11.0" lay-pid="2.10+" class="ws-anchor">
|
||||
v2.11.0
|
||||
<span class="layui-badge-rim">2025-04-21</span>
|
||||
</h2>
|
||||
|
||||
- #### 新特性
|
||||
- 新增 无缝扩展任意外部模块的支持,及优化大量核心 #2560 @sentsim
|
||||
- 重构 laytpl 模板引擎,增强对更多复杂模板结构的解析能力 #2577 @sentsim
|
||||
- #### Core
|
||||
- 新增 `layui.extend()` 无缝扩展任意外部模块的支持,即无需遵循 Layui 模块规范的第三方模块
|
||||
- 优化 `layui.use(), layui.link()` 核心逻辑
|
||||
- 优化 `layui.js` 整体代码风格
|
||||
- #### [laytpl](./laytpl/)
|
||||
- 新增 `cache` 选项,用于是否开启模板缓存
|
||||
- 新增 `condense` 选项,用于是否压缩模板空白符,如将多个连续的空白符压缩为单个空格
|
||||
- 新增 `tagStyle` 选项,用于设置标签风格。默认仍采用 `< 2.11` 版本风格
|
||||
- 新增 `laytpl.extendVars()` 方法,用于扩展模板内部变量
|
||||
- 新增 `compile` 实例方法,用于清除缓存后以便渲染时重新对模板进行编译
|
||||
- 新增 在模板中通过 `include()` 方法导入子模板的功能
|
||||
- 新增 新的标签风格:{{!`{{ 语句 }}` `{{= 转义输出 }}` `{{- 原文输出 }}` `{{# 注释 }}`!}}
|
||||
- 新增 template 报错时的上下文捕获,基于映射,可更精确定位到模板具体错误行 #2650 @sentsim
|
||||
- 提升 模板解析的整体性能及稳定性
|
||||
- 内置 对多种模块加载方式的支持,以同时适配 Node.js 和浏览器端的使用场景
|
||||
- #### rate
|
||||
- 重构 组件代码结构,由 component 模块构建,并继承其全部基础接口 #2626 @sentsim
|
||||
- #### component
|
||||
- 剔除 `isRenderOnEvent, isRenderWithoutElem` 实验型选项 #2625 @sentsim
|
||||
- #### tabs
|
||||
- 新增 `tabs.add()` 的 `active` 选项,用于是否将新增项设置为活动标签 #2607 @lanrenbulan
|
||||
- 修复 `box-sizing` 对主体区域中其他组件的样式影响 #2622 @sentsim
|
||||
- #### 其他
|
||||
- 新增 dropdown 可点击面板外部 iframe 区域关闭的功能 #2629 @Sight-wcg
|
||||
- 新增 select 可点击面板外部 iframe 区域关闭的功能 #2631 @Sight-wcg
|
||||
- 新增 layui.hash() 返回的成员 `pathname`, 与 layui.url() 一致 #2649 @sentsim
|
||||
- 优化 card 面板头部样式,去除高度限制 #2621 @sentsim
|
||||
- 优化 laypage 快速点击时文本被选中的问题 #2623 @sentsim
|
||||
- 优化 util 的 `escape` 和 `unescape` 在解析某些特殊字符串时的潜在问题 #2628 @sentsim
|
||||
|
||||
### 下载: [layui-v2.11.0.zip](https://gitee.com/layui/layui/attach_files/2158121/download)
|
||||
|
||||
---
|
||||
|
||||
<h2 id="v2.10.3" lay-pid="2.10+" class="ws-anchor">
|
||||
v2.10.3
|
||||
<span class="layui-badge-rim">2025-03-30</span>
|
||||
|
@ -17,6 +17,20 @@ toc: true
|
||||
|
||||
<h2 id="2.9.x" lay-toc="{title: '2.9.x'}"></h2>
|
||||
|
||||
<h2 id="v2.9.26" class="ws-anchor">
|
||||
v2.9.26
|
||||
<span class="layui-badge-rim">2025-04-15</span>
|
||||
<span class="layui-badge-rim" style="color: #16b777;">稳定版</span>
|
||||
</h2>
|
||||
|
||||
- 优化 util 的 `escape` 和 `unescape` 在解析某些特殊字符串时的潜在问题 #2628 @sentsim
|
||||
- 修复 layer.photos 在空图片容器动态添加图片时,无法获取 data 的问题 #2581 @Sight-wcg
|
||||
- 修复 body 初始 `line-height` 无效的问题 #2569 @sentsim
|
||||
|
||||
### 下载: [layui-v2.9.26.zip](https://gitee.com/layui/layui/attach_files/2149661/download)
|
||||
|
||||
---
|
||||
|
||||
<h2 id="v2.9.25" lay-pid="2.9.x" class="ws-anchor">
|
||||
v2.9.25
|
||||
<span class="layui-badge-rim">2025-03-13</span>
|
||||
|
89
examples/collapse.html
Normal file
89
examples/collapse.html
Normal file
@ -0,0 +1,89 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>折叠面板 - Layui</title>
|
||||
<link rel="stylesheet" href="../src/css/layui.css">
|
||||
</head>
|
||||
<body class="layui-padding-3">
|
||||
<h2>常规用法:</h2><br>
|
||||
<div class="layui-collapse" lay-filter="test">
|
||||
<div class="layui-colla-item">
|
||||
<h3 class="layui-colla-title">item 1</h3>
|
||||
<div class="layui-colla-content layui-show">
|
||||
旧版,通过给列表的内容添加 layui-show 类开启显示
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-colla-item">
|
||||
<h3 class="layui-colla-title">item2</h3>
|
||||
<div class="layui-colla-content">
|
||||
content 2
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-colla-item">
|
||||
<h3 class="layui-colla-title">item 3</h3>
|
||||
<div class="layui-colla-content">
|
||||
content 3
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<br>
|
||||
|
||||
<div class="layui-collapse" lay-filter="test">
|
||||
<div class="layui-colla-item layui-show">
|
||||
<h3 class="layui-colla-title">item 111</h3>
|
||||
<div class="layui-colla-content">
|
||||
新版 <sup>2.11.4+</sup>,通过给列表项直接添加 layui-show 类开启显示
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-colla-item">
|
||||
<h3 class="layui-colla-title">item 222</h3>
|
||||
<div class="layui-colla-content">
|
||||
content 2
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-colla-item">
|
||||
<h3 class="layui-colla-title">item 333</h3>
|
||||
<div class="layui-colla-content">
|
||||
content 3
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<br><h2>开启手风琴:</h2><br>
|
||||
<div class="layui-collapse" lay-accordion>
|
||||
<div class="layui-colla-item layui-show">
|
||||
<h3 class="layui-colla-title">item 1</h3>
|
||||
<div class="layui-colla-content">
|
||||
旧版,通过给列表的内容添加 layui-show 类开启显示
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-colla-item">
|
||||
<h3 class="layui-colla-title">item2</h3>
|
||||
<div class="layui-colla-content">
|
||||
content 2
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-colla-item">
|
||||
<h3 class="layui-colla-title">item 3</h3>
|
||||
<div class="layui-colla-content">
|
||||
content 3
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="../src/layui.js"></script>
|
||||
<script>
|
||||
layui.use('element', function(){
|
||||
var element = layui.element;
|
||||
|
||||
element.on('collapse(test)', function(data){
|
||||
console.log(data);
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -68,30 +68,7 @@ body{padding:20px;}
|
||||
|
||||
<span class="layui-badge-rim">Hot</span>
|
||||
|
||||
<hr>
|
||||
|
||||
<div class="layui-collapse" lay-filter="test" lay-accordion>
|
||||
<div class="layui-colla-item">
|
||||
<h2 class="layui-colla-title">杜甫</h2>
|
||||
<div class="layui-colla-content layui-show">
|
||||
<p>杜甫的思想核心是儒家的仁政思想,他有“致君尧舜上,再使风俗淳”的宏伟抱负。杜甫虽然在世时名声并不显赫,但后来声名远播,对中国文学和日本文学都产生了深远的影响。杜甫共有约1500首诗歌被保留了下来,大多集于《杜工部集》。</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-colla-item">
|
||||
<h2 class="layui-colla-title">李清照</h2>
|
||||
<div class="layui-colla-content">
|
||||
<p>李清照出生于书香门第,早期生活优裕,其父李格非藏书甚富,她小时候就在良好的家庭环境中打下文学基础。出嫁后与夫赵明诚共同致力于书画金石的搜集整理。金兵入据中原时,流寓南方,境遇孤苦。所作词,前期多写其悠闲生活,后期多悲叹身世,情调感伤。形式上善用白描手法,自辟途径,语言清丽。</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-colla-item">
|
||||
<h2 class="layui-colla-title">鲁迅</h2>
|
||||
<div class="layui-colla-content">
|
||||
<p>鲁迅一生在文学创作、文学批评、思想研究、文学史研究、翻译、美术理论引进、基础科学介绍和古籍校勘与研究等多个领域具有重大贡献。他对于五四运动以后的中国社会思想文化发展具有重大影响,蜚声世界文坛,尤其在韩国、日本思想文化领域有极其重要的地位和影响,被誉为“二十世纪东亚文化地图上占最大领土的作家”。</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<br><br>
|
||||
<hr><br>
|
||||
|
||||
<div class="layui-progress" lay-showPercent="true" lay-filter="demo-progress-1">
|
||||
<div class="layui-progress-bar" lay-percent="1/3"></div>
|
||||
@ -174,19 +151,11 @@ body{padding:20px;}
|
||||
灰色分割线
|
||||
<hr class="layui-border-gray">
|
||||
|
||||
|
||||
|
||||
|
||||
<script src="../src/layui.js"></script>
|
||||
<script>
|
||||
|
||||
layui.use(['element', 'form'], function(){
|
||||
var element = layui.element;
|
||||
|
||||
element.on('collapse(test)', function(data){
|
||||
console.log(data);
|
||||
layui.use('element', function() {
|
||||
var element = layui.element;
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -200,8 +200,8 @@
|
||||
<div class="layui-inline">
|
||||
<label class="layui-form-label">行内表单</label>
|
||||
<div class="layui-input-block">
|
||||
<select name="quiz" lay-verify="required" lay-vertype="tips" lay-filter="quiz111">
|
||||
<option value="">请"选择"问题</option>
|
||||
<select name="quiz" lay-verify="required" lay-vertype="tips" lay-filter="quiz">
|
||||
<option value="">请"选择"问题 😀</option>
|
||||
<option value="0">你工"作"的 第一个城市</option>
|
||||
<option value="1" disabled>你的工号</option>
|
||||
<option value="2">
|
||||
@ -213,7 +213,7 @@
|
||||
<div class="layui-inline">
|
||||
<label class="layui-form-label">select分组</label>
|
||||
<div class="layui-input-block">
|
||||
<select name="quiz" lay-filter="quiz">
|
||||
<select name="quiz111" lay-filter="quiz111">
|
||||
<option value="">请选择问题</option>
|
||||
<optgroup label="城市记忆">
|
||||
<option value="0">你工作的第一个城市</option>
|
||||
@ -245,7 +245,7 @@
|
||||
<div class="layui-inline">
|
||||
<label class="layui-form-label">搜索选择框</label>
|
||||
<div class="layui-input-block">
|
||||
<select name="interest-search" lay-filter="interest-search" lay-search="">
|
||||
<select name="interest-search" lay-filter="interest-search" lay-search="" lay-creatable>
|
||||
<option value="">请搜索</option>
|
||||
<option value="写作">写"作"</option>
|
||||
<option value="阅读" disabled>阅读</option>
|
||||
@ -451,12 +451,12 @@
|
||||
});
|
||||
|
||||
//事件
|
||||
form.on('select(quiz111)', function(data){
|
||||
console.log('select: ', this, data);
|
||||
form.on('select(quiz)', function(data){
|
||||
console.log('select.quiz: ', this, data);
|
||||
});
|
||||
|
||||
form.on('select(quiz)', function(data){
|
||||
console.log('select.quiz:', this, data);
|
||||
form.on('select(quiz111)', function(data){
|
||||
console.log('select.quiz111:', this, data);
|
||||
});
|
||||
|
||||
form.on('select(interest)', function(data){
|
||||
@ -531,7 +531,7 @@
|
||||
<div class="layui-inline" lay-ignore>
|
||||
<input type="checkbox" name="like[write]" title="写作">
|
||||
<input type="radio" name="sex" value="1" title="男">
|
||||
<select name="quiz">
|
||||
<select name="quiz111">
|
||||
<option value="">请选择</option>
|
||||
<option value="AAAAA">AAAAA</option>
|
||||
<option value="BBBBB">BBBBB</option>
|
||||
|
@ -90,6 +90,26 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h2>打乱标签顺序:</h2>
|
||||
<div class="layui-tabs" lay-options="{closable: true}">
|
||||
<ul class="layui-tabs-header">
|
||||
<li lay-id="fff">Tab6</li>
|
||||
<li lay-id="eee">Tab5</li>
|
||||
<li lay-id="ccc">Tab3</li>
|
||||
<li lay-id="bbb">Tab2</li>
|
||||
<li lay-id="aaa">Tab1</li>
|
||||
<li lay-id="ddd">Tab4</li>
|
||||
</ul>
|
||||
<div class="layui-tabs-body">
|
||||
<div class="layui-tabs-item" lay-id="aaa">Tab Content-1</div>
|
||||
<div class="layui-tabs-item" lay-id="bbb">Tab Content-2</div>
|
||||
<div class="layui-tabs-item" lay-id="ccc">Tab Content-3</div>
|
||||
<div class="layui-tabs-item" lay-id="ddd">Tab Content-4</div>
|
||||
<div class="layui-tabs-item" lay-id="eee">Tab Content-5</div>
|
||||
<div class="layui-tabs-item" lay-id="fff">Tab Content-6</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h2>标签 HASH 定位</h2>
|
||||
<div class="layui-tabs layui-hide-v" id="demoTabs-hash">
|
||||
<ul class="layui-tabs-header">
|
||||
@ -167,27 +187,40 @@
|
||||
<script src="../src/layui.js"></script>
|
||||
<script>
|
||||
layui.use(function() {
|
||||
var $ = layui.$;
|
||||
var tabs = layui.tabs
|
||||
var util = layui.util;
|
||||
var layer = layui.layer;
|
||||
var dropdown = layui.dropdown;
|
||||
|
||||
// 新增随机标签
|
||||
var addTabs = function(opts) {
|
||||
var n = Math.random()*1000 | 0; // 演示标记
|
||||
opts = $.extend({
|
||||
title: 'New Tab '+ n, // 此处加 n 仅为演示区分,实际应用不需要
|
||||
content: 'New Tab Content '+ n,
|
||||
id: 'new-'+ n,
|
||||
// active: false, // 是否设为活动标签
|
||||
done: function(data) {
|
||||
console.log(data); // 查看返回的参数
|
||||
|
||||
// 为新标签头添加任意属性 --- 2.11.2+
|
||||
data.headerItem.attr('lay-tips', 'tip-'+ n);
|
||||
|
||||
// 给新标签头添加上下文菜单
|
||||
dropdown.render($.extend({}, dropdownInst.config, {
|
||||
elem: data.headerItem // 新标签头元素
|
||||
}));
|
||||
}
|
||||
}, opts);
|
||||
// 添加标签到最后
|
||||
tabs.add('demoTabs1', opts);
|
||||
}
|
||||
|
||||
// 自定义事件
|
||||
util.on({
|
||||
add: function(){
|
||||
var n = Math.random()*1000 | 0; // 演示标记
|
||||
|
||||
//添加标签
|
||||
tabs.add('demoTabs1', {
|
||||
title: 'New Tab '+ n, // 此处加 n 仅为演示区分,实际应用不需要
|
||||
content: 'New Tab Content '+ n,
|
||||
id: 'new-'+ n,
|
||||
aaa: 'attr-'+ n, // 自定义属性,其中 aaa 可任意命名
|
||||
// mode: 'curr',
|
||||
done: function(params) {
|
||||
console.log(params);
|
||||
}
|
||||
});
|
||||
addTabs();
|
||||
}
|
||||
});
|
||||
|
||||
@ -226,30 +259,49 @@
|
||||
});
|
||||
|
||||
// 为标签头添加上下文菜单
|
||||
dropdown.render({
|
||||
var dropdownInst = dropdown.render({
|
||||
elem: '#demoTabs1 .layui-tabs-header>li',
|
||||
trigger: 'contextmenu',
|
||||
data: [{
|
||||
title: '关闭',
|
||||
type: 'this'
|
||||
}, {
|
||||
title: '关闭其他标签页',
|
||||
type: 'other'
|
||||
}, {
|
||||
title: '关闭右侧标签页',
|
||||
type: 'right'
|
||||
title: '在右侧新增标签页',
|
||||
action: 'add',
|
||||
mode: 'after'
|
||||
}, {
|
||||
type: '-'
|
||||
}, {
|
||||
title: '关闭',
|
||||
action: 'close',
|
||||
mode: 'this',
|
||||
}, {
|
||||
title: '关闭其他标签页',
|
||||
action: 'close',
|
||||
mode: 'other'
|
||||
}, {
|
||||
title: '关闭右侧标签页',
|
||||
action: 'close',
|
||||
mode: 'right'
|
||||
}, {
|
||||
title: '关闭所有标签页',
|
||||
type: 'all'
|
||||
action: 'close',
|
||||
mode: 'all'
|
||||
}],
|
||||
click: function(data, othis, event) {
|
||||
var index = this.elem.index();
|
||||
if (data.type === 'this') {
|
||||
tabs.close('demoTabs1', index); // 关闭当前标签
|
||||
} else {
|
||||
tabs.closeMult('demoTabs1', data.type, index); // 批量关闭标签
|
||||
var index = this.elem.index(); // 获取活动标签索引
|
||||
var layid = this.elem.attr('lay-id');
|
||||
|
||||
// 新增标签操作
|
||||
if (data.action === 'add') {
|
||||
// 在当前活动标签右侧新增标签页
|
||||
addTabs({
|
||||
mode: data.mode,
|
||||
index: index
|
||||
});
|
||||
} else if(data.action === 'close') { // 关闭标签操作
|
||||
if (data.mode === 'this') {
|
||||
tabs.close('demoTabs1', index); // 关闭当前标签
|
||||
} else {
|
||||
tabs.closeMult('demoTabs1', data.mode, index); // 批量关闭标签
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
@ -258,7 +310,7 @@
|
||||
tabs.render({
|
||||
elem: '#demoTabs2',
|
||||
header: [
|
||||
{ title: 'Tab1' },
|
||||
{ title: 'Tab1', closable: false },
|
||||
{ title: 'Tab2' },
|
||||
{ title: 'Tab3' }
|
||||
],
|
||||
@ -267,9 +319,9 @@
|
||||
{ content: 'Tab content 2' },
|
||||
{ content: 'Tab content 3' }
|
||||
],
|
||||
// index: 1, //初始选中项
|
||||
// index: 1, // 初始选中项
|
||||
// className: 'layui-tabs-card',
|
||||
// closable: true
|
||||
closable: true
|
||||
});
|
||||
|
||||
|
||||
|
@ -14,12 +14,17 @@
|
||||
<div class="layui-fluid" style="padding: 15px;">
|
||||
<button class="layui-btn" lay-on="asyncLoad">asyncLoad</button>
|
||||
<button class="layui-btn" lay-on="flatData">flatData</button>
|
||||
<button class="layui-btn" lay-on="expandNode">expandNode</button>
|
||||
<button class="layui-btn" lay-on="unexpandNode">unexpandNode</button>
|
||||
<table id="demo"></table>
|
||||
</div>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/Mock.js/1.0.0/mock-min.js"></script>
|
||||
<script src="../src/layui.js" src1="//cdnjs.cloudflare.com/ajax/libs/layui/2.9.7/layui.js"
|
||||
src1="https://cdn.jsdelivr.net/gh/layui/layui@879a9c629cc832f5b235d138adf164d74c34991b/src/layui.js"></script>
|
||||
<script>
|
||||
Mock.setup({
|
||||
timeout: '100-300'
|
||||
});
|
||||
layui.use(["treeTable", "util"], function () {
|
||||
var treeTable = layui.treeTable;
|
||||
var util = layui.util;
|
||||
@ -39,6 +44,11 @@
|
||||
async: {
|
||||
enable: true,
|
||||
autoParam: ["parentId=id"]
|
||||
},
|
||||
callback: {
|
||||
onExpand: function (tableId, trData, trExpand) {
|
||||
console.log('onExpand', tableId, trData.id, trExpand);
|
||||
}
|
||||
}
|
||||
},
|
||||
}, true)
|
||||
@ -57,6 +67,28 @@
|
||||
}
|
||||
},
|
||||
}, true)
|
||||
},
|
||||
expandNode: function(){
|
||||
treeTable.expandNode('demo', {
|
||||
index: 0,
|
||||
expandFlag: true,
|
||||
inherit: true,
|
||||
callbackFlag: true,
|
||||
done: function (tableId, trData, trExpand) {
|
||||
console.log('done', tableId, trData.id, trExpand);
|
||||
}
|
||||
})
|
||||
},
|
||||
unexpandNode: function(){
|
||||
treeTable.expandNode('demo', {
|
||||
index: 0,
|
||||
expandFlag: false,
|
||||
inherit: true,
|
||||
callbackFlag: true,
|
||||
done: function (tableId, trData, trExpand) {
|
||||
console.log('done', tableId, trData.id, trExpand);
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
@ -130,7 +162,7 @@
|
||||
//var testDatas = getTreeData(rootNodes);
|
||||
|
||||
Mock.mock(/getDatas/, "get", (config) => {
|
||||
console.log(config);
|
||||
//console.log(config);
|
||||
var params = layui.url(config.url);
|
||||
var search = params.search;
|
||||
var parentId = search.parentId;
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "layui",
|
||||
"version": "2.11.0-rc.2",
|
||||
"version": "2.11.4",
|
||||
"description": "Classic modular Front-End UI library",
|
||||
"keywords": [
|
||||
"layui",
|
||||
|
@ -577,7 +577,9 @@ a cite{font-style: normal;}
|
||||
.layui-colla-item:first-child{border-top: none;}
|
||||
.layui-colla-title{position: relative; height: 42px; line-height: 42px; padding: 0 15px 0 35px; color: #333; background-color: #fafafa; cursor: pointer; font-size: 14px; overflow: hidden;}
|
||||
.layui-colla-content{display: none; padding: 10px 15px; line-height: 1.6; color: #5F5F5F;}
|
||||
.layui-colla-icon{position: absolute; left: 15px; top: 0; font-size: 14px;}
|
||||
.layui-colla-icon{position: absolute; left: 15px; top: 50%; margin-top: -7px; font-size: 14px; line-height: normal; transition: all .2s;}
|
||||
.layui-colla-item.layui-show > .layui-colla-title .layui-colla-icon{transform: rotate(90deg);}
|
||||
.layui-colla-item.layui-show > .layui-colla-content{display: block;}
|
||||
|
||||
/* 卡片面板 */
|
||||
.layui-card{margin-bottom: 15px; border-radius: 2px; background-color: #fff; box-shadow: 0 1px 2px 0 rgba(0,0,0,.05);}
|
||||
@ -1504,13 +1506,13 @@ body .layui-table-tips .layui-layer-content{background: none; padding: 0; box-sh
|
||||
.layui-carousel>*[carousel-item]>.layui-this,
|
||||
.layui-carousel>*[carousel-item]>.layui-carousel-prev,
|
||||
.layui-carousel>*[carousel-item]>.layui-carousel-next{display: block}
|
||||
.layui-carousel>*[carousel-item]>.layui-this{left: 0;}
|
||||
.layui-carousel>*[carousel-item]>.layui-carousel-prev{left: -100%;}
|
||||
.layui-carousel>*[carousel-item]>.layui-carousel-next{left: 100%;}
|
||||
.layui-carousel>*[carousel-item]>.layui-this{-webkit-transform: translateX(0);transform: translateX(0);}
|
||||
.layui-carousel>*[carousel-item]>.layui-carousel-prev{-webkit-transform: translateX(-100%);transform: translateX(-100%);}
|
||||
.layui-carousel>*[carousel-item]>.layui-carousel-next{-webkit-transform: translateX(100%);transform: translateX(100%);}
|
||||
.layui-carousel>*[carousel-item]>.layui-carousel-prev.layui-carousel-right,
|
||||
.layui-carousel>*[carousel-item]>.layui-carousel-next.layui-carousel-left{left: 0;}
|
||||
.layui-carousel>*[carousel-item]>.layui-this.layui-carousel-left{left: -100%;}
|
||||
.layui-carousel>*[carousel-item]>.layui-this.layui-carousel-right{left: 100%;}
|
||||
.layui-carousel>*[carousel-item]>.layui-carousel-next.layui-carousel-left{-webkit-transform: translateX(0);transform: translateX(0);}
|
||||
.layui-carousel>*[carousel-item]>.layui-this.layui-carousel-left{-webkit-transform: translateX(-100%);transform: translateX(-100%);}
|
||||
.layui-carousel>*[carousel-item]>.layui-this.layui-carousel-right{-webkit-transform: translateX(100%);transform: translateX(100%);}
|
||||
|
||||
/* 上下切换 */.layui-carousel[lay-anim="updown"] .layui-carousel-arrow{left: 50%!important; top: 20px; margin: 0 0 0 -18px;}
|
||||
.layui-carousel[lay-anim="updown"] .layui-carousel-arrow[lay-type="add"]{top: auto!important; bottom: 20px;}
|
||||
@ -1519,13 +1521,13 @@ body .layui-table-tips .layui-layer-content{background: none; padding: 0; box-sh
|
||||
.layui-carousel[lay-anim="updown"] .layui-carousel-ind li{display: block; margin: 6px 0;}
|
||||
|
||||
.layui-carousel[lay-anim="updown"]>*[carousel-item]>*{left: 0!important;}
|
||||
.layui-carousel[lay-anim="updown"]>*[carousel-item]>.layui-this{top: 0;}
|
||||
.layui-carousel[lay-anim="updown"]>*[carousel-item]>.layui-carousel-prev{top: -100%;}
|
||||
.layui-carousel[lay-anim="updown"]>*[carousel-item]>.layui-carousel-next{top: 100%;}
|
||||
.layui-carousel[lay-anim="updown"]>*[carousel-item]>.layui-this{-webkit-transform: translateY(0);transform: translateY(0);}
|
||||
.layui-carousel[lay-anim="updown"]>*[carousel-item]>.layui-carousel-prev{-webkit-transform: translateY(-100%);transform: translateY(-100%);}
|
||||
.layui-carousel[lay-anim="updown"]>*[carousel-item]>.layui-carousel-next{-webkit-transform: translateY(100%);transform: translateY(100%);}
|
||||
.layui-carousel[lay-anim="updown"]>*[carousel-item]>.layui-carousel-prev.layui-carousel-right,
|
||||
.layui-carousel[lay-anim="updown"]>*[carousel-item]>.layui-carousel-next.layui-carousel-left{top: 0;}
|
||||
.layui-carousel[lay-anim="updown"]>*[carousel-item]>.layui-this.layui-carousel-left{top: -100%;}
|
||||
.layui-carousel[lay-anim="updown"]>*[carousel-item]>.layui-this.layui-carousel-right{top: 100%;}
|
||||
.layui-carousel[lay-anim="updown"]>*[carousel-item]>.layui-carousel-next.layui-carousel-left{-webkit-transform: translateY(0);transform: translateY(0);}
|
||||
.layui-carousel[lay-anim="updown"]>*[carousel-item]>.layui-this.layui-carousel-left{-webkit-transform: translateY(-100%);transform: translateY(-100%);}
|
||||
.layui-carousel[lay-anim="updown"]>*[carousel-item]>.layui-this.layui-carousel-right{-webkit-transform: translateY(100%);transform: translateY(100%);}
|
||||
|
||||
/* 渐显切换 */.layui-carousel[lay-anim="fade"]>*[carousel-item]>*{left: 0!important;}
|
||||
.layui-carousel[lay-anim="fade"]>*[carousel-item]>.layui-carousel-prev,
|
||||
|
@ -49,7 +49,6 @@ html #layuicss-skincodecss{display: none; position: absolute; width: 1989px;}
|
||||
.layui-code-preview > .layui-code-view{margin: 0;}
|
||||
.layui-code-preview > .layui-tab{position: relative; z-index: 1; margin-bottom: 0;}
|
||||
.layui-code-preview .layui-code-item{display: none; border-top-width: 0;}
|
||||
.layui-code-preview .layui-code-view > .layui-code-lines > .layui-code-line{}
|
||||
.layui-code-item-preview{position: relative; padding: 16px;}
|
||||
.layui-code-item-preview > iframe{position: absolute; top: 0; left: 0; width: 100%; height: 100%; border: none;}
|
||||
|
||||
|
@ -15,7 +15,7 @@ html #layuicss-laydate{display: none; position: absolute; width: 1989px;}
|
||||
.layui-laydate-header *,
|
||||
.layui-laydate-content td,
|
||||
.layui-laydate-list li{transition-duration: .3s; -webkit-transition-duration: .3s;}
|
||||
.layui-laydate-shade{top: 0; left: 0; width: 100%; height: 100%; _height: expression(document.body.offsetHeight+"px"); position: fixed; _position: absolute; pointer-events: auto;}
|
||||
.layui-laydate-shade{top: 0; left: 0; width: 100%; height: 100%; position: fixed; pointer-events: auto;}
|
||||
|
||||
/* 微微往下滑入 */
|
||||
@keyframes laydate-downbit {
|
||||
@ -51,7 +51,7 @@ html #layuicss-laydate{display: none; position: absolute; width: 1989px;}
|
||||
.laydate-time-text{cursor: default !important;}
|
||||
|
||||
/* 主体结构 */
|
||||
.layui-laydate-content{position: relative; padding: 10px; -moz-user-select: none; -webkit-user-select: none; -ms-user-select: none;}
|
||||
.layui-laydate-content{position: relative; padding: 10px; -moz-user-select: none; -webkit-user-select: none; -ms-user-select: none; user-select: none;}
|
||||
.layui-laydate-content table{border-collapse: collapse; border-spacing: 0;}
|
||||
.layui-laydate-content th,
|
||||
.layui-laydate-content td{width: 36px; height: 30px; padding: 0; text-align: center;}
|
||||
@ -140,7 +140,7 @@ html #layuicss-laydate{display: none; position: absolute; width: 1989px;}
|
||||
.layui-laydate-footer span[lay-type="date"]{color: #16b777;}
|
||||
.layui-laydate .layui-this,.layui-laydate .layui-this>div{background-color: #16b777 !important; color: #fff !important;}
|
||||
.layui-laydate .laydate-disabled,
|
||||
.layui-laydate .laydate-disabled:hover{background:none !important; color: #d2d2d2 !important; cursor: not-allowed !important; -moz-user-select: none; -webkit-user-select: none; -ms-user-select: none;}
|
||||
.layui-laydate .laydate-disabled:hover{background:none !important; color: #d2d2d2 !important; cursor: not-allowed !important; -moz-user-select: none; -webkit-user-select: none; -ms-user-select: none; user-select: none;}
|
||||
.layui-laydate .layui-this.laydate-disabled,.layui-laydate .layui-this.laydate-disabled>div{background-color: #eee !important}
|
||||
.layui-laydate-content td>div{padding: 7px 0; height: 100%;}
|
||||
|
||||
|
@ -6,17 +6,17 @@ html #layuicss-layer{display: none; position: absolute; width: 1989px;}
|
||||
|
||||
/* common */
|
||||
.layui-layer-shade, .layui-layer{position:fixed; _position:absolute; pointer-events: auto;}
|
||||
.layui-layer-shade{opacity: 0; transition: opacity .35s cubic-bezier(0.34, 0.69, 0.1, 1); top:0; left:0; width:100%; height:100%; _height:expression(document.body.offsetHeight+"px");}
|
||||
.layui-layer-shade{opacity: 0; transition: opacity .35s cubic-bezier(0.34, 0.69, 0.1, 1); top:0; left:0; width:100%; height:100%;}
|
||||
.layui-layer{-webkit-overflow-scrolling: touch;}
|
||||
.layui-layer{top:150px; left: 0; margin:0; padding:0; background-color:#fff; -webkit-background-clip: content; border-radius: 2px; box-shadow: 1px 1px 50px rgba(0,0,0,.3);}
|
||||
.layui-layer{top:150px; left: 0; margin:0; padding:0; background-color:#fff; -webkit-background-clip: content; background-clip: content; border-radius: 2px; box-shadow: 1px 1px 50px rgba(0,0,0,.3);}
|
||||
.layui-layer-close{position:absolute;}
|
||||
.layui-layer-content{position:relative;}
|
||||
.layui-layer-border{border: 1px solid #B2B2B2; border: 1px solid rgba(0,0,0,.1); box-shadow: 1px 1px 5px rgba(0,0,0,.2);}
|
||||
.layui-layer-load{background:url("data:image/gif;base64,R0lGODlhJQAlAJECAL3L2AYrTv///wAAACH/C05FVFNDQVBFMi4wAwEAAAAh+QQFCgACACwAAAAAJQAlAAACi5SPqcvtDyGYIFpF690i8xUw3qJBwUlSadmcLqYmGQu6KDIeM13beGzYWWy3DlB4IYaMk+Dso2RWkFCfLPcRvFbZxFLUDTt21BW56TyjRep1e20+i+eYMR145W2eefj+6VFmgTQi+ECVY8iGxcg35phGo/iDFwlTyXWphwlm1imGRdcnuqhHeop6UAAAIfkEBQoAAgAsEAACAAQACwAAAgWMj6nLXAAh+QQFCgACACwVAAUACgALAAACFZQvgRi92dyJcVJlLobUdi8x4bIhBQAh+QQFCgACACwXABEADAADAAACBYyPqcsFACH5BAUKAAIALBUAFQAKAAsAAAITlGKZwWoMHYxqtmplxlNT7ixGAQAh+QQFCgACACwQABgABAALAAACBYyPqctcACH5BAUKAAIALAUAFQAKAAsAAAIVlC+BGL3Z3IlxUmUuhtR2LzHhsiEFACH5BAUKAAIALAEAEQAMAAMAAAIFjI+pywUAIfkEBQoAAgAsBQAFAAoACwAAAhOUYJnAagwdjGq2amXGU1PuLEYBACH5BAUKAAIALBAAAgAEAAsAAAIFhI+py1wAIfkEBQoAAgAsFQAFAAoACwAAAhWUL4AIvdnciXFSZS6G1HYvMeGyIQUAIfkEBQoAAgAsFwARAAwAAwAAAgWEj6nLBQAh+QQFCgACACwVABUACgALAAACE5RgmcBqDB2MarZqZcZTU+4sRgEAIfkEBQoAAgAsEAAYAAQACwAAAgWEj6nLXAAh+QQFCgACACwFABUACgALAAACFZQvgAi92dyJcVJlLobUdi8x4bIhBQAh+QQFCgACACwBABEADAADAAACBYSPqcsFADs=") #fff center center no-repeat;}
|
||||
.layui-layer-setwin span,
|
||||
.layui-layer-btn a{display: inline-block; vertical-align: middle; *display: inline; *zoom:1; }
|
||||
.layui-layer-btn a{display: inline-block; vertical-align: middle;}
|
||||
|
||||
.layui-layer-move{display: none; position: fixed; *position: absolute; left: 0px; top: 0px; width: 100%; height: 100%; cursor: move; opacity: 0; filter:alpha(opacity=0); background-color: #fff; z-index: 2147483647;}
|
||||
.layui-layer-move{display: none; position: fixed; left: 0px; top: 0px; width: 100%; height: 100%; cursor: move; opacity: 0; filter:alpha(opacity=0); background-color: #fff; z-index: 2147483647;}
|
||||
.layui-layer-resize{position: absolute; width: 15px; height: 15px; right: 0; bottom: 0; cursor: se-resize;}
|
||||
|
||||
/* 动画 */
|
||||
@ -32,17 +32,27 @@ html #layuicss-layer{display: none; position: absolute; width: 1989px;}
|
||||
}
|
||||
.layer-anim-00{-webkit-animation-name: layer-bounceIn;animation-name: layer-bounceIn}
|
||||
|
||||
@-webkit-keyframes layer-zoomInDown{0%{opacity:0;-webkit-transform:scale(.1) translateY(-2000px);transform:scale(.1) translateY(-2000px);-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}60%{opacity:1;-webkit-transform:scale(.475) translateY(60px);transform:scale(.475) translateY(60px);-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}}@keyframes layer-zoomInDown{0%{opacity:0;-webkit-transform:scale(.1) translateY(-2000px);-ms-transform:scale(.1) translateY(-2000px);transform:scale(.1) translateY(-2000px);-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}60%{opacity:1;-webkit-transform:scale(.475) translateY(60px);-ms-transform:scale(.475) translateY(60px);transform:scale(.475) translateY(60px);-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}}.layer-anim-01{-webkit-animation-name:layer-zoomInDown;animation-name:layer-zoomInDown}
|
||||
@-webkit-keyframes layer-zoomInDown{0%{opacity:0;-webkit-transform:scale(.1) translateY(-2000px);transform:scale(.1) translateY(-2000px);-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}60%{opacity:1;-webkit-transform:scale(.475) translateY(60px);transform:scale(.475) translateY(60px);-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}}
|
||||
@keyframes layer-zoomInDown{0%{opacity:0;-webkit-transform:scale(.1) translateY(-2000px);-ms-transform:scale(.1) translateY(-2000px);transform:scale(.1) translateY(-2000px);-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}60%{opacity:1;-webkit-transform:scale(.475) translateY(60px);-ms-transform:scale(.475) translateY(60px);transform:scale(.475) translateY(60px);-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}}.layer-anim-01{-webkit-animation-name:layer-zoomInDown;animation-name:layer-zoomInDown}
|
||||
|
||||
@-webkit-keyframes layer-fadeInUpBig{0%{opacity:0;-webkit-transform:translateY(2000px);transform:translateY(2000px)}100%{opacity:1;-webkit-transform:translateY(0);transform:translateY(0)}}@keyframes layer-fadeInUpBig{0%{opacity:0;-webkit-transform:translateY(2000px);-ms-transform:translateY(2000px);transform:translateY(2000px)}100%{opacity:1;-webkit-transform:translateY(0);-ms-transform:translateY(0);transform:translateY(0)}}.layer-anim-02{-webkit-animation-name:layer-fadeInUpBig;animation-name:layer-fadeInUpBig}
|
||||
@-webkit-keyframes layer-fadeInUpBig{0%{opacity:0;-webkit-transform:translateY(2000px);transform:translateY(2000px)}100%{opacity:1;-webkit-transform:translateY(0);transform:translateY(0)}}
|
||||
@keyframes layer-fadeInUpBig{0%{opacity:0;-webkit-transform:translateY(2000px);-ms-transform:translateY(2000px);transform:translateY(2000px)}100%{opacity:1;-webkit-transform:translateY(0);-ms-transform:translateY(0);transform:translateY(0)}}
|
||||
.layer-anim-02{-webkit-animation-name:layer-fadeInUpBig;animation-name:layer-fadeInUpBig}
|
||||
|
||||
@-webkit-keyframes layer-zoomInLeft{0%{opacity:0;-webkit-transform:scale(.1) translateX(-2000px);transform:scale(.1) translateX(-2000px);-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}60%{opacity:1;-webkit-transform:scale(.475) translateX(48px);transform:scale(.475) translateX(48px);-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}}@keyframes layer-zoomInLeft{0%{opacity:0;-webkit-transform:scale(.1) translateX(-2000px);-ms-transform:scale(.1) translateX(-2000px);transform:scale(.1) translateX(-2000px);-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}60%{opacity:1;-webkit-transform:scale(.475) translateX(48px);-ms-transform:scale(.475) translateX(48px);transform:scale(.475) translateX(48px);-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}}.layer-anim-03{-webkit-animation-name:layer-zoomInLeft;animation-name:layer-zoomInLeft}
|
||||
@-webkit-keyframes layer-zoomInLeft{0%{opacity:0;-webkit-transform:scale(.1) translateX(-2000px);transform:scale(.1) translateX(-2000px);-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}60%{opacity:1;-webkit-transform:scale(.475) translateX(48px);transform:scale(.475) translateX(48px);-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}}
|
||||
@keyframes layer-zoomInLeft{0%{opacity:0;-webkit-transform:scale(.1) translateX(-2000px);-ms-transform:scale(.1) translateX(-2000px);transform:scale(.1) translateX(-2000px);-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}60%{opacity:1;-webkit-transform:scale(.475) translateX(48px);-ms-transform:scale(.475) translateX(48px);transform:scale(.475) translateX(48px);-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}}.layer-anim-03{-webkit-animation-name:layer-zoomInLeft;animation-name:layer-zoomInLeft}
|
||||
|
||||
@-webkit-keyframes layer-rollIn{0%{opacity:0;-webkit-transform:translateX(-100%) rotate(-120deg);transform:translateX(-100%) rotate(-120deg)}100%{opacity:1;-webkit-transform:translateX(0px) rotate(0deg);transform:translateX(0px) rotate(0deg)}}@keyframes layer-rollIn{0%{opacity:0;-webkit-transform:translateX(-100%) rotate(-120deg);-ms-transform:translateX(-100%) rotate(-120deg);transform:translateX(-100%) rotate(-120deg)}100%{opacity:1;-webkit-transform:translateX(0px) rotate(0deg);-ms-transform:translateX(0px) rotate(0deg);transform:translateX(0px) rotate(0deg)}}.layer-anim-04{-webkit-animation-name:layer-rollIn;animation-name:layer-rollIn}
|
||||
@-webkit-keyframes layer-rollIn{0%{opacity:0;-webkit-transform:translateX(-100%) rotate(-120deg);transform:translateX(-100%) rotate(-120deg)}100%{opacity:1;-webkit-transform:translateX(0px) rotate(0deg);transform:translateX(0px) rotate(0deg)}}
|
||||
@keyframes layer-rollIn{0%{opacity:0;-webkit-transform:translateX(-100%) rotate(-120deg);-ms-transform:translateX(-100%) rotate(-120deg);transform:translateX(-100%) rotate(-120deg)}100%{opacity:1;-webkit-transform:translateX(0px) rotate(0deg);-ms-transform:translateX(0px) rotate(0deg);transform:translateX(0px) rotate(0deg)}}
|
||||
.layer-anim-04{-webkit-animation-name:layer-rollIn;animation-name:layer-rollIn}
|
||||
|
||||
@keyframes layer-fadeIn{0%{opacity:0}100%{opacity:1}}.layer-anim-05{-webkit-animation-name:layer-fadeIn;animation-name:layer-fadeIn}
|
||||
@-webkit-keyframes layer-fadeIn{0%{opacity:0}100%{opacity:1}}
|
||||
@keyframes layer-fadeIn{0%{opacity:0}100%{opacity:1}}
|
||||
.layer-anim-05{-webkit-animation-name:layer-fadeIn;animation-name:layer-fadeIn}
|
||||
|
||||
@-webkit-keyframes layer-shake{0%,100%{-webkit-transform:translateX(0);transform:translateX(0)}10%,30%,50%,70%,90%{-webkit-transform:translateX(-10px);transform:translateX(-10px)}20%,40%,60%,80%{-webkit-transform:translateX(10px);transform:translateX(10px)}}@keyframes layer-shake{0%,100%{-webkit-transform:translateX(0);-ms-transform:translateX(0);transform:translateX(0)}10%,30%,50%,70%,90%{-webkit-transform:translateX(-10px);-ms-transform:translateX(-10px);transform:translateX(-10px)}20%,40%,60%,80%{-webkit-transform:translateX(10px);-ms-transform:translateX(10px);transform:translateX(10px)}}.layer-anim-06{-webkit-animation-name:layer-shake;animation-name:layer-shake}@-webkit-keyframes fadeIn{0%{opacity:0}100%{opacity:1}}
|
||||
@-webkit-keyframes layer-shake{0%,100%{-webkit-transform:translateX(0);transform:translateX(0)}10%,30%,50%,70%,90%{-webkit-transform:translateX(-10px);transform:translateX(-10px)}20%,40%,60%,80%{-webkit-transform:translateX(10px);transform:translateX(10px)}}
|
||||
@keyframes layer-shake{0%,100%{-webkit-transform:translateX(0);-ms-transform:translateX(0);transform:translateX(0)}10%,30%,50%,70%,90%{-webkit-transform:translateX(-10px);-ms-transform:translateX(-10px);transform:translateX(-10px)}20%,40%,60%,80%{-webkit-transform:translateX(10px);-ms-transform:translateX(10px);transform:translateX(10px)}}
|
||||
.layer-anim-06{-webkit-animation-name:layer-shake;animation-name:layer-shake}
|
||||
|
||||
/* 从上往下 */
|
||||
@keyframes layer-slide-down {
|
||||
@ -120,7 +130,7 @@ html #layuicss-layer{display: none; position: absolute; width: 1989px;}
|
||||
|
||||
/* 标题栏 */
|
||||
.layui-layer-title{padding: 0 81px 0 16px; height: 50px; line-height: 50px; border-bottom:1px solid #F0F0F0; font-size: 14px; color:#333; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; border-radius: 2px 2px 0 0;}
|
||||
.layui-layer-setwin{position:absolute; right: 15px; *right:0; top: 16px; font-size:0; line-height: initial;}
|
||||
.layui-layer-setwin{position:absolute; right: 15px; top: 16px; font-size:0; line-height: initial;}
|
||||
.layui-layer-setwin span{position:relative; width: 16px; height: 16px; line-height: 18px; margin-left: 10px; text-align: center; font-size: 16px; cursor: pointer; color: #000; _overflow: hidden; box-sizing: border-box;}
|
||||
.layui-layer-setwin .layui-layer-min:before{content: ''; position: absolute; width: 12px; border-bottom: 1px solid #2E2D3C; left: 50%; top: 50%; margin: -0.5px 0 0 -6px; cursor: pointer; _overflow:hidden;}
|
||||
.layui-layer-setwin .layui-layer-min:hover:before{background-color: #2D93CA}
|
||||
@ -134,7 +144,7 @@ html #layuicss-layer{display: none; position: absolute; width: 1989px;}
|
||||
.layui-layer-setwin .layui-layer-maxmin:after{z-index: 0; margin: -5px 0 0 -1px;}
|
||||
.layui-layer-setwin .layui-layer-close{cursor: pointer;}
|
||||
.layui-layer-setwin .layui-layer-close:hover{opacity:0.7;}
|
||||
.layui-layer-setwin .layui-layer-close2{position:absolute; right: -28px; top: -28px; color: #fff; background-color: #787878; padding: 3px; border: 3px solid; width: 28px; height: 28px; font-size: 16px; font-weight: bolder; border-radius: 50%; margin-left: 0; *right:-18px; _display:none;}
|
||||
.layui-layer-setwin .layui-layer-close2{position:absolute; right: -28px; top: -28px; color: #fff; background-color: #787878; padding: 3px; border: 3px solid; width: 28px; height: 28px; font-size: 16px; font-weight: bolder; border-radius: 50%; margin-left: 0;}
|
||||
.layui-layer-setwin .layui-layer-close2:hover{opacity: unset; background-color: #3888f6;}
|
||||
|
||||
/* 按钮栏 */
|
||||
@ -184,7 +194,7 @@ html #layuicss-layer{display: none; position: absolute; width: 1989px;}
|
||||
.layui-layer-tips{background: none; box-shadow:none; border:none;}
|
||||
.layui-layer-tips .layui-layer-content{position: relative; line-height: 22px; min-width: 12px; padding: 8px 15px; font-size: 12px; _float:left; border-radius: 2px; box-shadow: 1px 1px 3px rgba(0,0,0,.2); background-color: #000; color: #fff;}
|
||||
.layui-layer-tips .layui-layer-close{right:-2px; top:-1px;}
|
||||
.layui-layer-tips i.layui-layer-TipsG{ position:absolute; width:0; height:0; border-width:8px; border-color:transparent; border-style:dashed; *overflow:hidden;}
|
||||
.layui-layer-tips i.layui-layer-TipsG{ position:absolute; width:0; height:0; border-width:8px; border-color:transparent; border-style:dashed;}
|
||||
.layui-layer-tips i.layui-layer-TipsT, .layui-layer-tips i.layui-layer-TipsB{left:5px; border-right-style:solid; border-right-color: #000;}
|
||||
.layui-layer-tips i.layui-layer-TipsT{bottom:-8px;}
|
||||
.layui-layer-tips i.layui-layer-TipsB{top:-8px;}
|
||||
@ -220,18 +230,16 @@ html #layuicss-layer{display: none; position: absolute; width: 1989px;}
|
||||
|
||||
|
||||
/**
|
||||
|
||||
@Name: layer拓展样式
|
||||
|
||||
* layer 拓展层
|
||||
*/
|
||||
|
||||
/* prompt模式 */
|
||||
/* prompt */
|
||||
.layui-layer-prompt .layui-layer-input{display: block; width: 260px; height: 36px; margin: 0 auto; line-height: 30px; padding-left: 10px; border: 1px solid #e6e6e6; color: #333;}
|
||||
.layui-layer-prompt textarea.layui-layer-input{width: 300px; height: 100px; line-height: 20px; padding: 6px 10px;}
|
||||
.layui-layer-prompt .layui-layer-content{padding: 16px;}
|
||||
.layui-layer-prompt .layui-layer-btn{padding-top: 0;}
|
||||
|
||||
/* tab模式 */
|
||||
/* tab */
|
||||
.layui-layer-tab{box-shadow:1px 1px 50px rgba(0,0,0,.4);}
|
||||
.layui-layer-tab .layui-layer-title{padding-left:0; overflow: visible;}
|
||||
.layui-layer-tab .layui-layer-title span{position:relative; display: inline-block; vertical-align: top; border-left: 1px solid transparent; border-right: 1px solid transparent; min-width:80px; max-width: 300px; padding:0 16px; text-align:center; cursor:default; text-overflow: ellipsis; overflow: hidden; white-space: nowrap; cursor: pointer;}
|
||||
@ -244,7 +252,7 @@ html #layuicss-layer{display: none; position: absolute; width: 1989px;}
|
||||
/* photos */
|
||||
.layui-layer-photos{background: none; box-shadow: none;}
|
||||
.layui-layer-photos .layui-layer-content{overflow: visible; text-align: center;}
|
||||
.layui-layer-photos .layer-layer-photos-main img{position: relative; width:100%; display: inline-block; *display:inline; *zoom:1; vertical-align:top;}
|
||||
.layui-layer-photos .layer-layer-photos-main img{position: relative; width:100%; display: inline-block; vertical-align:top;}
|
||||
.layui-layer-photos-prev,
|
||||
.layui-layer-photos-next{position: fixed; top: 50%; width: 52px; height: 52px; line-height: 52px; margin-top: -26px; cursor: pointer; font-size: 52px; color: #717171;}
|
||||
.layui-layer-photos-prev{left: 32px;}
|
||||
@ -252,8 +260,8 @@ html #layuicss-layer{display: none; position: absolute; width: 1989px;}
|
||||
.layui-layer-photos-prev:hover,
|
||||
.layui-layer-photos-next:hover{color: #959595;}
|
||||
|
||||
.layui-layer-photos-toolbar{position: fixed; left: 0; right: 0; bottom: 0; width: 100%; height: 52px; line-height: 52px; background-color: #000\9; filter: Alpha(opacity=60); background-color: rgba(0,0,0,.32); color: #fff; text-overflow: ellipsis; overflow: hidden; white-space: nowrap; font-size:0;}
|
||||
.layui-layer-photos-toolbar > *{display:inline-block; vertical-align: top; padding: 0 16px; font-size: 12px; color: #fff; *display:inline; *zoom: 1;}
|
||||
.layui-layer-photos-toolbar{position: fixed; left: 0; right: 0; bottom: 0; width: 100%; height: 52px; line-height: 52px; background-color: rgba(0,0,0,.32); color: #fff; text-overflow: ellipsis; overflow: hidden; white-space: nowrap; font-size:0;}
|
||||
.layui-layer-photos-toolbar > *{display:inline-block; vertical-align: top; padding: 0 16px; font-size: 12px; color: #fff;}
|
||||
.layui-layer-photos-toolbar *{font-size: 12px;}
|
||||
.layui-layer-photos-header{top: 0; bottom: auto;}
|
||||
.layui-layer-photos-header > span{cursor: pointer;}
|
||||
|
36
src/layui.js
36
src/layui.js
@ -28,7 +28,7 @@
|
||||
|
||||
// constructor
|
||||
var Class = function() {
|
||||
this.v = '2.11.0-rc.2'; // 版本号
|
||||
this.v = '2.11.4'; // 版本号
|
||||
};
|
||||
|
||||
// 识别预先可能定义的指定全局对象
|
||||
@ -156,7 +156,7 @@
|
||||
}
|
||||
};
|
||||
|
||||
// 或许配置及临时缓存信息
|
||||
// 获取配置及临时缓存信息
|
||||
Class.prototype.cache = Object.assign(config, cache);
|
||||
|
||||
/**
|
||||
@ -421,7 +421,7 @@
|
||||
Class.prototype.link = function(href, callback, id) {
|
||||
var that = this;
|
||||
var head = document.getElementsByTagName('head')[0];
|
||||
var link = document.createElement('link');
|
||||
var hasCallback = typeof callback === 'function';
|
||||
|
||||
// 若第二个参数为 string 类型,则该参数为 id
|
||||
if (typeof callback === 'string') {
|
||||
@ -440,26 +440,31 @@
|
||||
});
|
||||
}
|
||||
|
||||
// 若为传入 id ,则取路径 `//` 后面的字符拼接为 id,不含.与参数
|
||||
// 若未传入 id ,则取路径 `//` 后面的字符拼接为 id,不含.与参数
|
||||
id = id || href.replace(/^(#|(http(s?)):\/\/|\/\/)|\.|\/|\?.+/g, '');
|
||||
id = 'layuicss-'+ id;
|
||||
|
||||
link.href = href + (config.debug ? '?v='+new Date().getTime() : '');
|
||||
link.rel = 'stylesheet';
|
||||
link.id = id;
|
||||
var link = document.getElementById(id);
|
||||
|
||||
// 插入节点
|
||||
if (!document.getElementById(id)) {
|
||||
// 初始创建节点
|
||||
if (!link) {
|
||||
link = document.createElement('link');
|
||||
link.href = href + (config.debug ? '?v='+new Date().getTime() : '');
|
||||
link.rel = 'stylesheet';
|
||||
link.id = id;
|
||||
head.appendChild(link);
|
||||
}
|
||||
|
||||
// 是否执行回调
|
||||
if (typeof callback !== 'function') {
|
||||
// 若加载已完成,则直接执行回调函数
|
||||
if (link.__lay_readyState__ === 'complete') {
|
||||
hasCallback && callback(link);
|
||||
return that;
|
||||
}
|
||||
|
||||
// 初始加载
|
||||
onNodeLoad(link, function() {
|
||||
callback(link);
|
||||
link.__lay_readyState__ = 'complete';
|
||||
hasCallback && callback(link);
|
||||
}, function() {
|
||||
error(href + ' load error', 'error');
|
||||
head.removeChild(link); // 移除节点
|
||||
@ -521,12 +526,16 @@
|
||||
var hash = hash || location.hash;
|
||||
var data = {
|
||||
path: [],
|
||||
pathname: [],
|
||||
search: {},
|
||||
hash: (hash.match(/[^#](#.*$)/) || [])[1] || '',
|
||||
href: ''
|
||||
};
|
||||
|
||||
if (!/^#/.test(hash)) return data; // 禁止非路由规范
|
||||
// 禁止非 hash 路由规范
|
||||
if (!/^#/.test(hash)) {
|
||||
return data;
|
||||
}
|
||||
|
||||
hash = hash.replace(/^#/, '');
|
||||
data.href = hash;
|
||||
@ -540,6 +549,7 @@
|
||||
}() : data.path.push(item);
|
||||
});
|
||||
|
||||
data.pathname = data.path; // path → pathname, 与 layui.url 一致
|
||||
return data;
|
||||
};
|
||||
|
||||
|
@ -152,14 +152,14 @@ layui.define(['jquery', 'lay'], function(exports) {
|
||||
}
|
||||
|
||||
// 渲染
|
||||
if (typeof settings.render === 'function') {
|
||||
if (typeof that.render === 'function') {
|
||||
component.cache.id[options.id] = null; // 记录所有实例 id,用于批量操作(如 resize)
|
||||
elem.attr(MOD_ID, options.id); // 目标元素已渲染过的标记
|
||||
that.render(rerender); // 渲染核心
|
||||
}
|
||||
|
||||
// 事件
|
||||
typeof settings.events === 'function' && that.events();
|
||||
typeof that.events === 'function' && that.events();
|
||||
};
|
||||
|
||||
// 组件必传项
|
||||
|
@ -567,7 +567,29 @@ layui.define(['jquery', 'laytpl', 'lay', 'util'], function(exports) {
|
||||
}
|
||||
|
||||
that.remove();
|
||||
}, {passive: false});
|
||||
}, lay.passiveSupported ? { passive: false} : false);
|
||||
|
||||
// onClickOutside 检测 iframe
|
||||
_WIN.on('blur', function(e){
|
||||
if(!dropdown.thisId) return;
|
||||
var that = thisModule.getThis(dropdown.thisId)
|
||||
if(!that) return;
|
||||
if(!that.config.elem.data(MOD_INDEX_OPENED)) return;
|
||||
|
||||
setTimeout(function(){
|
||||
if(document.activeElement && document.activeElement.tagName === 'IFRAME'
|
||||
&& that.mainElem && that.mainElem[0]
|
||||
&& that.mainElem[0].contains && !that.mainElem[0].contains(document.activeElement)
|
||||
){
|
||||
// 点击 dropdown 外部时的回调
|
||||
if(typeof that.config.onClickOutside === 'function'){
|
||||
var shouldClose = that.config.onClickOutside(e.originalEvent);
|
||||
if(shouldClose === false) return;
|
||||
}
|
||||
that.remove();
|
||||
}
|
||||
}, 0);
|
||||
})
|
||||
|
||||
// 基础菜单的静态元素事件
|
||||
var ELEM_LI = '.layui-menu:not(.layui-dropdown-menu) li';
|
||||
|
@ -404,28 +404,51 @@ layui.define('jquery', function(exports) {
|
||||
}
|
||||
|
||||
// 折叠面板
|
||||
,collapse: function(){
|
||||
,collapse: function() {
|
||||
var othis = $(this);
|
||||
var icon = othis.find('.layui-colla-icon');
|
||||
var elemCont = othis.siblings('.layui-colla-content');
|
||||
var parents = othis.parents('.layui-collapse').eq(0);
|
||||
var filter = parents.attr('lay-filter');
|
||||
var isNone = elemCont.css('display') === 'none';
|
||||
var wrapper = othis.closest('.layui-collapse');
|
||||
var filter = wrapper.attr('lay-filter');
|
||||
|
||||
// 是否手风琴
|
||||
if(typeof parents.attr('lay-accordion') === 'string'){
|
||||
var show = parents.children('.layui-colla-item').children('.'+SHOW);
|
||||
show.siblings('.layui-colla-title').children('.layui-colla-icon').html('');
|
||||
show.removeClass(SHOW);
|
||||
var ANIM_MS = 200; // 动画过渡毫秒数
|
||||
var CLASS_ITEM = '.layui-colla-item';
|
||||
var CLASS_CONTENT = '.layui-colla-content';
|
||||
|
||||
var thisItemElem = othis.parent(CLASS_ITEM);
|
||||
var thisContentElem = othis.siblings(CLASS_CONTENT);
|
||||
var isNone = thisContentElem.css('display') === 'none';
|
||||
var isAccordion = typeof wrapper.attr('lay-accordion') === 'string';
|
||||
|
||||
// 动画执行完成后的操作
|
||||
var complete = function() {
|
||||
$(this).css('display', ''); // 剔除动画生成的 style display,以适配外部样式的状态重置
|
||||
};
|
||||
|
||||
// 是否正处于动画中的状态
|
||||
if (thisContentElem.is(':animated')) return;
|
||||
|
||||
// 展开或收缩
|
||||
if (isNone) {
|
||||
// 先执行 slideDown 动画,再标注展开状态样式,避免元素 `block` 状态导致动画无效
|
||||
thisContentElem.slideDown(ANIM_MS, complete);
|
||||
thisItemElem.addClass(SHOW);
|
||||
} else {
|
||||
// 先取消展开状态样式,再将元素临时显示,避免 `none` 状态导致 slideUp 动画无效
|
||||
thisItemElem.removeClass(SHOW);
|
||||
thisContentElem.show().slideUp(ANIM_MS, complete);
|
||||
}
|
||||
|
||||
elemCont[isNone ? 'addClass' : 'removeClass'](SHOW);
|
||||
icon.html(isNone ? '' : '');
|
||||
// 是否开启手风琴
|
||||
if (isAccordion) {
|
||||
var itemSiblings = thisItemElem.siblings('.'+ SHOW);
|
||||
itemSiblings.removeClass(SHOW);
|
||||
itemSiblings.children(CLASS_CONTENT).show().slideUp(ANIM_MS, complete);
|
||||
}
|
||||
|
||||
// 事件
|
||||
layui.event.call(this, MOD_NAME, 'collapse('+ filter +')', {
|
||||
title: othis
|
||||
,content: elemCont
|
||||
,show: isNone
|
||||
title: othis,
|
||||
content: thisContentElem,
|
||||
show: isNone
|
||||
});
|
||||
}
|
||||
};
|
||||
@ -617,27 +640,32 @@ layui.define('jquery', function(exports) {
|
||||
});
|
||||
}
|
||||
|
||||
//折叠面板
|
||||
,collapse: function(elem){
|
||||
// 折叠面板
|
||||
,collapse: function(elem) {
|
||||
var ELEM = 'layui-collapse';
|
||||
var targetElem = elem || $('.' + ELEM + elemFilter);
|
||||
|
||||
targetElem.each(function(){
|
||||
var elemItem = $(this).find('.layui-colla-item')
|
||||
elemItem.each(function(){
|
||||
targetElem.each(function() {
|
||||
var elemItem = $(this).find('.layui-colla-item');
|
||||
elemItem.each(function() {
|
||||
var othis = $(this)
|
||||
,elemTitle = othis.find('.layui-colla-title')
|
||||
,elemCont = othis.find('.layui-colla-content')
|
||||
,isNone = elemCont.css('display') === 'none';
|
||||
var elemTitle = othis.find('.layui-colla-title');
|
||||
var elemCont = othis.find('.layui-colla-content');
|
||||
var isNone = elemCont.css('display') === 'none';
|
||||
|
||||
//初始状态
|
||||
// 初始状态
|
||||
elemTitle.find('.layui-colla-icon').remove();
|
||||
elemTitle.append('<i class="layui-icon layui-colla-icon">'+ (isNone ? '' : '') +'</i>');
|
||||
elemTitle.append('<i class="layui-icon layui-icon-right layui-colla-icon"></i>');
|
||||
othis[isNone ? 'removeClass' : 'addClass'](SHOW);
|
||||
|
||||
//点击标题
|
||||
// 兼容旧版( < 2.11.3)
|
||||
if (elemCont.hasClass(SHOW)) {
|
||||
elemCont.removeClass(SHOW);
|
||||
}
|
||||
|
||||
// 点击标题
|
||||
elemTitle.off('click', call.collapse).on('click', call.collapse);
|
||||
});
|
||||
|
||||
});
|
||||
}
|
||||
};
|
||||
|
@ -10,7 +10,6 @@ layui.define(['lay', 'layer', 'util'], function(exports){
|
||||
var util = layui.util;
|
||||
var hint = layui.hint();
|
||||
var device = layui.device();
|
||||
var needCheckboxFallback = lay.ie && parseFloat(lay.ie) === 8;
|
||||
|
||||
var MOD_NAME = 'form';
|
||||
var ELEM = '.layui-form';
|
||||
@ -21,6 +20,11 @@ layui.define(['lay', 'layer', 'util'], function(exports){
|
||||
var OUT_OF_RANGE = 'layui-input-number-out-of-range';
|
||||
var BAD_INPUT = 'layui-input-number-invalid';
|
||||
|
||||
// ie8 中可以获取到 input 元素的 'indeterminate' 属性描述符,但重新定义 getter/setter 无效,无报错
|
||||
// AppleWebKit/537.36 无法获取 input 元素任意属性的属性描述符(包括lookupGetter),但可以重新定义 getter/setter
|
||||
var needCheckboxFallback = (lay.ie && parseFloat(lay.ie) === 8)
|
||||
|| typeof Object.getOwnPropertyDescriptor(HTMLInputElement.prototype, 'checked') === 'undefined'
|
||||
|
||||
var Form = function(){
|
||||
this.config = {
|
||||
// 内置的验证规则
|
||||
@ -554,7 +558,7 @@ layui.define(['lay', 'layer', 'util'], function(exports){
|
||||
hideDown();
|
||||
initValue && input.val(initValue);
|
||||
},
|
||||
{ignore: title}
|
||||
{ignore: title, detectIframe: true, capture: false}
|
||||
);
|
||||
};
|
||||
|
||||
@ -563,7 +567,10 @@ layui.define(['lay', 'layer', 'util'], function(exports){
|
||||
title.parent().removeClass(CLASS+'ed ' + CLASS+'up');
|
||||
input.blur();
|
||||
isCreatable && dl.children('.' + CREATE_OPTION).remove();
|
||||
removeClickOutsideEvent && removeClickOutsideEvent();
|
||||
if(typeof removeClickOutsideEvent === 'function'){
|
||||
removeClickOutsideEvent();
|
||||
removeClickOutsideEvent = null;
|
||||
}
|
||||
if(isAppendTo){
|
||||
reElem.detach();
|
||||
$(window).off('resize.lay_select_resize');
|
||||
@ -576,7 +583,7 @@ layui.define(['lay', 'layer', 'util'], function(exports){
|
||||
|
||||
// 未查询到相关值
|
||||
if(none){
|
||||
initValue = $(select[0].options[selectedIndex]).html(); // 重新获得初始选中值
|
||||
initValue = $(select[0].options[selectedIndex]).prop('text'); // 重新获得初始选中值
|
||||
|
||||
// 如果是第一项,且文本值等于 placeholder,则清空初始值
|
||||
if(selectedIndex === 0 && initValue === input.attr('placeholder')){
|
||||
@ -747,10 +754,10 @@ layui.define(['lay', 'layer', 'util'], function(exports){
|
||||
}else{
|
||||
var createOptionElem = dl.children('.' + CREATE_OPTION);
|
||||
if(createOptionElem[0]){
|
||||
createOptionElem.attr('lay-value', value).html(util.escape(value));
|
||||
createOptionElem.attr('lay-value', value).text(value);
|
||||
}else{
|
||||
// 临时显示在顶部
|
||||
var ddElem = $('<dd>').addClass(CREATE_OPTION).attr('lay-value', value).html(util.escape(value));
|
||||
var ddElem = $('<dd>').addClass(CREATE_OPTION).attr('lay-value', value).text(value);
|
||||
var firstOptionELem = dl.children().eq(0);
|
||||
var hasTips = firstOptionELem.hasClass('layui-select-tips');
|
||||
firstOptionELem[hasTips ? 'after' : 'before'](ddElem);
|
||||
@ -782,7 +789,7 @@ layui.define(['lay', 'layer', 'util'], function(exports){
|
||||
input.on('input propertychange', layui.debounce(search, 50)).on('blur', function(e){
|
||||
var selectedIndex = select[0].selectedIndex;
|
||||
|
||||
initValue = $(select[0].options[selectedIndex]).text(); // 重新获得初始选中值
|
||||
initValue = $(select[0].options[selectedIndex]).prop('text'); // 重新获得初始选中值
|
||||
|
||||
// 如果是第一项,且文本值等于 placeholder,则清空初始值
|
||||
if(selectedIndex === 0 && initValue === input.attr('placeholder')){
|
||||
@ -804,6 +811,17 @@ layui.define(['lay', 'layer', 'util'], function(exports){
|
||||
|
||||
if(othis.hasClass(DISABLED)) return false;
|
||||
|
||||
// 将新增的 option 元素添加到末尾
|
||||
if(isCreatable && othis.hasClass(CREATE_OPTION)){
|
||||
var optionElem = $('<option>').text(othis.text());
|
||||
var displayValue = optionElem.prop('text');
|
||||
value = displayValue;
|
||||
optionElem.attr('value', displayValue);
|
||||
select.append(optionElem);
|
||||
othis.removeClass(CREATE_OPTION).attr('lay-value', displayValue).text(displayValue);
|
||||
dl.append(othis);
|
||||
}
|
||||
|
||||
if(othis.hasClass('layui-select-tips')){
|
||||
input.val('');
|
||||
} else {
|
||||
@ -811,13 +829,6 @@ layui.define(['lay', 'layer', 'util'], function(exports){
|
||||
othis.addClass(THIS);
|
||||
}
|
||||
|
||||
// 将新增的 option 元素添加到末尾
|
||||
if(isCreatable && othis.hasClass(CREATE_OPTION)){
|
||||
dl.append(othis.removeClass(CREATE_OPTION));
|
||||
var optionElem = $('<option>').attr('value', value).text(othis.text());
|
||||
select.append(optionElem);
|
||||
}
|
||||
|
||||
othis.siblings().removeClass(THIS);
|
||||
select.val(value).removeClass('layui-form-danger');
|
||||
|
||||
@ -855,7 +866,7 @@ layui.define(['lay', 'layer', 'util'], function(exports){
|
||||
};
|
||||
|
||||
// 初始渲染 select 组件选项
|
||||
selects.each(function(index, select){
|
||||
selects.each(function(index, select) {
|
||||
var othis = $(this);
|
||||
var hasRender = othis.next('.'+CLASS);
|
||||
var disabled = this.disabled;
|
||||
@ -863,67 +874,114 @@ layui.define(['lay', 'layer', 'util'], function(exports){
|
||||
var selected = $(select.options[select.selectedIndex]); // 获取当前选中项
|
||||
var optionsFirst = select.options[0];
|
||||
|
||||
if (othis.closest('[lay-ignore]').length) return othis.show();
|
||||
// 为忽略渲染的 select 元素保持原生显示状态
|
||||
if (othis.closest('[lay-ignore]').length) {
|
||||
return othis.show();
|
||||
}
|
||||
|
||||
var isSearch = typeof othis.attr('lay-search') === 'string'
|
||||
var isCreatable = typeof othis.attr('lay-creatable') === 'string' && isSearch
|
||||
var isAppendTo = typeof othis.attr('lay-append-to') === 'string'
|
||||
var isSearch = typeof othis.attr('lay-search') === 'string';
|
||||
var isCreatable = typeof othis.attr('lay-creatable') === 'string' && isSearch;
|
||||
var isAppendTo = typeof othis.attr('lay-append-to') === 'string';
|
||||
var placeholder = optionsFirst
|
||||
? (optionsFirst.value ? TIPS : (optionsFirst.innerHTML || TIPS))
|
||||
? (optionsFirst.value ? TIPS : (optionsFirst.text || TIPS))
|
||||
: TIPS;
|
||||
|
||||
// 替代元素
|
||||
var reElem = $(['<div class="'+ (isSearch ? '' : 'layui-unselect ') + CLASS
|
||||
,(disabled ? ' layui-select-disabled' : '') + '"></div>'].join(''));
|
||||
// 用于替代 select 的外层容器
|
||||
var selectWrapper = (function() {
|
||||
var elem = $('<div class="'+ CLASS +'"></div>');
|
||||
if (!isSearch) {
|
||||
elem.addClass('layui-unselect');
|
||||
}
|
||||
if (disabled) {
|
||||
elem.addClass('layui-select-disabled');
|
||||
}
|
||||
return elem;
|
||||
})();
|
||||
|
||||
var triggerElem = $([
|
||||
'<div class="'+ TITLE +'">'
|
||||
,('<input type="text" placeholder="'+ util.escape($.trim(placeholder)) +'" '
|
||||
+('value="'+ util.escape($.trim(value ? selected.html() : '')) +'"') // 默认值
|
||||
+((!disabled && isSearch) ? '' : ' readonly') // 是否开启搜索
|
||||
+' class="layui-input'
|
||||
+(isSearch ? '' : ' layui-unselect')
|
||||
+ (disabled ? (' ' + DISABLED) : '') +'">') // 禁用状态
|
||||
,'<i class="layui-edge"></i>'
|
||||
,'</div>'].join(''));
|
||||
var inputElem = (function() {
|
||||
var elem = $('<input type="text" class="layui-input">');
|
||||
|
||||
var contentElem = $(['<dl class="layui-anim layui-anim-upbit'+ (othis.find('optgroup')[0] ? ' layui-select-group' : '') +'">'
|
||||
,function(options){
|
||||
// 设置占位符和默认值
|
||||
elem.prop('placeholder', placeholder);
|
||||
elem.val(value ? selected.prop('text') : '');
|
||||
|
||||
// 设置未开启搜索或禁用时的输入框只读状态
|
||||
if (!isSearch || disabled) {
|
||||
elem.prop('readonly', true);
|
||||
}
|
||||
|
||||
// 添加禁用状态时的 className
|
||||
if (disabled) {
|
||||
elem.addClass(DISABLED);
|
||||
}
|
||||
|
||||
return elem;
|
||||
})();
|
||||
|
||||
var titleElem = (function() {
|
||||
var elem = $('<div class="'+ TITLE +'"></div>');
|
||||
elem.append(inputElem);
|
||||
elem.append('<i class="layui-edge"></i>');
|
||||
return elem;
|
||||
})();
|
||||
|
||||
var contentElem = (function() {
|
||||
var elem = $('<dl class="layui-anim layui-anim-upbit"></dl>');
|
||||
if (othis.find('optgroup')[0]) {
|
||||
elem.addClass('layui-select-group');
|
||||
}
|
||||
var content = function() {
|
||||
var arr = [];
|
||||
layui.each(options, function(index, item){
|
||||
layui.each(othis.find('optgroup,option'), function(index, item) {
|
||||
var tagName = item.tagName.toLowerCase();
|
||||
|
||||
if(index === 0 && !item.value && tagName !== 'optgroup'){
|
||||
arr.push('<dd lay-value="" class="layui-select-tips">'+ $.trim(item.innerHTML || TIPS) +'</dd>');
|
||||
} else if(tagName === 'optgroup'){
|
||||
arr.push('<dt>'+ item.label +'</dt>');
|
||||
var dd = $('<dd lay-value=""></dd>');
|
||||
if (index === 0 && !item.value && tagName !== 'optgroup') {
|
||||
dd.addClass('layui-select-tips');
|
||||
dd.text(item.text || TIPS);
|
||||
arr.push(dd.prop('outerHTML'));
|
||||
} else if(tagName === 'optgroup') {
|
||||
var dt = $('<dt></dt>');
|
||||
dt.text(item.label);
|
||||
arr.push(dt.prop('outerHTML'));
|
||||
} else {
|
||||
arr.push('<dd lay-value="'+ util.escape(item.value) +'" class="'+ (value === item.value ? THIS : '') + (item.disabled ? (' '+DISABLED) : '') +'">'+ $.trim(item.innerHTML) +'</dd>');
|
||||
dd.attr('lay-value', item.value);
|
||||
if (value === item.value) {
|
||||
dd.addClass(THIS);
|
||||
}
|
||||
if (item.disabled) {
|
||||
dd.addClass(DISABLED);
|
||||
}
|
||||
dd.text(item.text);
|
||||
arr.push(dd.prop('outerHTML'));
|
||||
}
|
||||
});
|
||||
arr.length === 0 && arr.push('<dd lay-value="" class="'+ DISABLED +'">没有选项</dd>');
|
||||
if (arr.length === 0) {
|
||||
arr.push('<dd lay-value="" class="'+ DISABLED +'">None</dd>');
|
||||
}
|
||||
return arr.join('');
|
||||
}(othis.find('*')) +'</dl>'
|
||||
].join(''));
|
||||
}();
|
||||
elem.html(content);
|
||||
return elem;
|
||||
})();
|
||||
|
||||
// 如果已经渲染,则Rerender
|
||||
if(hasRender[0]){
|
||||
if(isAppendTo){
|
||||
// 如果已经渲染,则 Rerender
|
||||
if (hasRender[0]) {
|
||||
if (isAppendTo) {
|
||||
var panelWrapElem = hasRender.data(PANEL_ELEM_DATA);
|
||||
panelWrapElem && panelWrapElem.remove();
|
||||
}
|
||||
hasRender.remove();
|
||||
}
|
||||
if(isAppendTo){
|
||||
reElem.append(triggerElem);
|
||||
othis.after(reElem);
|
||||
if (isAppendTo) {
|
||||
selectWrapper.append(titleElem);
|
||||
othis.after(selectWrapper);
|
||||
var contentWrapElem = $('<div class="'+ CLASS + ' ' + PANEL_WRAP +'"></div>').append(contentElem);
|
||||
reElem.data(PANEL_ELEM_DATA, contentWrapElem); // 将面板元素对象记录在触发元素 data 中,重新渲染时需要清理旧面板元素
|
||||
events.call(this, contentWrapElem, triggerElem, disabled, isSearch, isCreatable, isAppendTo);
|
||||
}else{
|
||||
reElem.append(triggerElem).append(contentElem);
|
||||
othis.after(reElem);
|
||||
events.call(this, reElem, triggerElem, disabled, isSearch, isCreatable, isAppendTo);
|
||||
selectWrapper.data(PANEL_ELEM_DATA, contentWrapElem); // 将面板元素对象记录在触发元素 data 中,重新渲染时需要清理旧面板元素
|
||||
events.call(this, contentWrapElem, titleElem, disabled, isSearch, isCreatable, isAppendTo);
|
||||
} else {
|
||||
selectWrapper.append(titleElem).append(contentElem);
|
||||
othis.after(selectWrapper);
|
||||
events.call(this, selectWrapper, titleElem, disabled, isSearch, isCreatable, isAppendTo);
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -1469,5 +1527,3 @@ layui.define(['lay', 'layer', 'util'], function(exports){
|
||||
|
||||
exports(MOD_NAME, form);
|
||||
});
|
||||
|
||||
|
||||
|
@ -551,11 +551,12 @@
|
||||
/**
|
||||
* 基于 touch 事件的触摸滑动
|
||||
* @param {string | HTMLElement | JQuery} elem - HTML 元素
|
||||
* @param {{onTouchStart?: touchSwipeCallback, onTouchMove?: touchSwipeCallback, onTouchEnd?: touchSwipeCallback}} opts - 配置项
|
||||
* @param {{onTouchStart?: touchSwipeCallback; onTouchMove?: touchSwipeCallback; onTouchEnd?: touchSwipeCallback; preventDefault?: boolean}} opts - 配置项
|
||||
*/
|
||||
lay.touchSwipe = function(elem, opts){
|
||||
var options = opts
|
||||
var targetElem = lay(elem)[0];
|
||||
var preventDefault = 'preventDefault' in options ? options.preventDefault : true;
|
||||
|
||||
if(!targetElem || !lay.touchEventsSupported()) return;
|
||||
|
||||
@ -582,7 +583,9 @@
|
||||
}
|
||||
|
||||
var onMove = function(e){
|
||||
e.preventDefault();
|
||||
if(preventDefault){
|
||||
e.preventDefault();
|
||||
}
|
||||
state.pointerEnd.x = e.touches[0].clientX;
|
||||
state.pointerEnd.y = e.touches[0].clientY;
|
||||
state.distanceX = state.pointerStart.x - state.pointerEnd.x;
|
||||
@ -680,15 +683,16 @@
|
||||
}();
|
||||
|
||||
/**
|
||||
* 监听指定元素外部的点击
|
||||
* @param {HTMLElement} target - 被监听的元素
|
||||
* 绑定指定元素外部的点击事件
|
||||
* @param {HTMLElement} target - 响应事件的元素
|
||||
* @param {(e: Event) => void} handler - 事件触发时执行的函数
|
||||
* @param {object} [options] - 选项
|
||||
* @param {string} [options.event="pointerdown"] - 监听的事件类型
|
||||
* @param {HTMLElement | Window} [options.scope=document] - 监听范围
|
||||
* @param {Array<HTMLElement | string>} [options.ignore] - 忽略监听的元素或选择器字符串
|
||||
* @param {boolean} [options.capture=true] - 对内部事件侦听器使用捕获阶段
|
||||
* @returns {() => void} - 返回一个停止事件监听的函数
|
||||
* @param {string} [options.event="pointerdown"] - 事件类型
|
||||
* @param {HTMLElement | Window} [options.scope=document] - 事件范围
|
||||
* @param {Array<HTMLElement | string>} [options.ignore] - 忽略触发事件的元素或选择器字符串
|
||||
* @param {boolean} [options.capture=true] - 对内部事件 listener 使用捕获阶段
|
||||
* @param {boolean} [options.detectIframe] - 是否检测 iframe
|
||||
* @returns {() => void} - 返回一个停止事件响应的函数
|
||||
*/
|
||||
lay.onClickOutside = function(target, handler, options){
|
||||
options = options || {};
|
||||
@ -696,6 +700,7 @@
|
||||
var scopeTarget = options.scope || document;
|
||||
var ignore = options.ignore || [];
|
||||
var useCapture = 'capture' in options ? options.capture : true;
|
||||
var detectIframe = options.detectIframe;
|
||||
|
||||
var listener = function(event){
|
||||
var el = target;
|
||||
@ -764,13 +769,31 @@
|
||||
}
|
||||
}
|
||||
|
||||
return bindEventListener(
|
||||
scopeTarget,
|
||||
eventType,
|
||||
listener,
|
||||
lay.passiveSupported ? { passive: true, capture: useCapture } : useCapture
|
||||
);
|
||||
}
|
||||
var cleanup = [
|
||||
bindEventListener(
|
||||
scopeTarget,
|
||||
eventType,
|
||||
listener,
|
||||
lay.passiveSupported ? { passive: true, capture: useCapture } : useCapture
|
||||
),
|
||||
detectIframe && bindEventListener(window, 'blur', function(event){
|
||||
setTimeout(function(){
|
||||
if(document.activeElement && document.activeElement.tagName === 'IFRAME'
|
||||
&& target.contains && !target.contains(document.activeElement)
|
||||
){
|
||||
handler(event);
|
||||
}
|
||||
}, 0);
|
||||
})
|
||||
];
|
||||
|
||||
return function(){
|
||||
for(var i=0; i < cleanup.length; i++){
|
||||
cleanup[i] && cleanup[i]();
|
||||
}
|
||||
cleanup = null;
|
||||
}
|
||||
};
|
||||
|
||||
var hasOwnProperty = Object.prototype.hasOwnProperty;
|
||||
lay.hasOwn = function(obj, prop){
|
||||
|
@ -12,6 +12,7 @@
|
||||
var thisModule = function() {
|
||||
var that = this;
|
||||
var options = that.config;
|
||||
|
||||
return {
|
||||
config: options,
|
||||
|
||||
@ -76,9 +77,9 @@
|
||||
var vars = {
|
||||
// 字符转义
|
||||
escape: function(html) {
|
||||
var exp = /[<"'>]|&(?=#[a-zA-Z0-9]+)/g;
|
||||
var exp = /[<"'>]|&(?=#?[a-zA-Z0-9]+)/g;
|
||||
if (html === undefined || html === null) return '';
|
||||
html = ''+ html;
|
||||
html += '';
|
||||
if (!exp.test(html)) return html;
|
||||
return html.replace(exp, function(str) {
|
||||
return '&#'+ str.charCodeAt(0) + ';';
|
||||
@ -88,6 +89,12 @@
|
||||
|
||||
// 组件工具类方法
|
||||
var tools = {
|
||||
/**
|
||||
* 创建动态正则表达式
|
||||
* @param {string} str - 表达式字符
|
||||
* @param {string} mod - 修饰符
|
||||
* @returns {RegExp} - 正则表达式
|
||||
*/
|
||||
regex: function(str, mod) {
|
||||
return new RegExp(str, mod || 'g');
|
||||
},
|
||||
@ -102,14 +109,17 @@
|
||||
error: function(e, opts, error) {
|
||||
opts = opts || {};
|
||||
opts = Object.assign({
|
||||
debug: '',
|
||||
message: 'Laytpl '+ (opts.type || '') +'Error: ' + e
|
||||
errorContext: ''
|
||||
}, opts);
|
||||
|
||||
// 向控制台输出错误信息
|
||||
typeof console === 'object' && console.error(opts.message, '\n', opts.debug, '\n', opts);
|
||||
var message = 'Laytpl '+ (opts.type || '') +'Error: ' + e;
|
||||
var errorContext = opts.errorContext;
|
||||
|
||||
delete opts.errorContext;
|
||||
typeof console === 'object' && console.error(message, '\n', errorContext, '\n', opts);
|
||||
typeof error === 'function' && error(opts); // 执行错误回调
|
||||
return opts.message; // 向视图返回错误提示
|
||||
return message; // 向视图返回错误提示
|
||||
}
|
||||
};
|
||||
|
||||
@ -173,7 +183,7 @@
|
||||
} catch(e) {
|
||||
template = template || options.template;
|
||||
return tools.error(e, {
|
||||
debug: that.checkErrorArea(template, data),
|
||||
errorContext: that.extractErrorContext(template, data),
|
||||
template: template,
|
||||
type: 'Render'
|
||||
}, options.error);
|
||||
@ -196,12 +206,11 @@
|
||||
Class.prototype.compile = function(template) {
|
||||
var that = this;
|
||||
var options = that.config;
|
||||
var source = template;
|
||||
var openDelimiter = options.open;
|
||||
var closeDelimiter = options.close;
|
||||
var condense = options.condense;
|
||||
var regex = tools.regex;
|
||||
const placeholder = '\u2028'; // Unicode 行分隔符
|
||||
var placeholder = '\u2028'; // Unicode 行分隔符
|
||||
|
||||
// console.log('compile');
|
||||
|
||||
@ -339,9 +348,17 @@
|
||||
return tpl;
|
||||
};
|
||||
|
||||
// 创建模板编译器
|
||||
var createCompiler = that.createCompiler = function(template) {
|
||||
var codeBuilder = [
|
||||
/**
|
||||
* 创建模板编译器
|
||||
* 请注意: 开发者在使用模板语法时,需确保模板中的 JS 语句不来自于页面用户输入。
|
||||
* 即模板中的 JS 语句必须在页面开发者自身的可控范围内,否则请避免使用该模板解析。
|
||||
*/
|
||||
var createCompiler = that.createCompiler = function(template, builder) {
|
||||
builder = builder || createBuilder(template);
|
||||
return new Function('laytpl', 'return '+ builder)(that.vars);
|
||||
};
|
||||
var createBuilder = that.createBuilder = function(template, builder) {
|
||||
builder = builder || [
|
||||
'function(d){',
|
||||
'"use strict";',
|
||||
'var __laytpl__="",'+
|
||||
@ -359,13 +376,8 @@
|
||||
// 'return __laytpl__.join("");',
|
||||
'};'
|
||||
].join('\n');
|
||||
// console.log(codeBuilder);
|
||||
|
||||
/**
|
||||
* 请注意: 开发者在使用模板语法时,需确保模板中的 JS 语句不来自于页面用户输入。
|
||||
* 即模板中的 JS 语句必须在页面开发者自身的可控范围内,否则请避免使用该模板解析。
|
||||
*/
|
||||
return new Function('laytpl', 'return '+ codeBuilder)(that.vars);
|
||||
// console.log(builder);
|
||||
return builder;
|
||||
};
|
||||
|
||||
try {
|
||||
@ -374,8 +386,8 @@
|
||||
delete that.compilerCache;
|
||||
return function() {
|
||||
return tools.error(e, {
|
||||
debug: that.checkErrorArea(source),
|
||||
template: source,
|
||||
errorContext: that.extractErrorContext(template),
|
||||
template: template,
|
||||
type: 'Compile'
|
||||
}, options.error);
|
||||
};
|
||||
@ -383,61 +395,82 @@
|
||||
};
|
||||
|
||||
/**
|
||||
* 校验出错区域
|
||||
* @param {string} source - 原始模板
|
||||
* 获取模板出错行上下文
|
||||
* @param {string} template - 原始模板
|
||||
* @param {Object} data - 数据
|
||||
* @returns {string} 出错区域的模板碎片
|
||||
* @returns {string}
|
||||
*/
|
||||
Class.prototype.checkErrorArea = function(source, data) {
|
||||
Class.prototype.extractErrorContext = function(template, data) {
|
||||
var that = this;
|
||||
var srcs = source.split(/\n/g);
|
||||
var validLine = -1; // 有效行
|
||||
|
||||
// 逐行查找
|
||||
var i = 0;
|
||||
var str = '';
|
||||
var len = srcs.length;
|
||||
for (; i < len; i++) {
|
||||
str += srcs[i];
|
||||
try {
|
||||
data
|
||||
? that.createCompiler(str)(data)
|
||||
: new Function('"use strict";_laytpl__="'+ that.parse(str) +'";');
|
||||
validLine = i;
|
||||
} catch(e) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
// 给模板每行开头添加行号标记
|
||||
var lineNum = 1; // 行号
|
||||
var templateArr = template.split(/\r?\n/g);
|
||||
|
||||
// 呈现模板出错大致区域
|
||||
var errorArea = function(errLine) {
|
||||
var arr = [];
|
||||
var addLine = 3; // 错误行上下延伸的行数
|
||||
var i = 0;
|
||||
var len = srcs.length;
|
||||
template = template.replace(/(?=^)/gm, function() {
|
||||
return '/*LINE:'+ (lineNum++) +'*/';
|
||||
});
|
||||
|
||||
if (errLine < 0) errLine = 0;
|
||||
if (errLine > len - 1) errLine = len - 1;
|
||||
var builder = that.createBuilder(template);
|
||||
var builderArr = builder.split(/\r?\n/);
|
||||
var sourceURL = 'laytpl.builder.map';
|
||||
|
||||
i = errLine - addLine;
|
||||
if (i < 0) i = 0;
|
||||
// 模板出错行上下文
|
||||
var errorContext = function(errLineNum) {
|
||||
errLineNum = parseInt(errLineNum) - 1;
|
||||
|
||||
for (; i < len; i++) {
|
||||
arr.push((i == errLine ? '? ' : ' ') +(i + 1)+ '| '+ srcs[i]);
|
||||
if (i >= errLine + addLine) break;
|
||||
var arr = [''];
|
||||
var contextLines = 3; // 错误行上下延伸的行数
|
||||
var start = Math.max(0, errLineNum - contextLines);
|
||||
var end = Math.min(templateArr.length, errLineNum + contextLines);
|
||||
|
||||
for (; start <= end; start++) {
|
||||
arr.push(
|
||||
(start == errLineNum ? '? ' : ' ') +
|
||||
((start + 1) + '| ') +
|
||||
templateArr[start]
|
||||
);
|
||||
}
|
||||
|
||||
return '\n'+ arr.join('\n');
|
||||
return arr.join('\n') + '\n';
|
||||
};
|
||||
|
||||
return errorArea(validLine + 1); // 有效行的下一行即为出错行
|
||||
try {
|
||||
builder += ('\n//# sourceURL='+ sourceURL); // 添加映射
|
||||
var compiler = that.createCompiler(template, builder);
|
||||
if (data) compiler(data);
|
||||
} catch(e) {
|
||||
// 提取堆栈报错行号
|
||||
var stackLineNumRegxp = tools.regex(sourceURL.replace(/\./g, '\\.')+':(\\d+)', 'i');
|
||||
var stackLineNum = (e.stack.match(stackLineNumRegxp) || [])[1] || 0;
|
||||
|
||||
// 提取模板实际行号
|
||||
var extractErrLineNum = function(stackLineNum, isRecursion) {
|
||||
var lineNumRegxp = isRecursion ? /\/\*LINE:(\d+)\*\/[^*]*$/ : /\/\*LINE:(\d+)\*\//;
|
||||
var errLineNum = String(builderArr[stackLineNum - 1]).match(lineNumRegxp) || [];
|
||||
errLineNum = errLineNum[1];
|
||||
|
||||
// 若当前行未找到行号映射,则递归查找上一行
|
||||
if (!errLineNum && stackLineNum > 0) {
|
||||
return extractErrLineNum(stackLineNum - 1, true);
|
||||
}
|
||||
|
||||
return errLineNum;
|
||||
};
|
||||
|
||||
// 此处减去 anonymous 开头占用的 2 行
|
||||
var errLineNum = extractErrLineNum(stackLineNum - 2);
|
||||
|
||||
// 若未找到映射行号,则直接返回 SyntaxError 对象(通过 DevTools 映射源查看模板行号标记)
|
||||
return errLineNum ? errorContext(errLineNum) : e;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 创建实例
|
||||
* @param {string} template - 模板
|
||||
* @param {Object} options - 选项
|
||||
* @returns
|
||||
* @returns {Object}
|
||||
*/
|
||||
var laytpl = function(template, options) {
|
||||
var inst = new Class(template, options);
|
||||
@ -461,12 +494,12 @@
|
||||
};
|
||||
|
||||
// 输出接口
|
||||
typeof module === 'object' && typeof exports === 'object'
|
||||
? module.exports = laytpl // CommonJS
|
||||
: ( // 浏览器
|
||||
typeof layui === 'object' ? layui.define(function(exports) { // Layui
|
||||
exports(MOD_NAME, laytpl);
|
||||
}) : (
|
||||
typeof layui === 'object' ? layui.define(function(exports) { // Layui
|
||||
exports(MOD_NAME, laytpl);
|
||||
}) : (
|
||||
typeof module === 'object' && typeof exports === 'object'
|
||||
? module.exports = laytpl // CommonJS
|
||||
: (
|
||||
typeof define === 'function' && define.amd ? define(function() { // RequireJS
|
||||
return laytpl;
|
||||
}) : global.laytpl = laytpl // 单独引入
|
||||
|
@ -415,7 +415,8 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports) {
|
||||
return obj;
|
||||
}()).html(laytpl(TPL_MAIN, {
|
||||
open: '{{', // 标签符前缀
|
||||
close: '}}' // 标签符后缀
|
||||
close: '}}', // 标签符后缀
|
||||
tagStyle: 'legacy'
|
||||
}).render({
|
||||
data: options,
|
||||
index: that.index //索引
|
||||
|
@ -54,7 +54,7 @@ layui.define('component', function(exports) {
|
||||
|
||||
// 若 header 选项类型为数组
|
||||
if (layui.type(options.header) === 'array') {
|
||||
if (options.header.length === 0) return;
|
||||
// if (options.header.length === 0) return;
|
||||
|
||||
// 给任意元素绑定 tabs 切换功能
|
||||
if (typeof options.header[0] === 'string') {
|
||||
@ -183,6 +183,7 @@ layui.define('component', function(exports) {
|
||||
var container = that.getContainer();
|
||||
var newHeaderItem = that.renderHeaderItem(opts);
|
||||
var newBodyItem = that.renderBodyItem(opts);
|
||||
var data = that.data();
|
||||
|
||||
// 选项默认值
|
||||
opts = $.extend({
|
||||
@ -191,7 +192,6 @@ layui.define('component', function(exports) {
|
||||
|
||||
// 插入方式
|
||||
if (/(before|after)/.test(opts.mode)) { // 在活动标签前后插入
|
||||
var data = that.data();
|
||||
var hasOwnIndex = opts.hasOwnProperty('index');
|
||||
var headerItem = hasOwnIndex ? that.findHeaderItem(opts.index) : data.thisHeaderItem;
|
||||
var bodyItem = hasOwnIndex ? that.findBodyItem(opts.index) : data.thisHeaderItem;
|
||||
@ -214,8 +214,12 @@ layui.define('component', function(exports) {
|
||||
}
|
||||
|
||||
// 回调
|
||||
var params = that.data();
|
||||
typeof opts.done === 'function' && opts.done(params);
|
||||
typeof opts.done === 'function' && opts.done(
|
||||
$.extend(data, {
|
||||
headerItem: newHeaderItem,
|
||||
bodyItem: newBodyItem
|
||||
})
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -224,21 +228,20 @@ layui.define('component', function(exports) {
|
||||
* @param {boolean} force - 是否强制删除
|
||||
*/
|
||||
Class.prototype.close = function(thisHeaderItem, force) {
|
||||
if(!thisHeaderItem || !thisHeaderItem[0]) return;
|
||||
if (!thisHeaderItem || !thisHeaderItem[0]) return;
|
||||
|
||||
var that = this;
|
||||
var options = that.config;
|
||||
var layid = thisHeaderItem.attr('lay-id');
|
||||
var index = thisHeaderItem.index();
|
||||
|
||||
if (!thisHeaderItem[0]) return;
|
||||
|
||||
// 标签是否不可关闭
|
||||
if (thisHeaderItem.attr('lay-closable') === 'false') {
|
||||
return;
|
||||
}
|
||||
|
||||
// 当前标签相关数据
|
||||
var params = that.data();
|
||||
var data = that.data();
|
||||
|
||||
// 标签关闭前的事件。若非强制关闭,可则根据事件的返回结果决定是否关闭
|
||||
if (!force) {
|
||||
@ -246,8 +249,8 @@ layui.define('component', function(exports) {
|
||||
thisHeaderItem[0],
|
||||
component.CONST.MOD_NAME,
|
||||
'beforeClose('+ options.id +')',
|
||||
$.extend(params, {
|
||||
index: thisHeaderItem.index()
|
||||
$.extend(data, {
|
||||
index: index
|
||||
})
|
||||
);
|
||||
|
||||
@ -267,20 +270,20 @@ layui.define('component', function(exports) {
|
||||
}
|
||||
|
||||
// 移除元素
|
||||
that.findBodyItem(layid || index).remove();
|
||||
thisHeaderItem.remove();
|
||||
that.findBodyItem(index).remove();
|
||||
|
||||
that.roll('auto', index);
|
||||
|
||||
// 获取当前标签相关数据
|
||||
var params = that.data();
|
||||
var data = that.data();
|
||||
|
||||
// 标签关闭后的事件
|
||||
layui.event.call(
|
||||
params.thisHeaderItem[0],
|
||||
data.thisHeaderItem[0],
|
||||
component.CONST.MOD_NAME,
|
||||
'afterClose('+ options.id +')',
|
||||
params
|
||||
data
|
||||
);
|
||||
};
|
||||
|
||||
@ -300,14 +303,9 @@ layui.define('component', function(exports) {
|
||||
|
||||
index = index === undefined ? data.index : index;
|
||||
|
||||
// 将标签头 lay-closable 属性值同步到 body 项
|
||||
headers.each(function(i) {
|
||||
var othis = $(this);
|
||||
var closableAttr = othis.attr('lay-closable');
|
||||
if (closableAttr) {
|
||||
bodys.eq(i).attr('lay-closable', closableAttr);
|
||||
}
|
||||
});
|
||||
var headerItem = that.findHeaderItem(index);
|
||||
var bodyItem = that.findBodyItem(index);
|
||||
var itemIndex = headerItem.index();
|
||||
|
||||
// 若当前选中标签也允许关闭,则尝试寻找不可关闭的标签并将其选中
|
||||
if (data.thisHeaderItem.attr('lay-closable') !== 'false') {
|
||||
@ -319,34 +317,45 @@ layui.define('component', function(exports) {
|
||||
} else if(prevHeader[0]) {
|
||||
that.change(prevHeader, true);
|
||||
}
|
||||
} else if(index !== data.index) { // 自动切换到活动标签(功能可取消)
|
||||
that.change(that.findHeaderItem(index), true);
|
||||
} else if(index !== data.index) { // 自动切换到活动标签
|
||||
that.change(headerItem, true);
|
||||
}
|
||||
}
|
||||
|
||||
// 执行批量关闭标签
|
||||
if (mode === 'other') { // 关闭其他标签
|
||||
headers.eq(index).siblings(FILTER).remove();
|
||||
bodys.eq(index).siblings(FILTER).remove();
|
||||
} else if(mode === 'right') { // 关闭右侧标签
|
||||
headers.filter(':gt('+ index +')'+ FILTER).remove();
|
||||
bodys.filter(':gt('+ index +')'+ FILTER).remove();
|
||||
} else { // 关闭所有标签
|
||||
headers.filter(FILTER).remove();
|
||||
bodys.filter(FILTER).remove();
|
||||
}
|
||||
headers.each(function(i) {
|
||||
var $this = $(this);
|
||||
var layid = $this.attr('lay-id');
|
||||
var bodyItem = that.findBodyItem(layid || i);
|
||||
|
||||
// 标签是否不可关闭
|
||||
if ($this.attr('lay-closable') === 'false') {
|
||||
return;
|
||||
}
|
||||
|
||||
// 批量关闭方式
|
||||
var isCloseOther = mode === 'other' && i !== itemIndex; // 关闭其他标签
|
||||
var isCloseRight = mode === 'right' && i > itemIndex; // 关闭右侧标签
|
||||
var isCloseLeft = mode === 'left' && i < itemIndex; // 关闭左侧标签(不推荐)
|
||||
var isCloseAll = mode === 'all'; // 关闭所有标签
|
||||
|
||||
if (isCloseOther || isCloseRight || isCloseLeft || isCloseAll) {
|
||||
$this.remove();
|
||||
bodyItem.remove();
|
||||
}
|
||||
});
|
||||
|
||||
that.roll('auto');
|
||||
|
||||
// 回调
|
||||
var params = that.data();
|
||||
var data = that.data();
|
||||
|
||||
// 标签关闭后的事件
|
||||
layui.event.call(
|
||||
params.thisHeaderItem[0],
|
||||
data.thisHeaderItem[0],
|
||||
component.CONST.MOD_NAME,
|
||||
'afterClose('+ options.id +')',
|
||||
params
|
||||
data
|
||||
);
|
||||
};
|
||||
|
||||
@ -361,6 +370,7 @@ layui.define('component', function(exports) {
|
||||
|
||||
var that = this;
|
||||
var options = that.config;
|
||||
var layid = thisHeaderItem.attr('lay-id');
|
||||
var index = thisHeaderItem.index();
|
||||
var thatA = thisHeaderItem.find('a');
|
||||
// 是否存在跳转链接
|
||||
@ -374,7 +384,7 @@ layui.define('component', function(exports) {
|
||||
}
|
||||
|
||||
// 当前标签相关数据
|
||||
var params = that.data();
|
||||
var data = that.data();
|
||||
|
||||
// 标签关闭前的事件。若非强制关闭,可则根据事件的返回结果决定是否关闭
|
||||
if (!force) {
|
||||
@ -382,13 +392,13 @@ layui.define('component', function(exports) {
|
||||
thisHeaderItem[0],
|
||||
component.CONST.MOD_NAME,
|
||||
'beforeChange('+ options.id +')',
|
||||
$.extend(params, {
|
||||
$.extend(data, {
|
||||
from: {
|
||||
index: params.index,
|
||||
headerItem: params.thisHeaderItem
|
||||
index: data.index,
|
||||
headerItem: data.thisHeaderItem
|
||||
},
|
||||
to: {
|
||||
index: thisHeaderItem.index(),
|
||||
index: index,
|
||||
headerItem: thisHeaderItem
|
||||
}
|
||||
})
|
||||
@ -405,20 +415,20 @@ layui.define('component', function(exports) {
|
||||
.removeClass(component.CONST.CLASS_THIS);
|
||||
|
||||
// 执行标签内容切换
|
||||
that.findBodyItem(index).addClass(component.CONST.CLASS_SHOW)
|
||||
that.findBodyItem(layid || index).addClass(component.CONST.CLASS_SHOW)
|
||||
.siblings().removeClass(component.CONST.CLASS_SHOW);
|
||||
|
||||
that.roll('auto', index);
|
||||
|
||||
// 重新获取标签相关数据
|
||||
var params = that.data();
|
||||
var data = that.data();
|
||||
|
||||
// 标签切换后的事件
|
||||
layui.event.call(
|
||||
params.thisHeaderItem[0],
|
||||
data.thisHeaderItem[0],
|
||||
component.CONST.MOD_NAME,
|
||||
'afterChange('+ options.id +')',
|
||||
params
|
||||
data
|
||||
);
|
||||
};
|
||||
|
||||
@ -431,17 +441,8 @@ layui.define('component', function(exports) {
|
||||
var options = that.config;
|
||||
var headerItem = $(opts.headerItem || options.headerItem || '<li></li>');
|
||||
|
||||
headerItem.html(opts.title || 'New Tab');
|
||||
|
||||
// 追加属性
|
||||
layui.each(opts, function(key, value){
|
||||
if(/^(title|content|mode|done)$/.test(key)) return;
|
||||
headerItem.attr('lay-'+ key, value);
|
||||
});
|
||||
|
||||
// 追加标签关闭元素
|
||||
that.appendClose(headerItem, opts);
|
||||
|
||||
headerItem.html(opts.title || 'New Tab').attr('lay-id', opts.id);
|
||||
that.appendClose(headerItem, opts); // 追加标签关闭元素
|
||||
return headerItem;
|
||||
};
|
||||
|
||||
@ -450,11 +451,11 @@ layui.define('component', function(exports) {
|
||||
* @param {Object} opts - 标签项配置信息
|
||||
*/
|
||||
Class.prototype.renderBodyItem = function(opts) {
|
||||
var that = this
|
||||
var options = that.config
|
||||
var that = this;
|
||||
var options = that.config;
|
||||
var bodyItem = $(opts.bodyItem || options.bodyItem || '<div class="'+ component.CONST.ITEM +'"></div>');
|
||||
|
||||
bodyItem.html(opts.content || '');
|
||||
bodyItem.html(opts.content || '').attr('lay-id', opts.id);
|
||||
return bodyItem;
|
||||
};
|
||||
|
||||
@ -472,7 +473,11 @@ layui.define('component', function(exports) {
|
||||
opts = opts || {};
|
||||
|
||||
// 不可关闭项
|
||||
if (opts.closable === 'false' || headerItem.attr('lay-closable') === 'false') {
|
||||
if (opts.closable == false) {
|
||||
headerItem.attr('lay-closable', 'false');
|
||||
}
|
||||
|
||||
if (headerItem.attr('lay-closable') === 'false') {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -493,16 +498,15 @@ layui.define('component', function(exports) {
|
||||
var options = that.config;
|
||||
var container = that.getContainer();
|
||||
|
||||
// 是否开启关闭
|
||||
if (options.closable) {
|
||||
container.header.items.each(function() {
|
||||
that.appendClose($(this));
|
||||
});
|
||||
} else {
|
||||
container.header.items.each(function() {
|
||||
$(this).find('.'+ component.CONST.CLOSE).remove();
|
||||
});
|
||||
}
|
||||
container.header.items.each(function() {
|
||||
var $this = $(this);
|
||||
// 是否开启关闭
|
||||
if (options.closable) {
|
||||
that.appendClose($this);
|
||||
} else {
|
||||
$this.find('.'+ component.CONST.CLOSE).remove();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
@ -652,25 +656,41 @@ layui.define('component', function(exports) {
|
||||
};
|
||||
|
||||
/**
|
||||
* 根据 id 或 index 获取相关标签头部项
|
||||
* @param {number|string} index - 标签索引或 id
|
||||
* 获取标签头部项
|
||||
* @param {number|string} index - 标签索引或 lay-id
|
||||
*/
|
||||
Class.prototype.findHeaderItem = function(index) {
|
||||
if(!(
|
||||
typeof index === 'number'
|
||||
|| (typeof index === 'string' && index)
|
||||
)) return;
|
||||
var headerItems = this.getContainer().header.items;
|
||||
var item = headerItems.filter('[lay-id="'+ index +'"]');
|
||||
return item[0] ? item : headerItems.eq(index);
|
||||
var container = this.getContainer();
|
||||
var headerItems = container.header.items;
|
||||
|
||||
// 根据 lay-id 匹配
|
||||
if (typeof index === 'string') {
|
||||
return headerItems.filter('[lay-id="'+ index +'"]');
|
||||
}
|
||||
|
||||
return headerItems.eq(index);
|
||||
};
|
||||
|
||||
/**
|
||||
* 根据 index 获取相关标签内容项
|
||||
* @param {number} index - 标签索引
|
||||
* 获取标签内容项
|
||||
* @param {number|string} index - 标签索引或 lay-id
|
||||
*/
|
||||
Class.prototype.findBodyItem = function(index) {
|
||||
return this.getContainer().body.items.eq(index);
|
||||
var container = this.getContainer();
|
||||
var bodyItems = container.body.items;
|
||||
|
||||
// 根据 lay-id 匹配
|
||||
if (typeof index === 'string') {
|
||||
var bodyItem = bodyItems.filter('[lay-id="'+ index +'"]');
|
||||
return bodyItem[0] ? bodyItem : function() {
|
||||
// 若未匹配到 lay-id 对应内容项,则通过对应头部项的索引匹配内容项
|
||||
var headerItems = container.header.items;
|
||||
var headerItem = headerItems.filter('[lay-id="'+ index +'"]');
|
||||
return bodyItems.eq(headerItem.index());
|
||||
}();
|
||||
}
|
||||
|
||||
return bodyItems.eq(index);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -687,11 +707,11 @@ layui.define('component', function(exports) {
|
||||
return {
|
||||
options: options, // 标签配置信息
|
||||
container: container, // 标签容器的相关元素
|
||||
thisHeaderItem: thisHeaderItem, // 当前标签头部项
|
||||
thisBodyItem: that.findBodyItem(index), // 当前标签内容项
|
||||
index: index, // 当前标签索引
|
||||
length: container.header.items.length // 当前标签数
|
||||
}
|
||||
thisHeaderItem: thisHeaderItem, // 当前活动标签头部项
|
||||
thisBodyItem: that.findBodyItem(index), // 当前活动标签内容项
|
||||
index: index, // 当前活动标签索引
|
||||
length: container.header.items.length // 标签数量
|
||||
};
|
||||
};
|
||||
|
||||
// 扩展组件接口
|
||||
@ -715,8 +735,11 @@ layui.define('component', function(exports) {
|
||||
*/
|
||||
close: function(id, index, force) {
|
||||
var that = component.getInst(id);
|
||||
if(!that) return;
|
||||
if(index === undefined) index = that.data().index; // index 若不传,则表示关闭当前标签
|
||||
if (!that) return;
|
||||
// index 若不传,则表示关闭当前标签
|
||||
if (index === undefined) {
|
||||
index = that.data().index;
|
||||
}
|
||||
that.close(that.findHeaderItem(index), force);
|
||||
},
|
||||
|
||||
@ -726,10 +749,10 @@ layui.define('component', function(exports) {
|
||||
* @param {('other'|'right'|'all')} [mode="all"] - 关闭方式
|
||||
* @param {number} index - 活动标签的索引,默认取当前选中标签的索引。一般用于标签右键事件
|
||||
*/
|
||||
closeMult: function(id, mode, index, force) {
|
||||
closeMult: function(id, mode, index) {
|
||||
var that = component.getInst(id);
|
||||
if(!that) return;
|
||||
that.closeMult(mode, index, force);
|
||||
that.closeMult(mode, index);
|
||||
},
|
||||
|
||||
/**
|
||||
@ -755,7 +778,7 @@ layui.define('component', function(exports) {
|
||||
/**
|
||||
* 获取标签指定头部项
|
||||
* @param {string} id - 渲染时的实例 ID
|
||||
* @param {number} index - 标签索引
|
||||
* @param {number} index - 标签索引或 lay-id 值
|
||||
* @returns
|
||||
*/
|
||||
getHeaderItem: function(id, index) {
|
||||
@ -767,7 +790,7 @@ layui.define('component', function(exports) {
|
||||
/**
|
||||
* 获取标签指定内容项
|
||||
* @param {string} id - 渲染时的实例 ID
|
||||
* @param {number} index - 标签索引
|
||||
* @param {number} index - 标签索引或 lay-id 值
|
||||
* @returns
|
||||
*/
|
||||
getBodyItem: function(id, index) {
|
||||
|
@ -145,7 +145,8 @@ layui.define(['laytpl', 'form'], function(exports) {
|
||||
// 解析模板
|
||||
var thisElem = that.elem = $(laytpl(TPL_MAIN, {
|
||||
open: '{{', // 标签符前缀
|
||||
close: '}}' // 标签符后缀
|
||||
close: '}}', // 标签符后缀
|
||||
tagStyle: 'legacy'
|
||||
}).render({
|
||||
data: options,
|
||||
index: that.index // 索引
|
||||
|
@ -590,7 +590,7 @@ layui.define(['table'], function (exports) {
|
||||
})()
|
||||
|
||||
// 优化参数,添加一个 getNodeByIndex 方法 只传 表格id 和行 dataIndex 分几步优化 todo
|
||||
var expandNode = function (treeNode, expandFlag, sonSign, focus, callbackFlag) {
|
||||
var expandNode = function (treeNode, expandFlag, sonSign, focus, callbackFlag, done) {
|
||||
// treeNode // 需要展开的节点
|
||||
var trElem = treeNode.trElem;
|
||||
var tableViewElem = treeNode.tableViewElem || trElem.closest(ELEM_VIEW);
|
||||
@ -658,7 +658,7 @@ layui.define(['table'], function (exports) {
|
||||
tableViewElem: tableViewElem,
|
||||
tableId: tableId,
|
||||
options: options,
|
||||
}, expandFlag, sonSign, focus, callbackFlag);
|
||||
}, expandFlag, sonSign, focus, callbackFlag, done);
|
||||
} else if (item1[LAY_EXPAND]) { // 初始化级联展开
|
||||
expandNode({
|
||||
dataIndex: item1[LAY_DATA_INDEX],
|
||||
@ -666,7 +666,7 @@ layui.define(['table'], function (exports) {
|
||||
tableViewElem: tableViewElem,
|
||||
tableId: tableId,
|
||||
options: options,
|
||||
}, true);
|
||||
}, true, undefined, undefined, undefined, done);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
@ -681,7 +681,7 @@ layui.define(['table'], function (exports) {
|
||||
trData[LAY_ASYNC_STATUS] = 'success';
|
||||
trData[customName.children] = data;
|
||||
treeTableThat.initData(trData[customName.children], trData[LAY_DATA_INDEX])
|
||||
expandNode(treeNode, true, isToggle ? false : sonSign, focus, callbackFlag);
|
||||
expandNode(treeNode, true, isToggle ? false : sonSign, focus, callbackFlag, done);
|
||||
}
|
||||
|
||||
var format = asyncSetting.format; // 自定义数据返回方法
|
||||
@ -804,7 +804,7 @@ layui.define(['table'], function (exports) {
|
||||
tableViewElem: tableViewElem,
|
||||
tableId: tableId,
|
||||
options: options,
|
||||
}, expandFlag, sonSign, focus, callbackFlag);
|
||||
}, expandFlag, sonSign, focus, callbackFlag, done);
|
||||
})
|
||||
}
|
||||
}
|
||||
@ -820,7 +820,7 @@ layui.define(['table'], function (exports) {
|
||||
tableViewElem: tableViewElem,
|
||||
tableId: tableId,
|
||||
options: options,
|
||||
}, expandFlag, sonSign, focus, callbackFlag);
|
||||
}, expandFlag, sonSign, focus, callbackFlag, done);
|
||||
});
|
||||
tableViewElem.find(childNodes.map(function (value, index, array) { // 只隐藏直接子节点,其他由递归的处理
|
||||
return 'tr[lay-data-index="' + value[LAY_DATA_INDEX] + '"]'
|
||||
@ -843,6 +843,10 @@ layui.define(['table'], function (exports) {
|
||||
layui.type(onExpand) === 'function' && onExpand(tableId, trData, trExpand);
|
||||
}
|
||||
|
||||
if(layui.type(done) === 'function' && trData[LAY_ASYNC_STATUS] !== 'loading'){
|
||||
done(tableId, trData, trExpand);
|
||||
}
|
||||
|
||||
return retValue;
|
||||
}
|
||||
|
||||
@ -853,7 +857,8 @@ layui.define(['table'], function (exports) {
|
||||
* @param {Number|String} opts.index 展开行的数据下标
|
||||
* @param {Boolean} [opts.expandFlag] 展开、关闭、切换
|
||||
* @param {Boolean} [opts.inherit] 是否级联子节点
|
||||
* @param {Boolean} [opts.callbackFlag] 是否触发事件
|
||||
* @param {Boolean} [opts.callbackFlag] 是否触发 tree.callback 事件
|
||||
* @param {Boolean} [opts.done] 节点操作完成后的回调函数
|
||||
* @return [{Boolean}] 状态结果
|
||||
* */
|
||||
treeTable.expandNode = function (id, opts) {
|
||||
@ -871,7 +876,7 @@ layui.define(['table'], function (exports) {
|
||||
var tableViewElem = options.elem.next();
|
||||
return expandNode({
|
||||
trElem: tableViewElem.find('tr[lay-data-index="' + index + '"]').first()
|
||||
}, expandFlag, sonSign, null, callbackFlag)
|
||||
}, expandFlag, sonSign, null, callbackFlag, opts.done)
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -348,25 +348,24 @@ layui.define('jquery', function(exports) {
|
||||
|
||||
// 转义 html
|
||||
escape: function(html){
|
||||
var exp = /[<"'>]|&(?=#[a-zA-Z0-9]+)/g;
|
||||
if(html === undefined || html === null) return '';
|
||||
var exp = /[<"'>]|&(?=#?[a-zA-Z0-9]+)/g;
|
||||
if (html === undefined || html === null) return '';
|
||||
|
||||
html += '';
|
||||
if(!exp.test(html)) return html;
|
||||
if (!exp.test(html)) return html;
|
||||
|
||||
return html.replace(/&(?!#?[a-zA-Z0-9]+;)/g, '&')
|
||||
return html.replace(/&(?=#?[a-zA-Z0-9]+;?)/g, '&')
|
||||
.replace(/</g, '<').replace(/>/g, '>')
|
||||
.replace(/'/g, ''').replace(/"/g, '"');
|
||||
},
|
||||
|
||||
// 还原转义的 html
|
||||
unescape: function(html){
|
||||
if(html === undefined || html === null) html = '';
|
||||
html += '';
|
||||
if (html === undefined || html === null) return '';
|
||||
|
||||
return html.replace(/\&/g, '&')
|
||||
.replace(/\</g, '<').replace(/\>/g, '>')
|
||||
.replace(/\'/g, '\'').replace(/\"/g, '"');
|
||||
return String(html).replace(/\"/g, '"').replace(/\'/g, '\'')
|
||||
.replace(/\>/g, '>').replace(/\</g, '<')
|
||||
.replace(/\&/g, '&');
|
||||
},
|
||||
|
||||
// 打开新窗口
|
||||
|
Loading…
Reference in New Issue
Block a user