mirror of https://github.com/layui/layui
236 lines
7.4 KiB
JavaScript
236 lines
7.4 KiB
JavaScript
import lay from './lay.js';
|
|
import { component as component$1 } from './component.js';
|
|
import $ from 'jquery';
|
|
|
|
/**
|
|
* rate
|
|
* 评分组件
|
|
*/
|
|
|
|
|
|
// 创建组件
|
|
var component = component$1({
|
|
name: 'rate',
|
|
|
|
// 默认配置
|
|
config: {
|
|
length: 5, // 评分的最大长度值
|
|
value: 0, // 评分的初始值
|
|
half: false, // 是否可以选择半星
|
|
text: false, // 是否显示评分对应的文本
|
|
readonly: false, // 是否只读
|
|
theme: '' // 主题颜色
|
|
},
|
|
|
|
CONST: {
|
|
ELEM: 'layui-rate',
|
|
ICON_RATE: 'layui-icon-rate',
|
|
ICON_RATE_SOLID: 'layui-icon-rate-solid',
|
|
ICON_RATE_HALF: 'layui-icon-rate-half',
|
|
ICON_SOLID_HALF: 'layui-icon-rate-solid layui-icon-rate-half',
|
|
ICON_SOLID_RATE: 'layui-icon-rate-solid layui-icon-rate',
|
|
ICON_HALF_RATE: 'layui-icon-rate layui-icon-rate-half',
|
|
},
|
|
|
|
// 渲染
|
|
render: function() {
|
|
var that = this;
|
|
var options = that.config;
|
|
|
|
// 自定义主题
|
|
var style = options.theme ? ('style="color: '+ options.theme + ';"') : '';
|
|
|
|
// 最大值不能大于总长度
|
|
if (options.value > options.length) {
|
|
options.value = options.length;
|
|
}
|
|
|
|
// 如果没有选择半星的属性,却给了小数的数值,统一向上或向下取整
|
|
if (parseInt(options.value) !== options.value) {
|
|
if (!options.half) {
|
|
options.value = (Math.ceil(options.value) - options.value) < 0.5
|
|
? Math.ceil(options.value)
|
|
: Math.floor(options.value);
|
|
}
|
|
}
|
|
|
|
// 组件模板
|
|
var template = '<ul class="layui-rate" '+ (options.readonly ? 'readonly' : '') +'>';
|
|
for (var i = 1; i <= options.length; i++) {
|
|
var item = '<li class="layui-inline"><i class="layui-icon '
|
|
+ (i > Math.floor(options.value) ? CONST.ICON_RATE : CONST.ICON_RATE_SOLID)
|
|
+ '" '+ style +'></i></li>';
|
|
if (options.half && parseInt(options.value) !== options.value && i == Math.ceil(options.value)) {
|
|
template = template + '<li><i class="layui-icon layui-icon-rate-half" '+ style +'></i></li>';
|
|
} else {
|
|
template = template + item;
|
|
}
|
|
}
|
|
template += '</ul>';
|
|
|
|
if (options.text) {
|
|
template += '<span class="layui-inline">'+ options.value + '</span>';
|
|
}
|
|
|
|
// 开始插入替代元素
|
|
var othis = options.elem;
|
|
var hasRender = othis.next('.' + CONST.ELEM);
|
|
|
|
// 生成替代元素
|
|
hasRender[0] && hasRender.remove(); // 如果已经渲染,则 Rerender
|
|
that.elemTemplate = $(template);
|
|
|
|
options.span = that.elemTemplate.next('span');
|
|
options.setText && options.setText(options.value);
|
|
|
|
othis.html(that.elemTemplate);
|
|
othis.addClass("layui-inline");
|
|
|
|
// 若非只读,则添加触控事件
|
|
if (!options.readonly) {
|
|
that.action();
|
|
}
|
|
},
|
|
|
|
// 扩展实例方法
|
|
extendsInstance: function() {
|
|
var that = this;
|
|
var options = that.config;
|
|
return {
|
|
setvalue: function (value) {
|
|
options.value = value;
|
|
that.render();
|
|
}
|
|
};
|
|
}
|
|
});
|
|
|
|
var CONST = component.CONST;
|
|
|
|
/**
|
|
* 扩展组件原型方法
|
|
*/
|
|
|
|
var Class = component.Class;
|
|
|
|
// li 相关事件
|
|
Class.prototype.action = function() {
|
|
var that = this;
|
|
var options = that.config;
|
|
var _ul = that.elemTemplate;
|
|
var wide = _ul.find("i").width();
|
|
var liElems = _ul.children("li");
|
|
|
|
liElems.each(function(index) {
|
|
var ind = index + 1;
|
|
var othis = $(this);
|
|
|
|
// 点击
|
|
othis.on('click', function(e) {
|
|
// 将当前点击li的索引值赋给 value
|
|
options.value = ind;
|
|
if (options.half) {
|
|
// 获取鼠标在 li 上的位置
|
|
var x = e.pageX - $(this).offset().left;
|
|
if (x <= wide / 2) {
|
|
options.value = options.value - 0.5;
|
|
}
|
|
}
|
|
|
|
if (options.text) {
|
|
_ul.next("span").text(options.value);
|
|
}
|
|
|
|
options.choose && options.choose(options.value);
|
|
options.setText && options.setText(options.value);
|
|
});
|
|
|
|
// 移入
|
|
othis.on('mousemove', function(e) {
|
|
_ul.find("i").each(function() {
|
|
$(this).addClass(CONST.ICON_RATE).removeClass(CONST.ICON_SOLID_HALF);
|
|
});
|
|
_ul.find("i:lt(" + ind + ")").each(function() {
|
|
$(this).addClass(CONST.ICON_RATE_SOLID).removeClass(CONST.ICON_HALF_RATE);
|
|
});
|
|
// 如果设置可选半星,那么判断鼠标相对 li 的位置
|
|
if (options.half) {
|
|
var x = e.pageX - $(this).offset().left;
|
|
if (x <= wide / 2) {
|
|
othis.children("i").addClass(CONST.ICON_RATE_HALF).removeClass(CONST.ICON_RATE_SOLID);
|
|
}
|
|
}
|
|
});
|
|
|
|
// 移出
|
|
othis.on('mouseleave', function() {
|
|
_ul.find("i").each(function() {
|
|
$(this).addClass(CONST.ICON_RATE).removeClass(CONST.ICON_SOLID_HALF);
|
|
});
|
|
_ul.find("i:lt(" + Math.floor(options.value) + ")").each(function() {
|
|
$(this).addClass(CONST.ICON_RATE_SOLID).removeClass(CONST.ICON_HALF_RATE);
|
|
});
|
|
// 如果设置可选半星,根据分数判断是否有半星
|
|
if (options.half) {
|
|
if (parseInt(options.value) !== options.value) {
|
|
_ul.children("li:eq(" + Math.floor(options.value) + ")").children("i").addClass(CONST.ICON_RATE_HALF).removeClass(CONST.ICON_SOLID_RATE);
|
|
}
|
|
}
|
|
});
|
|
|
|
});
|
|
|
|
lay.touchSwipe(_ul, {
|
|
onTouchMove: function(e, state) {
|
|
if(Date.now() - state.timeStart <= 200) return;
|
|
var pageX = e.touches[0].pageX;
|
|
var rateElemWidth = _ul.width();
|
|
var itemElemWidth = rateElemWidth / options.length; // 单颗星的宽度
|
|
var offsetX = pageX - _ul.offset().left;
|
|
var num = offsetX / itemElemWidth; // 原始值
|
|
var remainder = num % 1;
|
|
var integer = num - remainder;
|
|
|
|
// 最终值
|
|
var score = remainder <= 0.5 && options.half ? integer + 0.5 : Math.ceil(num);
|
|
if(score > options.length) score = options.length;
|
|
if(score < 0) score = 0;
|
|
|
|
liElems.each(function(index) {
|
|
var iconElem = $(this).children('i');
|
|
var isActiveIcon = (Math.ceil(score) - index === 1);
|
|
var needSelect = Math.ceil(score) > index;
|
|
var shouldHalfIcon = (score - index === 0.5);
|
|
|
|
if (needSelect) {
|
|
// 设置选中样式
|
|
iconElem.addClass(CONST.ICON_RATE_SOLID).removeClass(CONST.ICON_HALF_RATE);
|
|
if(options.half && shouldHalfIcon){
|
|
iconElem.addClass(CONST.ICON_RATE_HALF).removeClass(CONST.ICON_RATE_SOLID);
|
|
}
|
|
} else {
|
|
// 恢复初始样式
|
|
iconElem.addClass(CONST.ICON_RATE).removeClass(CONST.ICON_SOLID_HALF);
|
|
}
|
|
|
|
// 设置缩放样式
|
|
iconElem.toggleClass('layui-rate-hover', isActiveIcon);
|
|
});
|
|
|
|
// 更新最终值
|
|
options.value = score;
|
|
if(options.text) _ul.next("span").text(options.value);
|
|
options.setText && options.setText(options.value);
|
|
},
|
|
onTouchEnd: function(e, state) {
|
|
if(Date.now() - state.timeStart <= 200) return;
|
|
_ul.find('i').removeClass('layui-rate-hover');
|
|
options.choose && options.choose(options.value);
|
|
options.setText && options.setText(options.value);
|
|
}
|
|
});
|
|
};
|
|
|
|
export { component as default, component as rate };
|
|
//# sourceMappingURL=rate.js.map
|