mirror of
https://gitee.com/layui/layui.git
synced 2025-10-07 15:14:31 +08:00
Merge branch 'main' into feat/dropdown-mulit
This commit is contained in:
@@ -11,13 +11,13 @@
|
||||
<th>描述</th>
|
||||
<th>类型</th>
|
||||
<th>默认值</th>
|
||||
</tr>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>elem</td>
|
||||
<td>
|
||||
|
||||
|
||||
绑定元素选择器或 DOM 对象
|
||||
|
||||
</td>
|
||||
@@ -37,11 +37,11 @@
|
||||
<tr>
|
||||
<td>preview <sup>2.8+</sup></td>
|
||||
<td>
|
||||
|
||||
|
||||
是否开启 Code 预览功能,可选值有:
|
||||
|
||||
- `true` 开启 Code 的普通预览
|
||||
- `false` 关闭 Code 预览(默认)
|
||||
- `false` 关闭 Code 预览(默认)
|
||||
- `"iframe"` 开启 Code 在 iframe 模式中预览
|
||||
|
||||
当开启该属性时,`elem` 指定的元素需要设置成以下结构:
|
||||
@@ -65,13 +65,13 @@ code content
|
||||
<tr>
|
||||
<td>layout <sup>2.8+</sup></td>
|
||||
<td>
|
||||
|
||||
|
||||
开启预览后的面板布局方式,值为一个数组,数组的可选成员有:
|
||||
|
||||
- `code` 代码区域
|
||||
- `preview` 预览区域
|
||||
|
||||
面板将根据数组的排列顺序来显示,如:
|
||||
面板将根据数组的排列顺序来显示,如:
|
||||
|
||||
```
|
||||
layout: ['code', 'preview']
|
||||
@@ -84,7 +84,7 @@ layout: ['code', 'preview']
|
||||
<tr>
|
||||
<td>style <sup>2.8+</sup></td>
|
||||
<td>
|
||||
|
||||
|
||||
设置 Code 和预览区域的公共样式
|
||||
|
||||
</td>
|
||||
@@ -94,7 +94,7 @@ layout: ['code', 'preview']
|
||||
<tr>
|
||||
<td>codeStyle <sup>2.8+</sup></td>
|
||||
<td>
|
||||
|
||||
|
||||
设置 Code 区域的局部样式,优先级高于 `style` 属性
|
||||
|
||||
</td>
|
||||
@@ -104,7 +104,7 @@ layout: ['code', 'preview']
|
||||
<tr>
|
||||
<td>previewStyle <sup>2.8+</sup></td>
|
||||
<td>
|
||||
|
||||
|
||||
设置预览区域的局部样式,优先级高于 `style` 属性
|
||||
|
||||
</td>
|
||||
@@ -114,7 +114,7 @@ layout: ['code', 'preview']
|
||||
<tr>
|
||||
<td>id <sup>2.8+</sup></td>
|
||||
<td>
|
||||
|
||||
|
||||
设置实例的唯一索引,以便用于其他操作
|
||||
|
||||
</td>
|
||||
@@ -124,7 +124,7 @@ layout: ['code', 'preview']
|
||||
<tr>
|
||||
<td>className <sup>2.8+</sup></td>
|
||||
<td>
|
||||
|
||||
|
||||
追加实例面板的 `className`,以便对其自定义样式
|
||||
|
||||
</td>
|
||||
@@ -134,7 +134,7 @@ layout: ['code', 'preview']
|
||||
<tr>
|
||||
<td>tools <sup>2.8+</sup></td>
|
||||
<td>
|
||||
|
||||
|
||||
用于开启 `preview` 属性后的面板头部右侧区域工具栏图标,值为一个数组,内置成员:
|
||||
|
||||
- `copy` <sup>2.8.2+</sup> : 代码复制
|
||||
@@ -168,7 +168,7 @@ tools: [
|
||||
<tr>
|
||||
<td>toolsEvent <sup>2.8+</sup></td>
|
||||
<td>
|
||||
|
||||
|
||||
点击工具栏的回调函数,功能同 `tools` 中的 `event`,只是需通过 `type` 属性来区分是哪个工具菜单。
|
||||
|
||||
```
|
||||
@@ -187,7 +187,7 @@ toolsEvent: function(obj){
|
||||
<tr>
|
||||
<td>copy <sup>2.8.2+</sup></td>
|
||||
<td>
|
||||
|
||||
|
||||
用于开启代码复制功能图标。若开启 `priview`,则自动放置在 `tools` 属性中,复制图标将显示在容器右上角工具栏;若未开启 `priview`,则显示在 code 区域右上角。
|
||||
|
||||
</td>
|
||||
@@ -201,7 +201,7 @@ toolsEvent: function(obj){
|
||||
<tr>
|
||||
<td>text <sup>2.8+</sup></td>
|
||||
<td>
|
||||
|
||||
|
||||
自定义默认文本,值为一个对象,可选成员有:
|
||||
|
||||
```
|
||||
@@ -218,7 +218,7 @@ text: {
|
||||
<tr>
|
||||
<td>header <sup>2.8+</sup></td>
|
||||
<td>
|
||||
|
||||
|
||||
是否开启 Code 栏头部区域。
|
||||
|
||||
</td>
|
||||
@@ -232,7 +232,7 @@ text: {
|
||||
<tr>
|
||||
<td>ln</td>
|
||||
<td>
|
||||
|
||||
|
||||
是否显示 Code 区域的行号
|
||||
|
||||
</td>
|
||||
@@ -246,7 +246,7 @@ text: {
|
||||
<tr>
|
||||
<td>theme <sup>2.8.17+</sup></td>
|
||||
<td>
|
||||
|
||||
|
||||
Code 容器的主题风格,可选值有:
|
||||
|
||||
- `light` 浅色模式(默认)
|
||||
@@ -259,7 +259,7 @@ Code 容器的主题风格,可选值有:
|
||||
<tr>
|
||||
<td>encode</td>
|
||||
<td>
|
||||
|
||||
|
||||
是否对 code 中的 html 进行编码(转义)。
|
||||
|
||||
</td>
|
||||
@@ -358,7 +358,7 @@ code 组件语法高亮相关示例:
|
||||
</td>
|
||||
<td colspan="3">
|
||||
|
||||
<div id="options.done" lay-pid="options" class="ws-anchor">
|
||||
<div id="options.done" lay-pid="options" class="ws-anchor">
|
||||
组件渲染完毕的回调函数,函数返回一个 object 类型参数
|
||||
</div>
|
||||
|
||||
@@ -379,7 +379,7 @@ done: function(obj){
|
||||
</td>
|
||||
<td colspan="3">
|
||||
|
||||
<div id="options.onCopy" lay-pid="options" class="ws-anchor">
|
||||
<div id="options.onCopy" lay-pid="options" class="ws-anchor">
|
||||
点击复制图标时的回调函数。
|
||||
</div>
|
||||
|
||||
@@ -393,6 +393,49 @@ onCopy: function(code, copied){
|
||||
|
||||
```
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
|
||||
[highlightLine](#options.highlightLine) <sup>2.12+</sup>
|
||||
|
||||
</td>
|
||||
<td colspan="3">
|
||||
|
||||
<div id="options.highlightLine" lay-pid="options" class="ws-anchor">
|
||||
|
||||
设置行高亮,可选项:
|
||||
- `hl` : 高亮
|
||||
- `++` : diff++
|
||||
- `--` : diff--
|
||||
- `focus` : 聚焦
|
||||
|
||||
</div>
|
||||
|
||||
可通过 `hl.range` 选项来设置行高亮范围:
|
||||
|
||||
```
|
||||
highlightLine: {
|
||||
hl: {
|
||||
range: '1,3-5,8', // 指定行高亮范围 '1,3,4,5,8'
|
||||
comment: true, // 是否解析行中的高亮注释
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
或通过特定注释格式: `[!code <type>:<lines>]` 指定行高亮范围,规则解释:
|
||||
- `<type>` : `highlightLine` 的可选项,如 `h1, focus` 等
|
||||
- `<lines>` : 行数(含本行)
|
||||
|
||||
```
|
||||
111 聚焦 2 行(含本行) // [!code focus:2]
|
||||
222 高亮本行 // [!code hl]
|
||||
333
|
||||
```
|
||||
|
||||
highlightLine 选项的详细用法可参考:<a href="https://github.com/layui/layui/blob/main/examples/code.html" rel="nofollow" target="_blank">highlightLine 行高亮在线示例</a>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
|
@@ -1,182 +1,184 @@
|
||||
<pre class="layui-code" lay-options="{style: 'height: 525px;', layout: ['code'], tools: []}">
|
||||
<textarea>
|
||||
// 简体中文语言包(内置)
|
||||
var zhCN = {
|
||||
code: {
|
||||
copy: '复制代码',
|
||||
copied: '已复制',
|
||||
copyError: '复制失败',
|
||||
maximize: '最大化显示',
|
||||
restore: '还原显示',
|
||||
preview: '在新窗口预览'
|
||||
},
|
||||
colorpicker: {
|
||||
clear: '清除',
|
||||
confirm: '确定'
|
||||
},
|
||||
dropdown: {
|
||||
noData: '暂无数据'
|
||||
},
|
||||
flow: {
|
||||
loadMore: '加载更多',
|
||||
noMore: '没有更多了'
|
||||
},
|
||||
form: {
|
||||
select: {
|
||||
noData: '暂无数据',
|
||||
noMatch: '无匹配数据',
|
||||
placeholder: '请选择'
|
||||
},
|
||||
validateMessages: {
|
||||
required: '必填项不能为空',
|
||||
phone: '手机号格式不正确',
|
||||
email: '邮箱格式不正确',
|
||||
url: '链接格式不正确',
|
||||
number: '只能填写数字',
|
||||
date: '日期格式不正确',
|
||||
identity: '身份证号格式不正确'
|
||||
},
|
||||
verifyErrorPromptTitle: '提示'
|
||||
},
|
||||
laydate: {
|
||||
months: ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月'],
|
||||
weeks: ['日', '一', '二', '三', '四', '五', '六'],
|
||||
time: ['时', '分', '秒'],
|
||||
literal: {
|
||||
year: '年'
|
||||
},
|
||||
selectDate: '选择日期',
|
||||
selectTime: '选择时间',
|
||||
startTime: '开始时间',
|
||||
endTime: '结束时间',
|
||||
tools: {
|
||||
confirm: '确定',
|
||||
clear: '清空',
|
||||
now: '现在',
|
||||
reset: '重置'
|
||||
},
|
||||
rangeOrderPrompt: '结束时间不能早于开始时间\n请重新选择',
|
||||
invalidDatePrompt: '不在有效日期或时间范围内\n',
|
||||
formatErrorPrompt: '日期格式不合法\n必须遵循:\n{format}\n',
|
||||
autoResetPrompt: '已自动重置',
|
||||
preview: '当前选中的结果'
|
||||
},
|
||||
layer: {
|
||||
confirm: '确定',
|
||||
cancel: '取消',
|
||||
defaultTitle: '信息',
|
||||
prompt: {
|
||||
InputLengthPrompt: '最多输入 {length} 个字符'
|
||||
},
|
||||
photos: {
|
||||
noData: '没有图片',
|
||||
tools:{
|
||||
rotate: '旋转',
|
||||
scaleX: '水平变换',
|
||||
zoomIn: '放大',
|
||||
zoomOut: '缩小',
|
||||
reset: '还原',
|
||||
close: '关闭'
|
||||
},
|
||||
viewPicture: '查看原图',
|
||||
urlError: {
|
||||
prompt: '当前图片地址异常,\n是否继续查看下一张?',
|
||||
confirm: '下一张',
|
||||
cancel: '不看了'
|
||||
}
|
||||
}
|
||||
},
|
||||
laypage: {
|
||||
prev: '上一页',
|
||||
next: '下一页',
|
||||
first: '首页',
|
||||
last: '尾页',
|
||||
total: '共 {total} 条',
|
||||
pagesize: '条/页',
|
||||
goto: '到第',
|
||||
page: '页',
|
||||
confirm: '确定'
|
||||
},
|
||||
table: {
|
||||
sort: {
|
||||
asc: '升序',
|
||||
desc: '降序'
|
||||
},
|
||||
noData: '暂无数据',
|
||||
tools:{
|
||||
filter: {
|
||||
title: '筛选列'
|
||||
},
|
||||
export: {
|
||||
title: '导出',
|
||||
noDataPrompt: '当前表格无数据',
|
||||
compatPrompt: '导出功能不支持 IE,请用 Chrome 等高级浏览器导出',
|
||||
csvText : '导出 CSV 文件'
|
||||
},
|
||||
print: {
|
||||
title: '打印',
|
||||
noDataPrompt: '当前表格无数据'
|
||||
}
|
||||
},
|
||||
dataFormatError: '返回的数据不符合规范,正确的成功状态码应为:"{statusName}": {statusCode}',
|
||||
xhrError: '请求异常,错误提示:{msg}'
|
||||
},
|
||||
transfer: {
|
||||
noData: '暂无数据',
|
||||
noMatch: '无匹配数据',
|
||||
title: ['列表一', '列表二'],
|
||||
searchPlaceholder: '关键词搜索'
|
||||
},
|
||||
tree: {
|
||||
defaultNodeName: '未命名',
|
||||
noData: '暂无数据',
|
||||
deleteNodePrompt: '确认删除"{name}"节点吗?'
|
||||
},
|
||||
upload: {
|
||||
fileType: {
|
||||
file: '文件',
|
||||
image: '图片',
|
||||
video: '视频',
|
||||
audio: '音频'
|
||||
},
|
||||
validateMessages: {
|
||||
fileExtensionError: '选择的{fileType}中包含不支持的格式',
|
||||
filesOverLengthLimit: '同时最多只能上传: {length} 个文件',
|
||||
currentFilesLength: '当前已经选择了: {length} 个文件',
|
||||
fileOverSizeLimit: '文件大小不能超过 {size}'
|
||||
},
|
||||
chooseText: '{length} 个文件'
|
||||
},
|
||||
util: {
|
||||
timeAgo: {
|
||||
days: '{days} 天前',
|
||||
hours: '{hours} 小时前',
|
||||
minutes: '{minutes} 分钟前',
|
||||
future: '未来',
|
||||
justNow: '刚刚'
|
||||
},
|
||||
toDateString: {
|
||||
// https://www.unicode.org/cldr/charts/47/supplemental/day_periods.html
|
||||
meridiem: function(hours, minutes){
|
||||
var hm = hours * 100 + minutes;
|
||||
if (hm < 500) {
|
||||
return '凌晨';
|
||||
} else if (hm < 800) {
|
||||
return '早上';
|
||||
} else if (hm < 1200) {
|
||||
return '上午';
|
||||
} else if (hm < 1300) {
|
||||
return '中午';
|
||||
} else if (hm < 1900) {
|
||||
return '下午';
|
||||
}
|
||||
return '晚上';
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
i18n.set({
|
||||
locale: 'zh-CN', // 设置语言环境
|
||||
messages: { // 语言包
|
||||
'zh-CN': { // 简体中文语言包(内置)
|
||||
code: {
|
||||
copy: '复制代码',
|
||||
copied: '已复制',
|
||||
copyError: '复制失败',
|
||||
maximize: '最大化显示',
|
||||
restore: '还原显示',
|
||||
preview: '在新窗口预览'
|
||||
},
|
||||
colorpicker: {
|
||||
clear: '清除',
|
||||
confirm: '确定'
|
||||
},
|
||||
dropdown: {
|
||||
noData: '暂无数据'
|
||||
},
|
||||
flow: {
|
||||
loadMore: '加载更多',
|
||||
noMore: '没有更多了'
|
||||
},
|
||||
form: {
|
||||
select: {
|
||||
noData: '暂无数据',
|
||||
noMatch: '无匹配数据',
|
||||
placeholder: '请选择'
|
||||
},
|
||||
validateMessages: {
|
||||
required: '必填项不能为空',
|
||||
phone: '手机号格式不正确',
|
||||
email: '邮箱格式不正确',
|
||||
url: '链接格式不正确',
|
||||
number: '只能填写数字',
|
||||
date: '日期格式不正确',
|
||||
identity: '身份证号格式不正确'
|
||||
},
|
||||
verifyErrorPromptTitle: '提示'
|
||||
},
|
||||
laydate: {
|
||||
months: ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月'],
|
||||
weeks: ['日', '一', '二', '三', '四', '五', '六'],
|
||||
time: ['时', '分', '秒'],
|
||||
literal: {
|
||||
year: '年'
|
||||
},
|
||||
selectDate: '选择日期',
|
||||
selectTime: '选择时间',
|
||||
startTime: '开始时间',
|
||||
endTime: '结束时间',
|
||||
tools: {
|
||||
confirm: '确定',
|
||||
clear: '清空',
|
||||
now: '现在',
|
||||
reset: '重置'
|
||||
},
|
||||
rangeOrderPrompt: '结束时间不能早于开始时间\n请重新选择',
|
||||
invalidDatePrompt: '不在有效日期或时间范围内\n',
|
||||
formatErrorPrompt: '日期格式不合法\n必须遵循:\n{format}\n',
|
||||
autoResetPrompt: '已自动重置',
|
||||
preview: '当前选中的结果'
|
||||
},
|
||||
layer: {
|
||||
confirm: '确定',
|
||||
cancel: '取消',
|
||||
defaultTitle: '信息',
|
||||
prompt: {
|
||||
InputLengthPrompt: '最多输入 {length} 个字符'
|
||||
},
|
||||
photos: {
|
||||
noData: '没有图片',
|
||||
tools:{
|
||||
rotate: '旋转',
|
||||
scaleX: '水平变换',
|
||||
zoomIn: '放大',
|
||||
zoomOut: '缩小',
|
||||
reset: '还原',
|
||||
close: '关闭'
|
||||
},
|
||||
viewPicture: '查看原图',
|
||||
urlError: {
|
||||
prompt: '当前图片地址异常,\n是否继续查看下一张?',
|
||||
confirm: '下一张',
|
||||
cancel: '不看了'
|
||||
}
|
||||
}
|
||||
},
|
||||
laypage: {
|
||||
prev: '上一页',
|
||||
next: '下一页',
|
||||
first: '首页',
|
||||
last: '尾页',
|
||||
total: '共 {total} 条',
|
||||
pagesize: '条/页',
|
||||
goto: '到第',
|
||||
page: '页',
|
||||
confirm: '确定'
|
||||
},
|
||||
table: {
|
||||
sort: {
|
||||
asc: '升序',
|
||||
desc: '降序'
|
||||
},
|
||||
noData: '暂无数据',
|
||||
tools:{
|
||||
filter: {
|
||||
title: '筛选列'
|
||||
},
|
||||
export: {
|
||||
title: '导出',
|
||||
noDataPrompt: '当前表格无数据',
|
||||
compatPrompt: '导出功能不支持 IE,请用 Chrome 等高级浏览器导出',
|
||||
csvText : '导出 CSV 文件'
|
||||
},
|
||||
print: {
|
||||
title: '打印',
|
||||
noDataPrompt: '当前表格无数据'
|
||||
}
|
||||
},
|
||||
dataFormatError: '返回的数据不符合规范,正确的成功状态码应为:"{statusName}": {statusCode}',
|
||||
xhrError: '请求异常,错误提示:{msg}'
|
||||
},
|
||||
transfer: {
|
||||
noData: '暂无数据',
|
||||
noMatch: '无匹配数据',
|
||||
title: ['列表一', '列表二'],
|
||||
searchPlaceholder: '关键词搜索'
|
||||
},
|
||||
tree: {
|
||||
defaultNodeName: '未命名',
|
||||
noData: '暂无数据',
|
||||
deleteNodePrompt: '确认删除"{name}"节点吗?'
|
||||
},
|
||||
upload: {
|
||||
fileType: {
|
||||
file: '文件',
|
||||
image: '图片',
|
||||
video: '视频',
|
||||
audio: '音频'
|
||||
},
|
||||
validateMessages: {
|
||||
fileExtensionError: '选择的{fileType}中包含不支持的格式',
|
||||
filesOverLengthLimit: '同时最多只能上传: {length} 个文件',
|
||||
currentFilesLength: '当前已经选择了: {length} 个文件',
|
||||
fileOverSizeLimit: '文件大小不能超过 {size}'
|
||||
},
|
||||
chooseText: '{length} 个文件'
|
||||
},
|
||||
util: {
|
||||
timeAgo: {
|
||||
days: '{days} 天前',
|
||||
hours: '{hours} 小时前',
|
||||
minutes: '{minutes} 分钟前',
|
||||
future: '未来',
|
||||
justNow: '刚刚'
|
||||
},
|
||||
toDateString: {
|
||||
// https://www.unicode.org/cldr/charts/47/supplemental/day_periods.html
|
||||
meridiem: function(hours, minutes){
|
||||
var hm = hours * 100 + minutes;
|
||||
if (hm < 500) {
|
||||
return '凌晨';
|
||||
} else if (hm < 800) {
|
||||
return '早上';
|
||||
} else if (hm < 1200) {
|
||||
return '上午';
|
||||
} else if (hm < 1300) {
|
||||
return '中午';
|
||||
} else if (hm < 1900) {
|
||||
return '下午';
|
||||
}
|
||||
return '晚上';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
'zh-CN': zhCN
|
||||
}
|
||||
});
|
||||
</textarea>
|
||||
|
@@ -103,12 +103,8 @@ i18n.set({
|
||||
});
|
||||
```
|
||||
|
||||
为了节省时间,也可以借助「**第三方提供并维护**的 Layui 多语言 AI 翻译工具」直接生成不同语言的消息文本,如:
|
||||
|
||||
| 翻译工具 | 提供者 |
|
||||
| --- | --- |
|
||||
| <a href="https://gitee.com/mail_osc/translate/tree/master/extend/layui-i18n-object-translate" target="_blank">https://gitee.com/mail_osc/translate/tree/master/extend/layui-i18n-object-translate</a> | <a href="https://github.com/xnx3" target="_blank">@xnx3</a> |
|
||||
对消息文本进行翻译时,为了节省时间,你可以使用 AI 直接生成不同语言的消息文本,或者使用第三方提供的 Layui 多语言 AI 翻译工具(如:<a href="https://gitee.com/mail_osc/translate/tree/master/extend/layui-i18n-object-translate" target="_blank">https://gitee.com/mail_osc/translate/tree/master/extend/layui-i18n-object-translate</a> By <a href="https://github.com/xnx3" target="_blank">@xnx3</a>)。
|
||||
|
||||
## 💖 心语
|
||||
|
||||
i18n 模块是在众多开发者强烈的需求呼声中,由 Layui 核心 Contributor [@Sight-wcg](https://github.com/Sight-wcg) 完成,该模块通过简练的设计,为 Layui 组件实现了多语言的无缝接入,并且兼容了一些原本自带简单多语言或消息配置的组件,Layui 2.x 版本也因此具备国际化能力。
|
||||
i18n 模块是在众多开发者的广泛需求背景下完成开发,它通过简练的设计,为 Layui 组件实现了多语言的无缝接入,并且兼容了一些原本自带简单多语言或消息配置的组件,从而使 Layui 2 系列版本全面支持国际化。
|
||||
|
@@ -2,7 +2,7 @@
|
||||
title: 滑块组件 slider
|
||||
toc: true
|
||||
---
|
||||
|
||||
|
||||
# 滑块组件
|
||||
|
||||
> 滑块组件 `slider` 是一个拖拽选值的交互性组件,常与 `form` 元素结合使用。
|
||||
@@ -22,6 +22,7 @@ toc: true
|
||||
| API | 描述 |
|
||||
| --- | --- |
|
||||
| var slider = layui.slider | 获得 `slider` 模块。 |
|
||||
| [基础接口](../component/#export) <sup>2.12+</sup> | 该组件由 `component` 构建,因此继承其提供的基础接口。|
|
||||
| [var inst = slider.render(options)](#render) | slider 组件渲染,核心方法。 |
|
||||
| [inst.setValue(value)](#setValue) | 设置滑块值 |
|
||||
| inst.config | 获得当前实例的属性选项 |
|
||||
@@ -37,7 +38,7 @@ toc: true
|
||||
<div id="ID-test-slider"></div>
|
||||
<div class="class-test-slider" lay-options="{value: 50}"></div>
|
||||
<div class="class-test-slider" lay-options="{value: 80}"></div>
|
||||
|
||||
|
||||
<!-- import layui -->
|
||||
<script>
|
||||
layui.use(function(){
|
||||
@@ -71,16 +72,16 @@ console.log(inst); // 得到当前实例对象
|
||||
|
||||
```
|
||||
var slider = layui.slider;
|
||||
|
||||
|
||||
// 渲染
|
||||
var inst = slider.render({
|
||||
elem: '#id'
|
||||
// …
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
// 设置滑块值
|
||||
inst.setValue(20);
|
||||
|
||||
|
||||
// 若滑块开启了范围,即: `range: true`
|
||||
ins1.setValue(20, 0) // 设置开始值
|
||||
ins1.setValue(60, 1) // 设置结尾值
|
||||
|
@@ -4,15 +4,16 @@
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
|
||||
<title>Code blocks adorn - Layui</title>
|
||||
|
||||
<link href="../src/css/layui.css" rel="stylesheet">
|
||||
<style>
|
||||
body{padding: 32px;}
|
||||
pre{margin: 16px 0;}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<body class="layui-padding-3">
|
||||
|
||||
<div class="layui-text">
|
||||
<h2>代码高亮</h2>
|
||||
</div>
|
||||
<pre id="test" class="layui-test">
|
||||
<textarea class="layui-hide">
|
||||
<div class="layui-btn-container">
|
||||
@@ -54,6 +55,104 @@ Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
</textarea>
|
||||
</pre>
|
||||
|
||||
<div class="layui-text">
|
||||
<h2>行高亮和聚焦</h2>
|
||||
</div>
|
||||
<pre
|
||||
class="layui-code"
|
||||
lay-options="{
|
||||
highlightLine: {
|
||||
hl: {
|
||||
range: '1,3-5,8', // 指定行高亮范围 '1,3,4,5,8'
|
||||
comment: true, // 是否解析行中的高亮注释
|
||||
}
|
||||
}
|
||||
}">
|
||||
<textarea class="layui-hide">
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>Quick Start - Layui</title>
|
||||
<link href="//unpkg.com/layui@2.11.4/dist/css/layui.css" rel="stylesheet">
|
||||
</head>
|
||||
<body>
|
||||
<!-- HTML Content -->
|
||||
<script src="//unpkg.com/layui@2.11.4/dist/layui.js"></script>
|
||||
<script>
|
||||
// Usage // [!code focus:6]
|
||||
layui.use(function(){
|
||||
var layer = layui.layer;
|
||||
// Welcome
|
||||
layer.msg('Hello World', {icon: 6});
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
</textarea>
|
||||
</pre>
|
||||
|
||||
<div class="layui-text">
|
||||
<h2>diff</h2>
|
||||
</div>
|
||||
<pre
|
||||
class="layui-code"
|
||||
lay-options="{
|
||||
highlightLine: {
|
||||
hl:{range: '38-40'},
|
||||
'++':{comment: true},
|
||||
'--':{comment: true}
|
||||
}
|
||||
}">
|
||||
<textarea class="layui-hide">
|
||||
<template id="test">
|
||||
<p>转义输出:{{= d.desc }}</p>
|
||||
<p>原文输出:{{- d.desc }}</p>
|
||||
{{# 注释标签 - 仅在模板中显示,不在视图中输出 }} // [!code ++]
|
||||
<p>{{! 忽略标签,可显示原始标签:
|
||||
{{# let a = 0; }} // [!code --]
|
||||
{{ let a = 0; }} // [!code ++]
|
||||
!}}
|
||||
</p>
|
||||
<p>
|
||||
条件语句:
|
||||
{{= d.list.length ? d.title : '' }}
|
||||
{{# if(d.title){}} - #AAAA{{='A'}}{{# } }} //[!code --]
|
||||
{{ if(d.title){}} - #AAAA{{='A'}}{{ } }} //[!code ++]
|
||||
</p>
|
||||
<p>循环语句:</p>
|
||||
<ul>
|
||||
{{# d.list.forEach(function(item) { }} //[!code --]
|
||||
{{ d.list.forEach(function(item) { }} //[!code ++]
|
||||
</p>
|
||||
<li>
|
||||
<span>{{= item.title }}</span>
|
||||
<span>{{= item.name }}</span>
|
||||
</li>
|
||||
{{# }); }} //[!code --]
|
||||
{{ }); }} //[!code ++]
|
||||
</ul>
|
||||
{{# if (d.list.length === 0) { }} //[!code --]
|
||||
{{ if (d.list.length === 0) { }} //[!code ++]
|
||||
无数据
|
||||
{{#} }} //[!code --]
|
||||
{{} }} //[!code ++]
|
||||
</template>
|
||||
<script>
|
||||
layui.use(function(){
|
||||
var laytpl = layui.laytpl;
|
||||
|
||||
laytpl.config({
|
||||
tagStyle: 'modern'
|
||||
})
|
||||
})
|
||||
</script>
|
||||
</textarea>
|
||||
</pre>
|
||||
|
||||
<h2>普通示例</h2>
|
||||
|
||||
<pre><code class="layui-code" lay-options="{header: true}">
|
||||
code line
|
||||
code line
|
||||
|
@@ -71,3 +71,12 @@ html #layuicss-skincodecss{display: none; position: absolute; width: 1989px;}
|
||||
.layui-code-view.layui-code-hl > .layui-code-ln-side{background-color: transparent;}
|
||||
.layui-code-theme-dark.layui-code-hl,
|
||||
.layui-code-theme-dark.layui-code-hl > .layui-code-ln-side{border-color: rgb(126 122 122 / 15%);}
|
||||
|
||||
/*行高亮*/
|
||||
.layui-code-line-highlighted{background-color:rgba(142, 150, 170, .14)}
|
||||
.layui-code-line-diff-add{background-color: rgba(16, 185, 129, .14);}
|
||||
.layui-code-line-diff-remove{background-color: rgba(244, 63, 94, .14);}
|
||||
.layui-code-line-diff-add:before{position:absolute; content: "+"; color: #18794e;}
|
||||
.layui-code-line-diff-remove:before{position:absolute; content: "-"; color: #b8272c;}
|
||||
.layui-code-has-focused-lines .layui-code-line:not(.layui-code-line-has-focus) {filter: blur(.095rem); opacity: .7; -webkit-transition: filter .35s, opacity .35s; transition: filter .35s, opacity .35s;}
|
||||
.layui-code-has-focused-lines:hover .layui-code-line:not(.layui-code-line-has-focus) {filter: blur(); opacity: 1;}
|
||||
|
@@ -48,6 +48,30 @@ layui.define(['lay', 'i18n', 'util', 'element', 'tabs', 'form'], function(export
|
||||
lang: 'text', // 指定语言类型
|
||||
highlighter: false, // 是否开启语法高亮,'hljs','prism','shiki'
|
||||
langMarker: false, // 代码区域是否显示语言类型标记
|
||||
highlightLine: { // 行高亮
|
||||
// 聚焦
|
||||
focus: {
|
||||
range: '', // 高亮范围,不可全局设置值 '1,3-5,8'
|
||||
comment: false, // 是否解析注释,性能敏感不可全局开启 [!code type:<lines>]
|
||||
classActiveLine: 'layui-code-line-has-focus', // 添加到高亮行上的类
|
||||
classActivePre: 'layui-code-has-focused-lines' // 有高亮行时向根元素添加的类
|
||||
},
|
||||
// 高亮
|
||||
hl: {
|
||||
comment: false,
|
||||
classActiveLine: 'layui-code-line-highlighted',
|
||||
},
|
||||
// diff++
|
||||
'++':{
|
||||
comment: false,
|
||||
classActiveLine: 'layui-code-line-diff-add',
|
||||
},
|
||||
// diff--
|
||||
'--': {
|
||||
comment: false,
|
||||
classActiveLine: 'layui-code-line-diff-remove',
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// 初始索引
|
||||
@@ -61,6 +85,91 @@ layui.define(['lay', 'i18n', 'util', 'element', 'tabs', 'form'], function(export
|
||||
var trim = function(str){
|
||||
return trimEnd(str).replace(/^\n|\n$/, '');
|
||||
};
|
||||
|
||||
// '1,3-5,8' -> [1,3,4,5,8]
|
||||
var parseHighlightedLines = function(rangeStr){
|
||||
if (typeof rangeStr !== 'string') return [];
|
||||
var lines = $.map(rangeStr.split(','), function(v){
|
||||
var range = v.split('-');
|
||||
var start = parseInt(range[0], 10);
|
||||
var end = parseInt(range[1], 10);
|
||||
return start && end
|
||||
? $.map(new Array(end - start + 1), function(_, index){ return start + index })
|
||||
: start ? start : undefined
|
||||
})
|
||||
return lines;
|
||||
}
|
||||
|
||||
// 引用自 https://github.com/innocenzi/shiki-processor/blob/efa20624be415c866cc8e350d1ada886b6b5cd52/src/utils/create-range-processor.ts#L7
|
||||
// 添加了 HTML 注释支持,用来处理预览场景
|
||||
var highlightLineRegex = /(?:\/\/|\/\*{1,2}|<!--|<!--) *\[!code ([\w+-]+)(?::(\d+))?] *(?:\*{1,2}\/|-->|-->)?/;
|
||||
var preprocessHighlightLine = function (highlightLineOptions, codeLines) {
|
||||
var hasHighlightLine = false;
|
||||
var needParseComment = false;
|
||||
var lineClassMap = Object.create(null);
|
||||
var preClassMap = Object.create(null);
|
||||
|
||||
var updateLineClassMap = function (lineNumber, className) {
|
||||
if (!lineClassMap[lineNumber]) {
|
||||
lineClassMap[lineNumber] = [CONST.ELEM_LINE];
|
||||
}
|
||||
lineClassMap[lineNumber].push(className);
|
||||
}
|
||||
|
||||
// 收集高亮行 className
|
||||
$.each(highlightLineOptions, function (type, opts) {
|
||||
if (opts.range) {
|
||||
var highlightLines = parseHighlightedLines(opts.range);
|
||||
if (highlightLines.length > 0) {
|
||||
hasHighlightLine = true;
|
||||
if (opts.classActivePre) {
|
||||
preClassMap[opts.classActivePre] = true;
|
||||
}
|
||||
$.each(highlightLines, function (i, lineNumber) {
|
||||
updateLineClassMap(lineNumber, opts.classActiveLine);
|
||||
});
|
||||
}
|
||||
}
|
||||
if (opts.comment) {
|
||||
needParseComment = true;
|
||||
}
|
||||
});
|
||||
|
||||
// 解析行高亮注释并收集 className
|
||||
if (needParseComment) {
|
||||
$.each(codeLines, function (i, line) {
|
||||
var match = line.match(highlightLineRegex);
|
||||
if (match && match[1] && lay.hasOwn(highlightLineOptions, match[1])) {
|
||||
var opts = highlightLineOptions[match[1]];
|
||||
hasHighlightLine = true;
|
||||
if (opts.classActivePre) {
|
||||
preClassMap[opts.classActivePre] = true;
|
||||
}
|
||||
// 高亮的行数
|
||||
var lines = parseInt(match[2], 10)
|
||||
if (match[2] && lines && lines > 1) {
|
||||
var startLine = i + 1;
|
||||
var endLine = startLine + lines - 1;
|
||||
var highlightLines = parseHighlightedLines(startLine + '-' + endLine);
|
||||
if (highlightLines.length > 0) {
|
||||
$.each(highlightLines, function (i, lineNumber) {
|
||||
updateLineClassMap(lineNumber, opts.classActiveLine);
|
||||
});
|
||||
}
|
||||
}else{
|
||||
updateLineClassMap(i + 1, opts.classActiveLine);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
needParseComment: needParseComment,
|
||||
hasHighlightLine: hasHighlightLine,
|
||||
preClass: Object.keys(preClassMap).join(' '),
|
||||
lineClassMap: lineClassMap
|
||||
}
|
||||
}
|
||||
|
||||
// export api
|
||||
exports('code', function(options, mode){
|
||||
@@ -142,10 +251,16 @@ layui.define(['lay', 'i18n', 'util', 'element', 'tabs', 'form'], function(export
|
||||
// code 行
|
||||
var lines = String(html).split(/\r?\n/g);
|
||||
|
||||
// 预处理行高亮
|
||||
var highlightLineInfo = preprocessHighlightLine(options.highlightLine, lines);
|
||||
|
||||
// 包裹 code 行结构
|
||||
html = $.map(lines, function(line, num) {
|
||||
var lineClass = (highlightLineInfo.hasHighlightLine && highlightLineInfo.lineClassMap[num + 1])
|
||||
? highlightLineInfo.lineClassMap[num + 1].join(' ')
|
||||
: CONST.ELEM_LINE;
|
||||
return [
|
||||
'<div class="'+ CONST.ELEM_LINE +'">',
|
||||
'<div class="'+ lineClass + '">',
|
||||
(
|
||||
options.ln ? [
|
||||
'<div class="'+ CONST.ELEM_LINE_NUM +'">',
|
||||
@@ -154,12 +269,16 @@ layui.define(['lay', 'i18n', 'util', 'element', 'tabs', 'form'], function(export
|
||||
].join('') : ''
|
||||
),
|
||||
'<div class="layui-code-line-content">',
|
||||
(line || ' '),
|
||||
(highlightLineInfo.needParseComment ? line.replace(highlightLineRegex, '') : line) || ' ',
|
||||
'</div>',
|
||||
'</div>'
|
||||
].join('');
|
||||
});
|
||||
|
||||
if(highlightLineInfo.preClass){
|
||||
othis.addClass(highlightLineInfo.preClass)
|
||||
}
|
||||
|
||||
return {
|
||||
lines: lines,
|
||||
html: html
|
||||
|
@@ -2,83 +2,228 @@
|
||||
* slider 滑块组件
|
||||
*/
|
||||
|
||||
layui.define(['jquery', 'lay'], function(exports) {
|
||||
layui.define(['component', 'jquery', 'lay'], function(exports) {
|
||||
'use strict';
|
||||
|
||||
var $ = layui.$;
|
||||
var lay = layui.lay;
|
||||
|
||||
// 外部接口
|
||||
var slider = {
|
||||
config: {},
|
||||
index: layui.slider ? (layui.slider.index + 10000) : 0,
|
||||
|
||||
// 设置全局项
|
||||
set: function(options) {
|
||||
var that = this;
|
||||
that.config = $.extend({}, that.config, options);
|
||||
return that;
|
||||
var component = layui.component({
|
||||
name: 'slider',
|
||||
config: {
|
||||
type: 'default', //滑块类型,垂直:vertical
|
||||
min: 0, //最小值
|
||||
max: 100, //最大值,默认100
|
||||
value: 0, //初始值,默认为0
|
||||
step: 1, //间隔值
|
||||
showstep: false, //间隔点开启
|
||||
tips: true, //文字提示,开启
|
||||
tipsAlways: false, //文字提示,始终开启
|
||||
input: false, //输入框,关闭
|
||||
range: false, //范围选择,与输入框不能同时开启,默认关闭
|
||||
height: 200, //配合 type:"vertical" 使用,默认200px
|
||||
disabled: false, //滑块禁用,默认关闭
|
||||
theme: '#16baaa' //主题颜色
|
||||
},
|
||||
CONST: {
|
||||
ELEM_VIEW: 'layui-slider',
|
||||
SLIDER_BAR: 'layui-slider-bar',
|
||||
SLIDER_WRAP: 'layui-slider-wrap',
|
||||
SLIDER_WRAP_BTN: 'layui-slider-wrap-btn',
|
||||
SLIDER_TIPS: 'layui-slider-tips',
|
||||
SLIDER_INPUT: 'layui-slider-input',
|
||||
SLIDER_INPUT_TXT: 'layui-slider-input-txt',
|
||||
SLIDER_INPUT_BTN: 'layui-slider-input-btn',
|
||||
ELEM_HOVER: 'layui-slider-hover',
|
||||
},
|
||||
render: function (rerender) {
|
||||
var that = this;
|
||||
var options = that.config;
|
||||
|
||||
// 事件
|
||||
on: function(events, callback) {
|
||||
return layui.onevent.call(this, MOD_NAME, events, callback);
|
||||
//间隔值不能小于等于 0
|
||||
if (options.step <= 0) options.step = 1;
|
||||
|
||||
//最大值不能小于最小值
|
||||
if (options.max < options.min) options.max = options.min + options.step;
|
||||
|
||||
//判断是否开启双滑块
|
||||
if (options.range) {
|
||||
options.value = typeof (options.value) == 'object' ? options.value : [options.min, options.value];
|
||||
var minValue = Math.min(options.value[0], options.value[1])
|
||||
, maxValue = Math.max(options.value[0], options.value[1]);
|
||||
options.value[0] = Math.max(minValue, options.min);
|
||||
options.value[1] = Math.max(maxValue, options.min);
|
||||
options.value[0] = Math.min(options.value[0], options.max);
|
||||
options.value[1] = Math.min(options.value[1], options.max);
|
||||
|
||||
var scaleFir = (options.value[0] - options.min) / (options.max - options.min) * 100;
|
||||
var scaleSec = (options.value[1] - options.min) / (options.max - options.min) * 100;
|
||||
var scale = scaleSec - scaleFir + '%';
|
||||
scaleFir = scaleFir + '%';
|
||||
scaleSec = scaleSec + '%';
|
||||
} else {
|
||||
//如果初始值是一个数组,则获取数组的最小值
|
||||
if (typeof options.value == 'object') {
|
||||
options.value = Math.min.apply(null, options.value);
|
||||
}
|
||||
|
||||
//初始值不能小于最小值且不能大于最大值
|
||||
if (options.value < options.min) options.value = options.min;
|
||||
if (options.value > options.max) options.value = options.max;
|
||||
|
||||
var scale = (options.value - options.min) / (options.max - options.min) * 100 + '%';
|
||||
}
|
||||
|
||||
|
||||
//如果禁用,颜色为统一的灰色
|
||||
var theme = options.disabled ? '#c2c2c2' : options.theme;
|
||||
|
||||
//滑块
|
||||
var temp = '<div class="layui-slider ' + (options.type === 'vertical' ? 'layui-slider-vertical' : '') + '">' + (options.tips ? '<div class="' + CONST.SLIDER_TIPS + '" ' + (options.tipsAlways ? '' : 'style="display:none;"') + '></div>' : '') +
|
||||
'<div class="layui-slider-bar" style="background:' + theme + '; ' + (options.type === 'vertical' ? 'height' : 'width') + ':' + scale + ';' + (options.type === 'vertical' ? 'bottom' : 'left') + ':' + (scaleFir || 0) + ';"></div><div class="layui-slider-wrap" style="' + (options.type === 'vertical' ? 'bottom' : 'left') + ':' + (scaleFir || scale) + ';">' +
|
||||
'<div class="layui-slider-wrap-btn" style="border: 2px solid ' + theme + ';"></div></div>' + (options.range ? '<div class="layui-slider-wrap" style="' + (options.type === 'vertical' ? 'bottom' : 'left') + ':' + scaleSec + ';"><div class="layui-slider-wrap-btn" style="border: 2px solid ' + theme + ';"></div></div>' : '') + '</div>';
|
||||
|
||||
var othis = $(options.elem);
|
||||
var hasRender = othis.next('.' + CONST.ELEM_VIEW);
|
||||
//生成替代元素
|
||||
hasRender[0] && hasRender.remove(); //如果已经渲染,则Rerender
|
||||
that.elemTemp = $(temp);
|
||||
|
||||
//把数据缓存到滑块上
|
||||
if (options.range) {
|
||||
that.elemTemp.find('.' + CONST.SLIDER_WRAP).eq(0).data('value', options.value[0]);
|
||||
that.elemTemp.find('.' + CONST.SLIDER_WRAP).eq(1).data('value', options.value[1]);
|
||||
} else {
|
||||
that.elemTemp.find('.' + CONST.SLIDER_WRAP).data('value', options.value);
|
||||
}
|
||||
|
||||
//插入替代元素
|
||||
othis.html(that.elemTemp);
|
||||
|
||||
//垂直滑块
|
||||
if (options.type === 'vertical') {
|
||||
that.elemTemp.height(options.height + 'px');
|
||||
}
|
||||
|
||||
//显示间断点
|
||||
if (options.showstep) {
|
||||
var number = (options.max - options.min) / options.step, item = '';
|
||||
for (var i = 1; i < number + 1; i++) {
|
||||
var step = i * 100 / number;
|
||||
if (step < 100) {
|
||||
item += '<div class="layui-slider-step" style="' + (options.type === 'vertical' ? 'bottom' : 'left') + ':' + step + '%"></div>'
|
||||
}
|
||||
}
|
||||
that.elemTemp.append(item);
|
||||
}
|
||||
|
||||
//插入输入框
|
||||
if (options.input && !options.range) {
|
||||
var elemInput = $('<div class="layui-slider-input"><div class="layui-slider-input-txt"><input type="text" class="layui-input"></div><div class="layui-slider-input-btn"><i class="layui-icon layui-icon-up"></i><i class="layui-icon layui-icon-down"></i></div></div>');
|
||||
othis.css("position", "relative");
|
||||
othis.append(elemInput);
|
||||
othis.find('.' + CONST.SLIDER_INPUT_TXT).children('input').val(options.value);
|
||||
if (options.type === 'vertical') {
|
||||
elemInput.css({
|
||||
left: 0
|
||||
, top: -48
|
||||
});
|
||||
} else {
|
||||
that.elemTemp.css("margin-right", elemInput.outerWidth() + 15);
|
||||
}
|
||||
}
|
||||
|
||||
//给未禁止的滑块滑动事件
|
||||
if (!options.disabled) {
|
||||
that.slide();
|
||||
} else {
|
||||
that.elemTemp.addClass(CONST.CLASS_DISABLED);
|
||||
that.elemTemp.find('.' + CONST.SLIDER_WRAP_BTN).addClass(CONST.CLASS_DISABLED);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 设置提示文本内容
|
||||
* @param {Element} sliderWrapBtnElem 提示文本节点元素
|
||||
*/
|
||||
function setSliderTipsTxt(sliderWrapBtnElem) {
|
||||
var value = sliderWrapBtnElem.parent().data('value');
|
||||
var tipsTxt = options.setTips ? options.setTips(value) : value;
|
||||
that.elemTemp.find('.' + CONST.SLIDER_TIPS).html(tipsTxt);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 计算提示文本元素的 position left
|
||||
* @param {Element} sliderWrapBtnElem 提示文本节点元素
|
||||
*/
|
||||
function calcSliderTipsLeft(sliderWrapBtnElem) {
|
||||
var sliderWidth = options.type === 'vertical' ? options.height : that.elemTemp[0].offsetWidth;
|
||||
var sliderWrap = that.elemTemp.find('.' + CONST.SLIDER_WRAP);
|
||||
var tipsLeft = options.type === 'vertical' ? (sliderWidth - sliderWrapBtnElem.parent()[0].offsetTop - sliderWrap.height()) : sliderWrapBtnElem.parent()[0].offsetLeft;
|
||||
var left = tipsLeft / sliderWidth * 100;
|
||||
return left
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 设置提示文本元素的 position left
|
||||
* @param {number} left 要设置的 left 的大小
|
||||
*/
|
||||
function setSliderTipsLeft(left) {
|
||||
if (options.type === 'vertical') {
|
||||
that.elemTemp.find('.' + CONST.SLIDER_TIPS).css({
|
||||
"bottom": left + '%',
|
||||
"margin-bottom": "20px",
|
||||
"display": "inline-block"
|
||||
});
|
||||
} else {
|
||||
that.elemTemp.find('.' + CONST.SLIDER_TIPS).css({
|
||||
"left": left + '%',
|
||||
"display": "inline-block"
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
//判断是否要始终显示提示文本
|
||||
if (options.tips) {
|
||||
if (options.tipsAlways) {
|
||||
var sliderWrapBtnElem = that.elemTemp.find('.' + CONST.SLIDER_WRAP_BTN);
|
||||
setSliderTipsTxt(sliderWrapBtnElem)
|
||||
var left = calcSliderTipsLeft(sliderWrapBtnElem);
|
||||
setSliderTipsLeft(left)
|
||||
} else {
|
||||
//划过滑块显示数值
|
||||
var timer;
|
||||
that.elemTemp.find('.' + CONST.SLIDER_WRAP_BTN).on('mouseover', function () {
|
||||
setSliderTipsTxt($(this))
|
||||
var left = calcSliderTipsLeft($(this));
|
||||
clearTimeout(timer);
|
||||
timer = setTimeout(function () {
|
||||
setSliderTipsLeft(left)
|
||||
}, 300);
|
||||
}).on('mouseout', function () {
|
||||
clearTimeout(timer);
|
||||
if (!options.tipsAlways) {
|
||||
that.elemTemp.find('.' + CONST.SLIDER_TIPS).css("display", "none");
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
extendsInstance: function(){
|
||||
var that = this;
|
||||
var options = that.config;
|
||||
return {
|
||||
setValue: function (value, index) {
|
||||
value = value > options.max ? options.max : value;
|
||||
value = value < options.min ? options.min : value;
|
||||
options.value = value;
|
||||
return that.slide('set', value, index || 0);
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
// 操作当前实例
|
||||
var thisSlider = function(){
|
||||
var that = this;
|
||||
var options = that.config;
|
||||
|
||||
return {
|
||||
setValue: function(value, index){ // 设置值
|
||||
value = value > options.max ? options.max : value;
|
||||
value = value < options.min ? options.min : value;
|
||||
options.value = value;
|
||||
return that.slide('set', value, index || 0);
|
||||
},
|
||||
config: options
|
||||
}
|
||||
};
|
||||
|
||||
// 字符常量
|
||||
var MOD_NAME = 'slider';
|
||||
var DISABLED = 'layui-disabled';
|
||||
var ELEM_VIEW = 'layui-slider';
|
||||
var SLIDER_BAR = 'layui-slider-bar';
|
||||
var SLIDER_WRAP = 'layui-slider-wrap';
|
||||
var SLIDER_WRAP_BTN = 'layui-slider-wrap-btn';
|
||||
var SLIDER_TIPS = 'layui-slider-tips';
|
||||
var SLIDER_INPUT = 'layui-slider-input';
|
||||
var SLIDER_INPUT_TXT = 'layui-slider-input-txt';
|
||||
var SLIDER_INPUT_BTN = 'layui-slider-input-btn';
|
||||
var ELEM_HOVER = 'layui-slider-hover';
|
||||
|
||||
// 构造器
|
||||
var Class = function(options){
|
||||
var that = this;
|
||||
that.index = ++slider.index;
|
||||
that.config = $.extend({}, that.config, slider.config, options);
|
||||
that.render();
|
||||
};
|
||||
|
||||
// 默认配置
|
||||
Class.prototype.config = {
|
||||
type: 'default', //滑块类型,垂直:vertical
|
||||
min: 0, //最小值
|
||||
max: 100, //最大值,默认100
|
||||
value: 0, //初始值,默认为0
|
||||
step: 1, //间隔值
|
||||
showstep: false, //间隔点开启
|
||||
tips: true, //文字提示,开启
|
||||
tipsAlways: false, //文字提示,始终开启
|
||||
input: false, //输入框,关闭
|
||||
range: false, //范围选择,与输入框不能同时开启,默认关闭
|
||||
height: 200, //配合 type:"vertical" 使用,默认200px
|
||||
disabled: false, //滑块禁用,默认关闭
|
||||
theme: '#16baaa' //主题颜色
|
||||
};
|
||||
var CONST = component.CONST;
|
||||
var Class = component.Class;
|
||||
|
||||
// 数值精度
|
||||
Class.prototype.precision = function(){
|
||||
@@ -91,196 +236,6 @@ layui.define(['jquery', 'lay'], function(exports) {
|
||||
return Math.max.apply(null, precisions);
|
||||
}
|
||||
|
||||
//滑块渲染
|
||||
Class.prototype.render = function(){
|
||||
var that = this;
|
||||
var options = that.config;
|
||||
|
||||
// 若 elem 非唯一,则拆分为多个实例
|
||||
var elem = $(options.elem);
|
||||
if(elem.length > 1){
|
||||
layui.each(elem, function(){
|
||||
slider.render($.extend({}, options, {
|
||||
elem: this
|
||||
}));
|
||||
});
|
||||
return that;
|
||||
}
|
||||
|
||||
// 合并 lay-options 属性上的配置信息
|
||||
$.extend(options, lay.options(elem[0]));
|
||||
|
||||
//间隔值不能小于等于 0
|
||||
if(options.step <= 0) options.step = 1;
|
||||
|
||||
//最大值不能小于最小值
|
||||
if(options.max < options.min) options.max = options.min + options.step;
|
||||
|
||||
|
||||
|
||||
//判断是否开启双滑块
|
||||
if(options.range){
|
||||
options.value = typeof(options.value) == 'object' ? options.value : [options.min, options.value];
|
||||
var minValue = Math.min(options.value[0], options.value[1])
|
||||
,maxValue = Math.max(options.value[0], options.value[1]);
|
||||
options.value[0] = Math.max(minValue,options.min);
|
||||
options.value[1] = Math.max(maxValue,options.min);
|
||||
options.value[0] = Math.min(options.value[0],options.max);
|
||||
options.value[1] = Math.min(options.value[1],options.max);
|
||||
|
||||
var scaleFir = (options.value[0] - options.min) / (options.max - options.min) * 100;
|
||||
var scaleSec = (options.value[1] - options.min) / (options.max - options.min) * 100;
|
||||
var scale = scaleSec - scaleFir + '%';
|
||||
scaleFir = scaleFir + '%';
|
||||
scaleSec = scaleSec + '%';
|
||||
} else {
|
||||
//如果初始值是一个数组,则获取数组的最小值
|
||||
if(typeof options.value == 'object'){
|
||||
options.value = Math.min.apply(null, options.value);
|
||||
}
|
||||
|
||||
//初始值不能小于最小值且不能大于最大值
|
||||
if(options.value < options.min) options.value = options.min;
|
||||
if(options.value > options.max) options.value = options.max;
|
||||
|
||||
var scale = (options.value - options.min) / (options.max - options.min) * 100 + '%';
|
||||
}
|
||||
|
||||
|
||||
//如果禁用,颜色为统一的灰色
|
||||
var theme = options.disabled ? '#c2c2c2' : options.theme;
|
||||
|
||||
//滑块
|
||||
var temp = '<div class="layui-slider '+ (options.type === 'vertical' ? 'layui-slider-vertical' : '') +'">'+ (options.tips ? '<div class="'+ SLIDER_TIPS +'" '+ (options.tipsAlways ? '' : 'style="display:none;"') +'></div>' : '') +
|
||||
'<div class="layui-slider-bar" style="background:'+ theme +'; '+ (options.type === 'vertical' ? 'height' : 'width') +':'+ scale +';'+ (options.type === 'vertical' ? 'bottom' : 'left') +':'+ (scaleFir || 0) +';"></div><div class="layui-slider-wrap" style="'+ (options.type === 'vertical' ? 'bottom' : 'left') +':'+ (scaleFir || scale) +';">' +
|
||||
'<div class="layui-slider-wrap-btn" style="border: 2px solid '+ theme +';"></div></div>'+ (options.range ? '<div class="layui-slider-wrap" style="'+ (options.type === 'vertical' ? 'bottom' : 'left') +':'+ scaleSec +';"><div class="layui-slider-wrap-btn" style="border: 2px solid '+ theme +';"></div></div>' : '') +'</div>';
|
||||
|
||||
var othis = $(options.elem);
|
||||
var hasRender = othis.next('.' + ELEM_VIEW);
|
||||
//生成替代元素
|
||||
hasRender[0] && hasRender.remove(); //如果已经渲染,则Rerender
|
||||
that.elemTemp = $(temp);
|
||||
|
||||
//把数据缓存到滑块上
|
||||
if(options.range){
|
||||
that.elemTemp.find('.' + SLIDER_WRAP).eq(0).data('value', options.value[0]);
|
||||
that.elemTemp.find('.' + SLIDER_WRAP).eq(1).data('value', options.value[1]);
|
||||
}else{
|
||||
that.elemTemp.find('.' + SLIDER_WRAP).data('value', options.value);
|
||||
}
|
||||
|
||||
//插入替代元素
|
||||
othis.html(that.elemTemp);
|
||||
|
||||
//垂直滑块
|
||||
if(options.type === 'vertical'){
|
||||
that.elemTemp.height(options.height + 'px');
|
||||
}
|
||||
|
||||
//显示间断点
|
||||
if(options.showstep){
|
||||
var number = (options.max - options.min) / options.step, item = '';
|
||||
for(var i = 1; i < number + 1; i++) {
|
||||
var step = i * 100 / number;
|
||||
if(step < 100){
|
||||
item += '<div class="layui-slider-step" style="'+ (options.type === 'vertical' ? 'bottom' : 'left') +':'+ step +'%"></div>'
|
||||
}
|
||||
}
|
||||
that.elemTemp.append(item);
|
||||
}
|
||||
|
||||
//插入输入框
|
||||
if(options.input && !options.range){
|
||||
var elemInput = $('<div class="layui-slider-input"><div class="layui-slider-input-txt"><input type="text" class="layui-input"></div><div class="layui-slider-input-btn"><i class="layui-icon layui-icon-up"></i><i class="layui-icon layui-icon-down"></i></div></div>');
|
||||
othis.css("position","relative");
|
||||
othis.append(elemInput);
|
||||
othis.find('.' + SLIDER_INPUT_TXT).children('input').val(options.value);
|
||||
if(options.type === 'vertical'){
|
||||
elemInput.css({
|
||||
left: 0
|
||||
,top: -48
|
||||
});
|
||||
} else {
|
||||
that.elemTemp.css("margin-right", elemInput.outerWidth() + 15);
|
||||
}
|
||||
}
|
||||
|
||||
//给未禁止的滑块滑动事件
|
||||
if(!options.disabled){
|
||||
that.slide();
|
||||
}else{
|
||||
that.elemTemp.addClass(DISABLED);
|
||||
that.elemTemp.find('.' + SLIDER_WRAP_BTN).addClass(DISABLED);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 设置提示文本内容
|
||||
* @param {Element} sliderWrapBtnElem 提示文本节点元素
|
||||
*/
|
||||
function setSliderTipsTxt(sliderWrapBtnElem) {
|
||||
var value = sliderWrapBtnElem.parent().data('value');
|
||||
var tipsTxt = options.setTips ? options.setTips(value) : value;
|
||||
that.elemTemp.find('.' + SLIDER_TIPS).html(tipsTxt);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 计算提示文本元素的 position left
|
||||
* @param {Element} sliderWrapBtnElem 提示文本节点元素
|
||||
*/
|
||||
function calcSliderTipsLeft(sliderWrapBtnElem){
|
||||
var sliderWidth = options.type === 'vertical' ? options.height : that.elemTemp[0].offsetWidth;
|
||||
var sliderWrap = that.elemTemp.find('.' + SLIDER_WRAP);
|
||||
var tipsLeft = options.type === 'vertical' ? (sliderWidth - sliderWrapBtnElem.parent()[0].offsetTop - sliderWrap.height()) : sliderWrapBtnElem.parent()[0].offsetLeft;
|
||||
var left = tipsLeft / sliderWidth * 100;
|
||||
return left
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 设置提示文本元素的 position left
|
||||
* @param {number} left 要设置的 left 的大小
|
||||
*/
|
||||
function setSliderTipsLeft(left) {
|
||||
if(options.type === 'vertical'){
|
||||
that.elemTemp.find('.' + SLIDER_TIPS).css({
|
||||
"bottom": left + '%',
|
||||
"margin-bottom": "20px",
|
||||
"display": "inline-block"
|
||||
});
|
||||
} else {
|
||||
that.elemTemp.find('.' + SLIDER_TIPS).css({
|
||||
"left": left + '%',
|
||||
"display": "inline-block"
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
//判断是否要始终显示提示文本
|
||||
if(options.tips){
|
||||
if(options.tipsAlways){
|
||||
var sliderWrapBtnElem = that.elemTemp.find('.' + SLIDER_WRAP_BTN);
|
||||
setSliderTipsTxt(sliderWrapBtnElem)
|
||||
var left = calcSliderTipsLeft(sliderWrapBtnElem);
|
||||
setSliderTipsLeft(left)
|
||||
}else{
|
||||
//划过滑块显示数值
|
||||
var timer;
|
||||
that.elemTemp.find('.' + SLIDER_WRAP_BTN).on('mouseover', function(){
|
||||
setSliderTipsTxt($(this))
|
||||
var left = calcSliderTipsLeft($(this));
|
||||
clearTimeout(timer);
|
||||
timer = setTimeout(function(){
|
||||
setSliderTipsLeft(left)
|
||||
}, 300);
|
||||
}).on('mouseout', function(){
|
||||
clearTimeout(timer);
|
||||
if(!options.tipsAlways){
|
||||
that.elemTemp.find('.' + SLIDER_TIPS).css("display", "none");
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
//滑块滑动
|
||||
Class.prototype.slide = function(setValue, value, i){
|
||||
var that = this;
|
||||
@@ -289,9 +244,9 @@ layui.define(['jquery', 'lay'], function(exports) {
|
||||
var sliderWidth = function(){
|
||||
return options.type === 'vertical' ? options.height : sliderAct[0].offsetWidth
|
||||
};
|
||||
var sliderWrap = sliderAct.find('.' + SLIDER_WRAP);
|
||||
var sliderTxt = sliderAct.next('.' + SLIDER_INPUT);
|
||||
var inputValue = sliderTxt.children('.' + SLIDER_INPUT_TXT).children('input').val();
|
||||
var sliderWrap = sliderAct.find('.' + CONST.SLIDER_WRAP);
|
||||
var sliderTxt = sliderAct.next('.' + CONST.SLIDER_INPUT);
|
||||
var inputValue = sliderTxt.children('.' + CONST.SLIDER_INPUT_TXT).children('input').val();
|
||||
var step = 100 / ((options.max - options.min) / options.step);
|
||||
var precision = that.precision();
|
||||
var change = function(offsetValue, index, from){
|
||||
@@ -306,27 +261,27 @@ layui.define(['jquery', 'lay'], function(exports) {
|
||||
var firLeft = valueTo(sliderWrap[0].offsetLeft);
|
||||
var secLeft = options.range ? valueTo(sliderWrap[1].offsetLeft) : 0;
|
||||
if(options.type === 'vertical'){
|
||||
sliderAct.find('.' + SLIDER_TIPS).css({"bottom":offsetValue + '%', "margin-bottom":"20px"});
|
||||
sliderAct.find('.' + CONST.SLIDER_TIPS).css({"bottom":offsetValue + '%', "margin-bottom":"20px"});
|
||||
firLeft = valueTo(sliderWidth() - sliderWrap[0].offsetTop - sliderWrap.height());
|
||||
secLeft = options.range ? valueTo(sliderWidth() - sliderWrap[1].offsetTop - sliderWrap.height()) : 0;
|
||||
}else{
|
||||
sliderAct.find('.' + SLIDER_TIPS).css("left",offsetValue + '%');
|
||||
sliderAct.find('.' + CONST.SLIDER_TIPS).css("left",offsetValue + '%');
|
||||
}
|
||||
firLeft = firLeft > 100 ? 100: firLeft;
|
||||
secLeft = secLeft > 100 ? 100: secLeft;
|
||||
var minLeft = Math.min(firLeft, secLeft)
|
||||
,wrapWidth = Math.abs(firLeft - secLeft);
|
||||
if(options.type === 'vertical'){
|
||||
sliderAct.find('.' + SLIDER_BAR).css({"height":wrapWidth + '%', "bottom":minLeft + '%'});
|
||||
sliderAct.find('.' + CONST.SLIDER_BAR).css({"height":wrapWidth + '%', "bottom":minLeft + '%'});
|
||||
}else{
|
||||
sliderAct.find('.' + SLIDER_BAR).css({"width":wrapWidth + '%', "left":minLeft + '%'});
|
||||
sliderAct.find('.' + CONST.SLIDER_BAR).css({"width":wrapWidth + '%', "left":minLeft + '%'});
|
||||
}
|
||||
var selfValue = options.min + (options.max - options.min) * offsetValue / 100;
|
||||
selfValue = Number(parseFloat(selfValue).toFixed(precision));
|
||||
inputValue = selfValue;
|
||||
sliderTxt.children('.' + SLIDER_INPUT_TXT).children('input').val(inputValue);
|
||||
sliderTxt.children('.' + CONST.SLIDER_INPUT_TXT).children('input').val(inputValue);
|
||||
sliderWrap.eq(index).data('value', selfValue);
|
||||
sliderAct.find('.' + SLIDER_TIPS).html(options.setTips ? options.setTips(selfValue) : selfValue);
|
||||
sliderAct.find('.' + CONST.SLIDER_TIPS).html(options.setTips ? options.setTips(selfValue) : selfValue);
|
||||
|
||||
//如果开启范围选择,则返回数组值
|
||||
if(options.range){
|
||||
@@ -384,7 +339,7 @@ layui.define(['jquery', 'lay'], function(exports) {
|
||||
}
|
||||
|
||||
//滑块滑动
|
||||
sliderAct.find('.' + SLIDER_WRAP_BTN).each(function(index){
|
||||
sliderAct.find('.' + CONST.SLIDER_WRAP_BTN).each(function(index){
|
||||
var othis = $(this);
|
||||
othis.on('mousedown touchstart', function(e){
|
||||
e = e || window.event;
|
||||
@@ -411,16 +366,16 @@ layui.define(['jquery', 'lay'], function(exports) {
|
||||
if(left > sliderWidth())left = sliderWidth();
|
||||
var reaLeft = left / sliderWidth() * 100 / step;
|
||||
change(reaLeft, index);
|
||||
othis.addClass(ELEM_HOVER);
|
||||
sliderAct.find('.' + SLIDER_TIPS).show();
|
||||
othis.addClass(CONST.ELEM_HOVER);
|
||||
sliderAct.find('.' + CONST.SLIDER_TIPS).show();
|
||||
e.preventDefault();
|
||||
};
|
||||
|
||||
var up = function(delay){
|
||||
othis.removeClass(ELEM_HOVER);
|
||||
othis.removeClass(CONST.ELEM_HOVER);
|
||||
if(!options.tipsAlways){
|
||||
setTimeout(function(){
|
||||
sliderAct.find('.' + SLIDER_TIPS).hide();
|
||||
sliderAct.find('.' + CONST.SLIDER_TIPS).hide();
|
||||
}, delay);
|
||||
}
|
||||
};
|
||||
@@ -431,7 +386,7 @@ layui.define(['jquery', 'lay'], function(exports) {
|
||||
|
||||
// 点击滑块
|
||||
sliderAct.on('click', function(e){
|
||||
var main = $('.' + SLIDER_WRAP_BTN);
|
||||
var main = $('.' + CONST.SLIDER_WRAP_BTN);
|
||||
var othis = $(this);
|
||||
if(!main.is(event.target) && main.has(event.target).length === 0 && main.length){
|
||||
var index;
|
||||
@@ -457,9 +412,9 @@ layui.define(['jquery', 'lay'], function(exports) {
|
||||
});
|
||||
|
||||
//点击加减输入框
|
||||
sliderTxt.children('.' + SLIDER_INPUT_BTN).children('i').each(function(index){
|
||||
sliderTxt.children('.' + CONST.SLIDER_INPUT_BTN).children('i').each(function(index){
|
||||
$(this).on('click', function(){
|
||||
inputValue = sliderTxt.children('.' + SLIDER_INPUT_TXT).children('input').val();
|
||||
inputValue = sliderTxt.children('.' + CONST.SLIDER_INPUT_TXT).children('input').val();
|
||||
if(index == 1){ //减
|
||||
inputValue = inputValue - options.step < options.min
|
||||
? options.min
|
||||
@@ -484,7 +439,7 @@ layui.define(['jquery', 'lay'], function(exports) {
|
||||
var inputScale = (realValue - options.min) / (options.max - options.min) * 100 / step;
|
||||
change(inputScale, 0, 'done');
|
||||
};
|
||||
sliderTxt.children('.' + SLIDER_INPUT_TXT).children('input').on('keydown', function(e){
|
||||
sliderTxt.children('.' + CONST.SLIDER_INPUT_TXT).children('input').on('keydown', function(e){
|
||||
if(e.keyCode === 13){
|
||||
e.preventDefault();
|
||||
getInputValue.call(this);
|
||||
@@ -492,17 +447,5 @@ layui.define(['jquery', 'lay'], function(exports) {
|
||||
}).on('change', getInputValue);
|
||||
};
|
||||
|
||||
//事件处理
|
||||
Class.prototype.events = function(){
|
||||
var that = this;
|
||||
var options = that.config;
|
||||
};
|
||||
|
||||
//核心入口
|
||||
slider.render = function(options){
|
||||
var inst = new Class(options);
|
||||
return thisSlider.call(inst);
|
||||
};
|
||||
|
||||
exports(MOD_NAME, slider);
|
||||
exports(CONST.MOD_NAME, component);
|
||||
})
|
||||
|
Reference in New Issue
Block a user