发布 v2.9.0-beta.1

pull/1440/head v2.9.0-beta.1
贤心 2023-11-20 09:04:26 +08:00 committed by GitHub
commit 0968676e1f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
27 changed files with 575 additions and 507 deletions

4
.gitignore vendored
View File

@ -15,11 +15,11 @@ Thumbs.db
.nojekyll
.project
.settings/
.npmignore
node_modules/
_site/
.git/
package-lock.json
# Published folders
release/
v/
package-lock.json

View File

@ -15,11 +15,11 @@
<a href="https://www.npmjs.com/package/layui">
<img src="https://img.shields.io/github/license/layui/layui" alt="License">
</a>
<a href="https://github.com/layui/layui/blob/master/dist/css/layui.css">
<img src="https://img.badgesize.io/layui/layui/master/dist/css/layui.css?compression=brotli&label=CSS%20Brotli%20size" alt="CSS Brotli size">
<a href="https://github.com/layui/layui/blob/2.x/dist/css/layui.css">
<img src="https://img.badgesize.io/layui/layui/2.x/dist/css/layui.css?compression=brotli&label=CSS%20Brotli%20size" alt="CSS Brotli size">
</a>
<a href="https://github.com/layui/layui/blob/master/dist/layui.js">
<img src="https://img.badgesize.io/layui/layui/master/dist/layui.js?compression=brotli&label=JS%20Brotli%20size" alt="JS Brotli size">
<a href="https://github.com/layui/layui/blob/2.x/dist/layui.js">
<img src="https://img.badgesize.io/layui/layui/2.x/dist/layui.js?compression=brotli&label=JS%20Brotli%20size" alt="JS Brotli size">
</a>
</p>
@ -57,7 +57,7 @@ Layui 是一套开源免费的 Web UI 组件库,采用自身轻量级模块化
## 使用文档
[**最新文档**](https://layui.dev)
[**当前版本文档**](https://layui.dev/docs/2/)
## 项目参与

2
dist/layui.js vendored

File diff suppressed because one or more lines are too long

2
dist/layui.js.map vendored

File diff suppressed because one or more lines are too long

View File

@ -2,7 +2,7 @@
## 文档预览
- [最新文档](https://layui.dev)
- [当前版本文档](https://layui.dev/docs/2/)
- [2.7 文档](https://layui.dev/2.7/)
## 目录规范

View File

@ -98,6 +98,8 @@ compile.render(data, callback); // 模板渲染
{{- d.include("/laytpl/detail/options.md") }}
</div>
> ### 注意
> 开发者在使用模板语法时,需确保模板中的 JS 语句不来自于页面用户输入,即必须在页面开发者自身的可控范围内,否则请避免使用该模板引擎。
<h2 id="config" lay-toc="{level: 2}">属性配置</h2>

View File

@ -120,8 +120,8 @@
</div>
- `height: 315` 设置固定高度
- `height: 'full-30'` 设置自适应高度。这是一个特定的语法格式:`full` 表示铺满;后面的数字表示当前 table 之外的元素占用的高度,如:表格头部到页面最顶部*加*表格底部距离页面最底部的“距离和”
- `height: '#id-30'` 设置相对父元素的高度自适应,其中 `#id` 即父元素的 ID 选择器,其计算原理和上述 `full` 相同。
- `height: 'full-30'` 设置相对可视屏幕的高度铺满。这是一个特定的语法格式:`full` 表示铺满;后面的数字表示当前 table 之外的元素占用的高度,如:表格头部到页面最顶部*加*表格底部距离页面最底部的“距离和”
- `height: '#id-30'` 设置相对父元素的高度铺满,其中 `#id` 即父元素的 ID 选择器,其计算原理和上述 `full` 相同。
</td>
<td>number<br>string</td>

View File

@ -70,15 +70,16 @@ layui.use(function(){
var options = this;
// 获取当前行数据
table.getRowData = function(elem){
table.getRowData = function(tableId, elem){
var index = $(elem).closest('tr').data('index');
return table.cache[options.id][index] || {};
return table.cache[tableId][index] || {};
};
// 原生 select 事件
$('.select-demo-primary').on('change', function(){
var tableViewElem = this.elem.next();
tableViewElem.off('change').on('change', '.select-demo-primary', function(){
var value = this.value; // 获取选中项 value
var data = table.getRowData(this); // 获取当前行数据(如 id 等字段,以作为数据修改的索引)
var data = table.getRowData(options.id, this); // 获取当前行数据(如 id 等字段,以作为数据修改的索引)
// 更新数据中对应的字段
data.city = value;
@ -92,7 +93,7 @@ layui.use(function(){
console.log(obj); // 获取选中项数据
// 获取当前行数据(如 id 等字段,以作为数据修改的索引)
var data = table.getRowData(obj.elem);
var data = table.getRowData(options.id, obj.elem);
// 更新数据中对应的字段
data.city = value;
@ -115,7 +116,7 @@ layui.use(function(){
id: 102
}],
click: function(obj){
var data = table.getRowData(this.elem); // 获取当前行数据(如 id 等字段,以作为数据修改的索引)
var data = table.getRowData(options.id, this.elem); // 获取当前行数据(如 id 等字段,以作为数据修改的索引)
this.elem.find('span').html(obj.title);
@ -131,7 +132,7 @@ layui.use(function(){
laydate.render({
elem: '.laydate-demo',
done: function(value, date, endDate){
var data = table.getRowData(this.elem); // 获取当前行数据(如 id 等字段,以作为数据修改的索引)
var data = table.getRowData(options.id, this.elem); // 获取当前行数据(如 id 等字段,以作为数据修改的索引)
// 更新数据中对应的字段
data.date = value;
@ -145,7 +146,7 @@ layui.use(function(){
colorpicker.render({
elem: '.colorpicker-demo',
done: function(value){
var data = table.getRowData(this.elem); // 获取当前行数据(如 id 等字段,以作为数据修改的索引)
var data = table.getRowData(options.id, this.elem); // 获取当前行数据(如 id 等字段,以作为数据修改的索引)
// 更新数据中对应的字段
data.color = value;

View File

@ -204,18 +204,27 @@ util.openWin({
<h3 id="on" class="ws-anchor ws-bold">批量事件处理</h3>
`util.on(attr, obj, eventType);`
`util.on(attr, events, options);`
- 参数 `attr` : 触发事件的元素属性名
- 参数 `obj` : 事件回调函数集合
- 参数 `eventType` : 事件类型。默认 `click`
| 参数 | 描述 | 类型 | 默认值 |
| --- | --- | --- | --- |
| attr | 触发事件的元素属性名。可省略<sup>2.9+</sup> | `string` | `lay-on` |
| events | 事件集合。包含 `attr` 对应的属性值和事件回调函数的键值对 | `object` | - |
| options <sup>2.9+</sup> | 参数的更多选项。详见下表。 | `object` | - |
参数 `options` 可选项:
| options | 描述 | 类型 | 默认值 |
| --- | --- | --- | --- |
| elem | 触发事件的委托元素 | string \| HTMLElement \| jQuery | - |
| trigger | 事件触发的方式 | string | `click` |
<pre class="layui-code" lay-options="{preview: true, codeStyle: 'height: 535px;', layout: ['code', 'preview'], tools: ['full']}">
<textarea>
<div class="layui-btn-container">
<button class="layui-btn" lay-on="e1">事件 1</button>
<button class="layui-btn" lay-on="e2">事件 2</button>
<button class="layui-btn" lay-on="e3">事件 3</button>
<button class="layui-btn" lay-active="e3">事件 3</button>
</div>
<!-- import layui -->
@ -223,19 +232,26 @@ util.openWin({
layui.use('util', function(){
var util = layui.util;
// 处理属性 为 lay-on 的所有元素事件
util.on('lay-on', {
// 2.9+ 版本可省略 attr 参数,默认读取 lay-on
util.on({
e1: function(){
console.log(this); // 当前触发事件的 DOM 对象
console.log(this); // 当前触发事件的 DOM 元素
layer.msg('触发了事件 1');
},
e2: function(){
layer.msg('触发了事件 2');
},
e3: function(){
layer.msg('触发了事件 3');
}
});
// 自定义:触发事件的元素属性名、触发事件的方式
util.on('lay-active', {
e3: layui.throttle(function(othis) {
console.log(this);
layer.tips(othis.html(), this);
}, 3000) // 3s 内不重复执行
}, {
trigger: 'mouseenter' // 鼠标移入时触发事件
});
});
</script>
</textarea>

View File

@ -5,12 +5,34 @@ toc: true
# 更新日志
<h2 class="layui-hide" lay-toc="{href: '/docs/2/versions.html', title: '2.8.x', hot: true}">
2.8.x
> 导读:📑 [Layui 2.8+ 《升级指南》](/notes/2.8/upgrade-guide.html) · 📑 [Layui 新版文档站上线初衷](/notes/2.8/news.html)
<h2 id="2.9.x" lay-toc="{title: '2.9.x'}"></h2>
<h2 id="2.9.0" class="ws-anchor">
2.9.0-beta.1
<span class="layui-badge-rim">预览版</span>
<span class="layui-badge-rim">2023-11-20</span>
</h2>
> 导读:📑 [Layui 2.8 《升级指南》](/notes/2.8/upgrade-guide.html) · 📑 [Layui 新版文档站上线初衷](/notes/2.8/news.html)
`2.9.x``2.8.18` 向下兼容,可覆盖升级。
- #### table
- 修复 `complete` 属性导致 `$.ajaxSetup()``complete` 失效的问题 [#1423](https://github.com/layui/layui/pull/1423)
- 修复 单元格展开再收缩后,当列通过拖拽改变过宽度,列存在概率性错位的问题 [#28347fc](https://github.com/layui/layui/commit/28347fcf8f97912d6c90d81931f9ed5527dc3627)
- 修复 合计行单元格展开异常的问题 [#I8FH3K](https://gitee.com/layui/layui/issues/I8FH3K)
- 优化 `height` 属性高度铺满语法中不支持浮点型数值的问题 [#I8DSPH](https://gitee.com/layui/layui/issues/I8DSPH)
- 优化 关闭单元格多行展开状态后,悬停状态样式未移除的问题 [#1425](https://github.com/layui/layui/pull/1425)
- #### util
- 优化 `util.on()` 方法,提升参数的灵活性和代码的可读性 [#d74abb4](https://github.com/layui/layui/commit/d74abb453cb45ea5d2eb69f0ed7250caf0ab0088)
- #### 其他
- 优化 `lay.clipboard.writeText()` 逻辑,以适配无写入权限时的场景 [#1421](https://github.com/layui/layui/pull/1421)
### 下载: [layui-v2.9.0-beta.1.zip](https://gitee.com/layui/layui/attach_files/1587087/download)
---
<h2 id="2.8.x" lay-toc="{title: '2.8.x'}"></h2>
<h2 id="2.8.18" class="ws-anchor">
2.8.18

View File

@ -13,11 +13,10 @@ body{padding: 50px;}
</head>
<body>
<button class="layui-btn" lay-active="e1">事件1</button>
<button class="layui-btn" lay-active="e2">事件2</button>
<button class="layui-btn" lay-active="e3">事件3</button>
<button class="layui-btn" lay-active2="e4">事件4</button>
<button class="layui-btn" lay-on="e1">事件1</button>
<button class="layui-btn" lay-on="e2">事件2</button>
<button class="layui-btn" lay-on="e3">事件3</button>
<button class="layui-btn" lay-active="e4">事件4</button>
<hr>
@ -43,10 +42,11 @@ body{padding: 50px;}
<script src="../src/layui.js"></script>
<script>
layui.use(['util', 'layer'], function(){
layui.use(['lay', 'util', 'layer'], function(){
var $ = layui.$;
var util = layui.util;
var layer = layui.layer;
var lay = layui.lay;
// 固定块
util.fixbar({
@ -90,46 +90,58 @@ layui.use(['util', 'layer'], function(){
}
});
//倒计时
var endTime = new Date(2099,1,1).getTime() //假设为结束日期
,serverTime = new Date().getTime(); //假设为当前服务器时间,这里采用的是本地时间,实际使用一般是取服务端的
util.countdown(endTime, serverTime, function(date, serverTime, timer){
var str = date[0] + '天' + date[1] + '时' + date[2] + '分' + date[3] + '秒';
$('#test').html('距离2099年1月1日还有'+ str);
// 批量处理事件
util.on({
e1: function(othis){
alert(othis.html())
},
e2: function(othis){
alert(othis.html())
}
});
// 事件集的替换和增加
util.on({
e1: function(othis){ // 重置事件 e1
alert(othis.html() + ' - replace')
},
e3: function(othis){ // 增加事件 e3
alert(othis.html())
}
});
// 自定义触发事件的元素属性名、自定义触发事件的方式
util.on('lay-active', {
e4: layui.throttle(function(othis) {
layer.tips(othis.html(), this);
}, 3000) // 3s 内不重复执行
}, {
trigger: 'mouseenter'
});
// 倒计时
var countdown = util.countdown({
date: '2099-12-31 00:00:00', // 目标时间值
now: new Date(), // 当前时间,一般为服务器时间,此处以本地时间为例
ready: function(){ // 初始操作
clearTimeout(util.countdown.timer); // 清除旧定时器,防止多次渲染时重复执行。实际使用时不常用
},
clock: function(obj, inst){ // 计时中
var str = [obj.d,'天',obj.h,'时',obj.m,'分',obj.s,'秒'].join(' ');
lay('#test').html(str);
util.countdown.timer = inst.timer; // 记录当前定时器,以便在重复渲染时清除。实际使用时不常用
},
done: function(obj, inst){ // 计时完成
layer.msg('Time is up');
}
});
// 某个时间在当前时间的多久前
var str = util.timeAgo(new Date(2017,7,15,2,58,0));
$('#test1').html('示例写于:'+ str);
//处理属性 为 lay-active 的所有元素事件
util.event('lay-active', {
e1: function(othis){
alert(othis.html())
}
,e2: function(othis){
alert(othis.html())
}
,e3: function(othis){
alert(othis.html())
}
});
//测试是否重复绑定
util.event('lay-active', {
e1: function(othis){
alert(othis.html() + '新事件')
}
});
//测试绑定新事件
util.event('lay-active2', {
e4: function(othis){
alert(othis.html())
}
});
// 转换日期格式
var timer = null
var toDateString = function (format) {

View File

@ -1,45 +1,46 @@
const pkg = require('./package.json');
const path = require('path');
const gulp = require('gulp');
const uglify = require('gulp-uglify');
const cleanCSS = require('gulp-clean-css');
const concat = require('gulp-concat');
const rename = require('gulp-rename');
const replace = require('gulp-replace');
const header = require('gulp-header');
const footer = require('gulp-footer');
const sourcemaps = require('gulp-sourcemaps');
const zip = require('gulp-zip');
const del = require('del');
const minimist = require('minimist');
const yargs = require('yargs');
const pkg = require('./package.json');
// 基础配置
const config = {
// 注释
// 头部注释
comment: [
'/** v<%= pkg.version %> | <%= pkg.license %> Licensed */<%= js %>',
{pkg: pkg, js: ';'}
],
// 模块
// 全部模块
modules: 'lay,laytpl,laypage,laydate,jquery,layer,util,dropdown,slider,colorpicker,element,upload,form,table,treeTable,tree,transfer,carousel,rate,flow,code'
};
// 获取参数
const argv = require('minimist')(process.argv.slice(2), {
const argv = minimist(process.argv.slice(2), {
default: {
version: pkg.version
}
});
// 前置目录
const dir = {
rls: './release/zip/layui-v' + pkg.version
};
const rlsFileName = `${pkg.name}-v${pkg.version}`; // 发行文件名
const rlsDest = `./release/zip/${rlsFileName}/${pkg.name}`; // 发行目标路径
const rlsDirname = path.dirname(rlsDest); // 发行目录名
// 输出目录
const dest = ({
dist: './dist',
rls: dir.rls + '/layui'
}[argv.dest || 'dist'] || argv.dest) + (argv.vs ? '/'+ pkg.version : '');
// 复制目标路径
const copyDest = argv.dest
? path.join(argv.dest, (argv.vs ? '/' + pkg.version : ''))
: rlsDest;
// 打包目标路径
const dest = './dist';
// js
const js = () => {
@ -56,7 +57,7 @@ const js = () => {
}))
.pipe(concat('layui.js', {newLine: ''}))
.pipe(header.apply(null, config.comment))
.pipe(sourcemaps.write(''))
.pipe(sourcemaps.write('.'))
.pipe(gulp.dest(dest));
};
@ -71,7 +72,7 @@ const css = () => {
compatibility: 'ie8'
}))
.pipe(concat('layui.css', {newLine: ''}))
.pipe(sourcemaps.write(''))
.pipe(sourcemaps.write('.'))
.pipe(gulp.dest(dest +'/css'));
};
@ -82,84 +83,51 @@ const files = () => {
.pipe(gulp.dest(dest));
};
// cp
const cp = () => {
const basePath = './dist/**/*';
// clean
const clean = () => {
return del([dest]);
};
// 默认任务
exports.default = gulp.series(clean, gulp.parallel(js, css, files));
// 复制 dist 目录到指定路径
exports.cp = gulp.series(() => del(copyDest), () => {
const src = `${dest}/**/*`;
// 复制 css js
gulp.src(`${basePath}.{css,js}`)
gulp.src(`${src}.{css,js}`)
.pipe(replace(/\n\/(\*|\/)\#[\s\S]+$/, '')) // 过滤 css 和 js 的 map 特定注释
.pipe(gulp.dest(dest));
.pipe(gulp.dest(copyDest));
// 复制其他文件
return gulp.src([
basePath,
`!${basePath}.{css,js,map}` // 过滤 map 文件
src,
`!${src}.{css,js,map}` // 过滤 map 文件
])
.pipe(replace(/\n\/(\*|\/)\#[\s\S]+$/, '')) // 过滤 css 和 js 的 map 特定注释
.pipe(gulp.dest(dest));
};
.pipe(gulp.dest(copyDest));
});
// release
const rls = () => {
return gulp.src('./release/doc/**/*')
// 发行
exports.release = gulp.series(
() => del([rlsDirname]), // 清理发行目录
() => { // 生成说明
return gulp.src('./release/introduce/**/*')
.pipe(replace(/[^'"]+(\/layui\.css)/, 'layui/css$1')) // 替换 css 引入路径中的本地 path
.pipe(replace(/[^'"]+(\/layui\.js)/, 'layui$1')) // 替换 js 引入路径中的本地 path
.pipe(gulp.dest(dir.rls));
};
// clean
const clean = cb => {
return del([dest], {
force: true
});
};
const cleanRLS = cb => {
return del([dir.rls]);
};
// Define all task
exports.js = js;
exports.css = css;
exports.files = files;
exports.default = gulp.series(clean, gulp.parallel(js, css, files)); // default task
exports.cp = gulp.series(clean, cp);
exports.rls = gulp.series(cleanRLS, rls); // release task
// layer task
exports.layer = () => { // gulp layer
let dest = './release/layer';
gulp.src('./src/css/modules/layer.css')
.pipe(gulp.dest(dest + '/src'));
return gulp.src('./src/modules/layer.js')
.pipe(gulp.dest(dest + '/src'));
};
// laydate task
exports.laydate = () => { // gulp laydate
let dest = './release/laydate/'; // 发行目录
let comment = [ // 注释
'\n/** \n * <%= title %> \n * <%= license %> Licensed \n */ \n\n'
,{title: 'laydate 日期与时间组件(单独版)', license: 'MIT'}
];
// css
gulp.src('./src/css/modules/laydate.css')
.pipe(gulp.dest(dest + 'src'));
// js
return gulp.src(['./src/layui.js', './src/modules/{lay,laydate}.js'])
.pipe(replace('win.layui =', 'var layui =')) // 将 layui 替换为局部变量
.pipe(replace('}(window); // gulp build: layui-footer', '')) // 替换 layui.js 的落脚
.pipe(replace(';!function(window){ // gulp build: lay-header', '')) // 替换 lay.js 的头部
.pipe(replace('}(window, window.document); // gulp build: lay-footer', '')) // 替换 lay.js 的落脚
.pipe(concat('laydate.js', {newLine: ''}))
.pipe(replace(';!function(window, document){ // gulp build: laydate-header', '')) // 替换 laydate.js 的头部
.pipe(header.apply(null, comment)) // 追加头部
.pipe(gulp.dest(dest + 'src'));
};
.pipe(gulp.dest(rlsDirname));
},
exports.cp, // 复制 dist 目录文件
() => { // 生成 ZIP 压缩包
const base = path.dirname(rlsDirname);
return gulp.src(rlsDirname + '/**/*', {
base: base
})
.pipe(zip(`${rlsFileName}.zip`))
.pipe(gulp.dest(base))
}
);
// helper
exports.help = () => {
@ -167,7 +135,7 @@ exports.help = () => {
let parser = yargs.usage(usage, {
dest: {
type: 'string',
desc: '定义输出目录可选项dist默认、rls、任意路径'
desc: '定义输出路径'
},
vs: {
type: 'boolean',
@ -179,10 +147,8 @@ exports.help = () => {
console.log([
'Tasks:',
' default 默认任务',
' rls 发行任务',
' release 发行任务',
' cp 将 dist 目录复制一份到参数 --dest 指向的目录'
].join('\n'), '\n\nExamples:\n gulp cp --dest ./v --vs', '\n');
return gulp.src('./');
};

View File

@ -1,39 +1,45 @@
{
"name": "layui",
"version": "2.8.18",
"version": "2.9.0-beta.1",
"description": "Classic modular Front-End UI library",
"main": "dist/layui.js",
"keywords": [
"layui",
"components",
"front-end",
"framework",
"library",
"ui",
"web"
],
"homepage": "https://layui.dev",
"license": "MIT",
"scripts": {},
"bugs": {
"url": "https://github.com/layui/layui/issues"
},
"repository": {
"type": "git",
"url": "git+ssh://git@github.com/layui/layui.git"
},
"homepage": "https://layui.dev",
"main": "dist/layui.js",
"files": [
"dist"
],
"scripts": {
"build": "gulp",
"release": "npm run build && npm rum release-zip",
"release-zip": "gulp release"
},
"devDependencies": {
"gulp": "^4.0.2",
"gulp-uglify": "^3.0.2",
"gulp-clean-css": "^4.3.0",
"gulp-concat": "^2.6.1",
"gulp-replace": "^1.1.4",
"gulp-rename": "^2.0.0",
"gulp-header": "^2.0.9",
"gulp-footer": "^2.1.0",
"gulp-sourcemaps": "^3.0.0",
"del": "^2.2.2",
"gulp-zip": "^5.1.0",
"del": "^6.1.1",
"minimist": "^1.2.8"
},
"bugs": {
"url": "https://gitee.com/layui/layui/issues"
},
"dependencies": {},
"keywords": [
"layui",
"ui",
"javascript",
"css",
"components",
"framework",
"library"
]
"dependencies": {}
}

View File

@ -16,7 +16,7 @@
};
var Layui = function(){
this.v = '2.8.18'; // Layui 版本号
this.v = '2.9.0-beta.1'; // Layui 版本号
};
// 识别预先可能定义的指定全局对象

View File

@ -138,7 +138,7 @@
/**
* 创建元素
* @param {string} elemName - 元素的标签名
* @param {{attrName: string, attrValue:string}} [attr] - 添加到元素上的属性
* @param {Object.<string, string>} [attr] - 添加到元素上的属性
* @returns {HTMLElement} 返回创建的 HTML 元素
* @example
* ```js
@ -392,7 +392,7 @@
* 获取元素上的属性配置项
* @param {string | HTMLElement | JQuery} elem - HTML 元素
* @param {{attr: string} | string} [opts="lay-options"] - 可配置的选项string 类型指定属性名
* @returns {*} 返回元素上的属性配置项
* @returns {Object.<string, any>} 返回元素上的属性配置项
* @example
* ```js
* <div id="testEl" lay-options="{color:red}" lay-toc="{hot: true}"></div>
@ -417,6 +417,10 @@
var attrValue = othis.attr(attrName);
try {
/**
* 请注意: 开发者在使用 lay-options="{}" 配置组件选项时需确保属性值不来自于网页用户,
* 即属性值必须在网页开发者自身的可控范围内否则请勿在 HTML 标签属性中获取组件选项
*/
return new Function('return '+ (attrValue || '{}'))();
} catch(ev) {
layui.hint().error(opts.errorText || [
@ -468,11 +472,16 @@
writeText: function(options) {
var text = String(options.text);
try {
navigator.clipboard.writeText(text).then(
options.done
)['catch'](options.error);
} catch(e) {
if(navigator && 'clipboard' in navigator){
navigator.clipboard.writeText(text)
.then(options.done, function(){
legacyCopy();
});
}else{
legacyCopy();
}
function legacyCopy(){
var elem = document.createElement('textarea');
elem.value = text;

View File

@ -1405,7 +1405,7 @@
that.limit({
elem: lay(that.footer).find(ELEM_CONFIRM),
date: that[startEnd],
inedx: 0,
index: 0,
time: ['hours', 'minutes', 'seconds']
});
}

View File

@ -1598,6 +1598,7 @@ layer.photos = function(options, loop, key){
} else {
zoomElem.eq(1).trigger('click');
}
e.preventDefault();
});
};

View File

@ -118,6 +118,10 @@ layui.define(function(exports){
template = '"use strict";var view = "' + template + '";return view;';
try {
/**
* 请注意: 开发者在使用模板语法时需确保模板中的 JS 语句不来自于页面用户输入
* 即模板中的 JS 语句必须在页面开发者自身的可控范围内否则请避免使用该模板解析
*/
that.cache = template = new Function('d, laytpl', template);
return template(data, tool);
} catch(e) {

View File

@ -352,12 +352,12 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){
that.setInit();
// 高度铺满full-差距值
if(options.height && /^full-\d+$/.test(options.height)){
that.fullHeightGap = options.height.split('-')[1];
if(options.height && /^full-.+$/.test(options.height)){
that.fullHeightGap = parseFloat(options.height.split('-')[1]) || 0;
options.height = _WIN.height() - that.fullHeightGap;
} else if (options.height && /^#\w+\S*-\d+$/.test(options.height)) {
} else if (options.height && /^#\w+\S*-.+$/.test(options.height)) {
var parentDiv = options.height.split("-");
that.parentHeightGap = parentDiv.pop();
that.parentHeightGap = parseFloat(parentDiv.pop()) || 0;
that.parentDiv = parentDiv.join("-");
options.height = $(that.parentDiv).height() - that.parentHeightGap;
}
@ -1035,9 +1035,7 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){
dataType: options.dataType || 'json',
jsonpCallback: options.jsonpCallback,
headers: options.headers || {},
complete: function(xhr,ts){
typeof options.complete === 'function' && options.complete(xhr, ts);
},
complete: typeof options.complete === 'function' ? options.complete : undefined,
success: function(res){
// 若有数据解析的回调,则获得其返回的数据
if(typeof options.parseData === 'function'){
@ -2469,7 +2467,7 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){
}
};
// 展开单元格内容
var gridExpand = function(e){
var gridExpand = function(e, expandedMode){
var othis = $(this);
var td = othis.parent();
var key = td.data('key');
@ -2478,7 +2476,8 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){
var elemCell = td.children(ELEM_CELL);
var ELEM_CELL_C = 'layui-table-cell-c';
var elemCellClose = $('<i class="layui-icon layui-icon-up '+ ELEM_CELL_C +'">');
var expandedMode = col.expandedMode || options.cellExpandedMode;
expandedMode = expandedMode || col.expandedMode || options.cellExpandedMode;
// 展开风格
if (expandedMode === 'tips') { // TIPS 展开风格
@ -2539,11 +2538,13 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){
// 关闭展开状态
elemCellClose.on('click', function(){
var $this = $(this);
that.setRowActive(index, ELEM_EXPAND, true); // 移除单元格展开样式
that.setRowActive(index, [ELEM_EXPAND, ELEM_HOVER].join(' '), true); // 移除单元格展开样式
that.cssRules(key, function(item){
item.style.width = $this.data('cell-width'); // 恢复单元格展开前的宽度
setTimeout(function(){
that.resize(); // 滚动条补丁
});
});
$this.remove();
});
}
@ -2558,7 +2559,7 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){
});
// 表格合计栏单元格展开事件
that.layTotal.on('click', '.'+ ELEM_GRID_DOWN, function(e){
gridExpand.call(this, e);
gridExpand.call(this, e, 'tips'); // 强制采用 tips 风格
});
// 行工具条操作事件

View File

@ -383,33 +383,61 @@ layui.define('jquery', function(exports){
}
},
// 批量事件
event: function(attr, obj, eventType){
var _body = $('body');
eventType = eventType || 'click';
/**
* 批量事件
* @param {string} [attr="lay-on"] - 触发事件的元素属性名
* @param {Object.<string, Function} events - 事件集合
* @param {Object} [options] - 参数的更多选项
* @param {(string|HTMLElement|jQuery)} [options.elem="body"] - 触发事件的委托元素
* @param {string} [options.trigger="click"] - 事件触发的方式
* @returns {Object} 返回当前 events 参数设置的事件集合
*/
on: function(attr, events, options) {
// 若参数一为 object 类型,则为事件集,且省略 attr
if (typeof attr === 'object') {
options = events || {};
events = attr;
attr = options.attr || 'lay-on'; // 默认属性名
}
// 记录事件回调集合
obj = util.event[attr] = $.extend(true, util.event[attr], obj) || {};
// 更多选项
options = $.extend({
elem: 'body',
trigger: 'click'
}, typeof options === 'object' ? options : {
trigger: options // 兼容旧版
});
// 清除委托事件
util.event.UTIL_EVENT_CALLBACK = util.event.UTIL_EVENT_CALLBACK || {};
_body.off(eventType, '*['+ attr +']', util.event.UTIL_EVENT_CALLBACK[attr])
var elem = options.elem = $(options.elem);
var attrSelector = '['+ attr +']';
var CALLBACK = 'UTIL_ON_CALLBACK';
// 绑定委托事件
util.event.UTIL_EVENT_CALLBACK[attr] = function(){
if (!elem[0]) return; // 若委托元素不存在
// 根据 attr 记录事件集合
events = util.on[attr] = $.extend(true, util.on[attr], events) || {};
// 清除事件委托
util.on[CALLBACK] = util.on[CALLBACK] || {};
elem.off(options.trigger, attrSelector, util.on[CALLBACK][attr]);
// 绑定事件委托
elem.on(
options.trigger,
attrSelector,
util.on[CALLBACK][attr] = function() {
var othis = $(this);
var key = othis.attr(attr);
(typeof obj[key] === 'function') && obj[key].call(this, othis);
};
typeof events[key] === 'function' && events[key].call(this, othis);
}
);
// 清除旧事件,绑定新事件
_body.on(eventType, '*['+ attr +']', util.event.UTIL_EVENT_CALLBACK[attr]);
return obj;
return events;
}
};
util.on = util.event;
// 兼容旧版
util.event = util.on;
// 输出接口
exports('util', util);