/*!
* mobileSelect.js
* (c) 2017-present onlyhom
* Released under the MIT License.
* https://demo.demohuo.top/jquery/25/2534/demo/
*/
window.MobileSelect = (function() {
function getClass(dom, string) {
return dom.getElementsByClassName(string);
}
//构造器
function MobileSelect(config) {
this.mobileSelect;
this.wheelsData = config.wheels;
this.jsonType = false;
this.multiple = config.multiple
this.jsonData = [];
this.checkDataType();
this.renderWheels(this.wheelsData);
this.displayJson = [];
this.cascade = false;
this.startY;
this.moveEndY;
this.moveY;
this.oldMoveY;
this.offset = 0;
this.offsetSum = 0;
this.oversizeBorder;
this.curDistance = [];
this.clickStatus = false;
this.setValueOffset = config.setValueOffset==null?2:config.setValueOffset
this.showNum = config.showNum==null?5:config.showNum
this.init(config);
}
MobileSelect.prototype = {
constructor: MobileSelect,
init: function(config) {
var _this = this;
_this.trigger = document.querySelector(config.trigger);
_this.wheel = getClass(_this.mobileSelect, 'wheel'); //wheel 数组
_this.slider = getClass(_this.mobileSelect, 'selectContainer'); // slider 数组
_this.wheels = _this.mobileSelect.querySelector('.wheels'); //wheels
_this.liHeight = _this.mobileSelect.querySelector('li') && _this.mobileSelect.querySelector('li').offsetHeight || 0;
_this.ensureBtn = _this.mobileSelect.querySelector('.ensure');
_this.closeBtn = _this.mobileSelect.querySelector('.cancel');
_this.grayLayer = _this.mobileSelect.querySelector('.grayLayer');
_this.popUp = _this.mobileSelect.querySelector('.select-content');
_this.callback = config.callback ? config.callback : function() {};
_this.transitionEnd = config.transitionEnd ? config.transitionEnd : function() {};
_this.initPosition = config.position ? config.position : [];
_this.titleText = config.title ? config.title : '';
_this.cancelText = config.cancelText ? config.cancelText : '';
_this.ensureText = config.ensureText ? config.ensureText : '';
_this.trigger.style.cursor = 'pointer';
_this.setTitle(_this.titleText);
_this.checkCascade();
if (_this.cascade) {
_this.initCascade();
}
//定位 初始位置
if (_this.initPosition.length == 0) {
for (var i = 0; i < _this.slider.length; i++) {
_this.initPosition.push(0);
}
}
_this.setCurDistance(_this.initPosition);
_this.addListenerAll();
//按钮监听
_this.closeBtn.addEventListener('click', function() {
_this.mobileSelect.classList.remove('mobileSelect-show');
});
_this.ensureBtn.addEventListener('click', function() {
_this.mobileSelect.classList.remove('mobileSelect-show');
var tempValue;
for (var i = 0; i < _this.wheel.length; i++) {
if (tempValue) {
tempValue.child = _this.getValue(i)
} else {
tempValue = _this.getValue(i)
}
}
if (tempValue.child) {
$(_this.trigger).find(".J-select-text").val(tempValue.child.name).trigger("change")
$(_this.trigger).find(".J-select-value").val(tempValue.child.value).trigger("change")
$(_this.trigger).find(".J-select-parent-value").val(tempValue.value).trigger("change")
} else if (_this.multiple) {
var $selectAll = $(_this.popUp).find(".checkboxtext input.J-select-all-ipt");
if( $selectAll.prop("checked")){
tempValue = { name: $selectAll.parents(".multiple-item").data("name"), value: $selectAll.parents(".multiple-item").data("value") };
}else{
var names = [];
var values = [];
$(_this.popUp).find(".checkboxtext input").not(".J-select-all-ipt").each(function(){
if($(this).prop("checked")){
names.push($(this).parents(".multiple-item").data("name"))
values.push($(this).parents(".multiple-item").data("value"))
}
})
tempValue = { name: names.join(","), value: values.join(",") };
}
$(_this.trigger).find(".J-select-text").val(tempValue.name).trigger("change")
$(_this.trigger).find(".J-select-value").val(tempValue.value).trigger("change")
} else {
$(_this.trigger).find(".J-select-text").val(tempValue.name).trigger("change")
$(_this.trigger).find(".J-select-value").val(tempValue.value).trigger("change")
}
_this.callback(_this.getIndexArr(), _this.getJson());
});
if (_this.multiple) {
$(_this.popUp).find(".multiple-item").on("click",function(e){
if(e.target.nodeName=="INPUT"||e.target.nodeName=="LABEL"){
return;
}
if($(this).find("input").prop("checked")){
$(this).find("input").prop("checked",false).trigger("change")
}else{
$(this).find("input").prop("checked",true).trigger("change")}
});
$(_this.popUp).find(".checkboxtext input").on("change",function(){
if($(this).hasClass("J-select-all-ipt")){
if($(this).prop("checked")){
$(_this.popUp).find(".checkboxtext input").not(".J-select-all-ipt").prop("checked",true)
}else{
$(_this.popUp).find(".checkboxtext input").not(".J-select-all-ipt").prop("checked",false)
}
}else{
var allSelect = true;
$(_this.popUp).find(".checkboxtext input").not(".J-select-all-ipt").each(function(){
if(!$(this).prop("checked")){
allSelect = false;
return false;
}
})
if(allSelect){
$(_this.popUp).find(".checkboxtext input.J-select-all-ipt").prop("checked",true)
}else{
$(_this.popUp).find(".checkboxtext input.J-select-all-ipt").prop("checked",false)
}
}
})
}
_this.trigger.addEventListener('click', function() {
_this.mobileSelect.classList.add('mobileSelect-show');
_this.setActive();
});
_this.grayLayer.addEventListener('click', function() {
_this.mobileSelect.classList.remove('mobileSelect-show');
});
_this.popUp.addEventListener('click', function() {
event.stopPropagation();
});
_this.fixRowStyle(); //修正列数
},
setActive: function() {
var _this = this;
for (var i = 0; i < _this.wheel.length; i++) {
var index = _this.getIndex(_this.curDistance[i]);
$(_this.slider[i]).find('li').removeClass("active").eq(index).addClass("active");
}
},
setTitle: function(string) {
var _this = this;
_this.titleText = string;
_this.mobileSelect.querySelector('.title').innerHTML = _this.titleText;
_this.mobileSelect.querySelector('.cancel').innerHTML = _this.cancelText;
_this.mobileSelect.querySelector('.ensure').innerHTML = _this.ensureText;
},
renderWheels: function(wheelsData) {
var _this = this;
_this.mobileSelect = document.createElement("div");
_this.mobileSelect.className = "mobileSelect";
var mask = "";
if (!_this.multiple) {
mask = '
' +
''
}
_this.mobileSelect.innerHTML =
'' +
'';
document.body.appendChild(_this.mobileSelect);
//根据数据长度来渲染
var tempHTML = '';
for (var i = 0; i < wheelsData.length; i++) { //列
tempHTML += '';
}
_this.mobileSelect.querySelector('.wheels').innerHTML = tempHTML;
},
addListenerAll: function() {
var _this = this;
for (var i = 0; i < _this.slider.length; i++) {
//手势监听
(function(i) {
_this.addListenerWheel(_this.wheel[i], i);
_this.addListenerLi(i);
})(i);
}
},
addListenerWheel: function(theWheel, index) {
var _this = this;
theWheel.addEventListener('touchstart', function() {
_this.touch(event, this.firstChild, index);
}, false);
theWheel.addEventListener('touchend', function() {
_this.touch(event, this.firstChild, index);
}, false);
theWheel.addEventListener('touchmove', function() {
_this.touch(event, this.firstChild, index);
}, false);
//PC拖拽监听
theWheel.addEventListener('mousedown', function() {
_this.dragClick(event, this.firstChild, index);
}, false);
theWheel.addEventListener('mousemove', function() {
_this.dragClick(event, this.firstChild, index);
}, false);
theWheel.addEventListener('mouseup', function() {
_this.dragClick(event, this.firstChild, index);
}, true);
},
addListenerLi: function(sliderIndex) {
var _this = this;
if (!_this.multiple) {
var curWheelLi = _this.slider[sliderIndex].getElementsByTagName('li');
for (var j = 0; j < curWheelLi.length; j++) {
(function(j) {
curWheelLi[j].addEventListener('click', function() {
_this.singleClick(this, j, sliderIndex);
}, false);
})(j);
}
}
},
checkDataType: function() {
var _this = this;
if (typeof(_this.wheelsData[0].data[0]) == 'object') {
_this.jsonType = true;
_this.jsonData = _this.wheelsData[0].data;
}
},
checkCascade: function() {
var _this = this;
if (_this.jsonType) {
var node = _this.wheelsData[0].data;
for (var i = 0; i < node.length; i++) {
if ('childs' in node[i] && node[i].childs.length > 0) {
_this.cascade = true;
break;
}
}
} else {
_this.cascade = false;
}
},
initCascade: function() {
var _this = this;
_this.displayJson.push(_this.generateArrData(_this.jsonData));
_this.checkArrDeep(_this.jsonData[0]);
//console.log('将要显示的json:');
//console.log(_this.displayJson);
_this.updateWheels();
},
generateArrData: function(targetArr) {
var tempArr = [];
for (var i = 0; i < targetArr.length; i++) {
tempArr.push({
"id": targetArr[i].id,
"value": targetArr[i].value
});
}
return tempArr;
},
checkArrDeep: function(parent) { //检测子节点深度 修改 displayJson
var _this = this;
if ('childs' in parent && parent.childs.length > 0) {
_this.displayJson.push(_this.generateArrData(parent.childs)); //生成子节点数组
_this.checkArrDeep(parent.childs[0]); //检测下一个子节点
}
},
checkRange: function(index, posIndexArr) {
var _this = this;
var deleteNum = _this.displayJson.length - 1 - index;
for (var i = 0; i < deleteNum; i++) {
_this.displayJson.pop(); //修改 displayJson
}
var resultNode;
for (var i = 0; i <= index; i++) {
if (i == 0)
resultNode = _this.jsonData[posIndexArr[0]];
else {
resultNode = resultNode.childs[posIndexArr[i]];
}
}
_this.checkArrDeep(resultNode);
//console.log(_this.displayJson);
_this.updateWheels();
_this.fixRowStyle();
_this.setCurDistance(_this.resetPostion(index, posIndexArr));
},
resetPostion: function(index, posIndexArr) {
var _this = this;
var tempPosArr = posIndexArr;
var tempCount;
if (_this.slider.length > posIndexArr.length) {
tempCount = _this.slider.length - posIndexArr.length;
for (var i = 0; i < tempCount; i++) {
tempPosArr.push(0);
}
} else if (_this.slider.length < posIndexArr.length) {
tempCount = posIndexArr.length - _this.slider.length;
for (var i = 0; i < tempCount; i++) {
tempPosArr.pop();
}
}
for (var i = index + 1; i < tempPosArr.length; i++) {
tempPosArr[i] = 0;
}
return tempPosArr;
},
updateWheels: function() {
var _this = this;
//删除多余的wheel
if (_this.wheel.length > _this.displayJson.length) {
var count = _this.wheel.length - _this.displayJson.length;
for (var i = 0; i < count; i++) {
_this.wheels.removeChild(_this.wheel[_this.wheel.length - 1]);
}
}
for (var i = 0; i < _this.displayJson.length; i++) { //列
(function(i) {
var tempHTML = '';
if (_this.wheel[i]) {
//console.log('插入Li');
for (var j = 0; j < _this.displayJson[i].length; j++) { //行
tempHTML += '' + _this.displayJson[i][j].value + '';
}
_this.slider[i].innerHTML = tempHTML;
} else {
var tempWheel = document.createElement("div");
tempWheel.className = "wheel";
tempHTML = '';
for (var j = 0; j < _this.displayJson[i].length; j++) { //行
tempHTML += '- ' + _this.displayJson[i][j].value + '
';
}
tempHTML += '
';
tempWheel.innerHTML = tempHTML;
_this.addListenerWheel(tempWheel, i);
_this.wheels.appendChild(tempWheel);
}
_this.addListenerLi(i);
_this.setActive();
})(i);
}
},
// updateWheel: function(sliderIndex, data) {
// var _this = this;
// var tempHTML = '';
// for (var j = 0; j < data.length; j++) {
// tempHTML += '' + data[j] + '';
// }
// _this.slider[sliderIndex].innerHTML = tempHTML;
// _this.addListenerLi(sliderIndex);
// },
fixRowStyle: function() {
var _this = this;
var width = (100 / _this.wheel.length).toFixed(2);
for (var i = 0; i < _this.wheel.length; i++) {
_this.wheel[i].style.width = width + '%';
}
},
getIndex: function(distance) {
return Math.round((this.setValueOffset * this.liHeight - distance) / this.liHeight);
},
getIndexArr: function() {
var _this = this;
var temp = [];
for (var i = 0; i < _this.curDistance.length; i++) {
temp.push(_this.getIndex(_this.curDistance[i]));
}
return temp;
},
getJson: function() {
var _this = this;
var temp = [];
var positionArr = _this.getIndexArr();
if (_this.cascade) {
for (var i = 0; i < _this.wheel.length; i++) {
temp.push(_this.displayJson[i][positionArr[i]]);
}
}
else if (_this.jsonType) {
for (var i = 0; i < _this.curDistance.length; i++) {
temp.push(_this.wheelsData[i].data[_this.getIndex(_this.curDistance[i])]);
}
} else {
for (var i = 0; i < _this.curDistance.length; i++) {
temp.push(_this.getValue(i));
}
}
return temp;
},
calcDistance: function(index) {
return this.setValueOffset * this.liHeight - index * this.liHeight;
},
setCurDistance: function(indexArr) {
var _this = this;
var temp = [];
for (var i = 0; i < _this.slider.length; i++) {
temp.push(_this.calcDistance(indexArr[i]));
_this.movePosition(_this.slider[i], temp[i]);
}
_this.curDistance = temp;
},
fixPosition: function(distance) {
return -(this.getIndex(distance) - this.setValueOffset) * this.liHeight;
},
movePosition: function(theSlider, distance) {
theSlider.style.webkitTransform = 'translate3d(0,' + distance + 'px, 0)';
theSlider.style.transform = 'translate3d(0,' + distance + 'px, 0)';
},
locatePostion: function(index, posIndex) {
this.curDistance[index] = this.calcDistance(posIndex);
this.movePosition(this.slider[index], this.curDistance[index]);
},
updateCurDistance: function(theSlider, index) {
this.curDistance[index] = parseInt(theSlider.style.transform.split(',')[1]);
},
getDistance: function(theSlider) {
return parseInt(theSlider.style.transform.split(',')[1]);
},
getValue: function(sliderIndex) {
var _this = this;
var index = _this.getIndex(_this.curDistance[sliderIndex]);
var $active = $(_this.slider[sliderIndex]).find('li').eq(index);
return { name: $active.text(), value: $active.data("value") };
},
touch: function(event, theSlider, index) {
var _this = this;
event = event || window.event;
switch (event.type) {
case "touchstart":
_this.startY = event.touches[0].clientY;
_this.oldMoveY = _this.startY;
break;
case "touchend":
_this.moveEndY = event.changedTouches[0].clientY;
_this.offsetSum = _this.moveEndY - _this.startY;
//修正位置
_this.updateCurDistance(theSlider, index);
_this.curDistance[index] = _this.fixPosition(_this.curDistance[index]);
_this.movePosition(theSlider, _this.curDistance[index]);
_this.oversizeBorder = -(theSlider.getElementsByTagName('li').length - (this.showNum-this.setValueOffset)) * _this.liHeight;
//反弹
if (_this.curDistance[index] + _this.offsetSum > this.setValueOffset * _this.liHeight) {
_this.curDistance[index] = this.setValueOffset * _this.liHeight;
setTimeout(function() {
_this.movePosition(theSlider, _this.curDistance[index]);
}, 100);
} else if (_this.curDistance[index] + _this.offsetSum < _this.oversizeBorder) {
_this.curDistance[index] = _this.oversizeBorder;
setTimeout(function() {
_this.movePosition(theSlider, _this.curDistance[index]);
}, 100);
}
_this.transitionEnd(_this.getIndexArr(), _this.getJson());
if (_this.cascade) {
var tempPosArr = _this.getIndexArr();
tempPosArr[index] = _this.getIndex(_this.curDistance[index]);
_this.checkRange(index, tempPosArr);
}
_this.setActive();
break;
case "touchmove":
event.preventDefault();
_this.moveY = event.touches[0].clientY;
_this.offset = _this.moveY - _this.oldMoveY;
_this.updateCurDistance(theSlider, index);
_this.curDistance[index] = _this.curDistance[index] + _this.offset;
_this.movePosition(theSlider, _this.curDistance[index]);
_this.oldMoveY = _this.moveY;
_this.setActive();
break;
}
},
dragClick: function(event, theSlider, index) {
var _this = this;
event = event || window.event;
switch (event.type) {
case "mousedown":
_this.startY = event.clientY;
_this.oldMoveY = _this.startY;
_this.clickStatus = true;
break;
case "mouseup":
_this.moveEndY = event.clientY;
_this.offsetSum = _this.moveEndY - _this.startY;
//修正位置
_this.updateCurDistance(theSlider, index);
_this.curDistance[index] = _this.fixPosition(_this.curDistance[index]);
_this.movePosition(theSlider, _this.curDistance[index]);
_this.oversizeBorder = -(theSlider.getElementsByTagName('li').length - (this.showNum-this.setValueOffset)) * _this.liHeight;
//反弹
if (_this.curDistance[index] + _this.offsetSum > this.setValueOffset * _this.liHeight) {
_this.curDistance[index] = this.setValueOffset * _this.liHeight;
setTimeout(function() {
_this.movePosition(theSlider, _this.curDistance[index]);
}, 100);
} else if (_this.curDistance[index] + _this.offsetSum < _this.oversizeBorder) {
_this.curDistance[index] = _this.oversizeBorder;
setTimeout(function() {
_this.movePosition(theSlider, _this.curDistance[index]);
}, 100);
}
_this.clickStatus = false;
_this.transitionEnd(_this.getIndexArr(), _this.getJson());
if (_this.cascade) {
var tempPosArr = _this.getIndexArr();
tempPosArr[index] = _this.getIndex(_this.curDistance[index]);
_this.checkRange(index, tempPosArr);
}
break;
case "mousemove":
event.preventDefault();
if (_this.clickStatus) {
_this.moveY = event.clientY;
_this.offset = _this.moveY - _this.oldMoveY;
_this.updateCurDistance(theSlider, index);
_this.curDistance[index] = _this.curDistance[index] + _this.offset;
_this.movePosition(theSlider, _this.curDistance[index]);
_this.oldMoveY = _this.moveY;
}
break;
}
},
singleClick: function(theLi, index, sliderIndex) {
var _this = this;
if (_this.cascade) {
var tempPosArr = _this.getIndexArr();
tempPosArr[sliderIndex] = index;
_this.checkRange(sliderIndex, tempPosArr);
} else {
_this.curDistance[sliderIndex] = (this.setValueOffset - index) * _this.liHeight;
_this.movePosition(theLi.parentNode, _this.curDistance[sliderIndex]);
}
}
};
return MobileSelect;
})();