/*! * mobileSelect.js * (c) 2017-present onlyhom * Released under the MIT License. */ (function() { function getClass(dom,string) { return dom.getElementsByClassName(string); } //构造器 function MobileSelect(config) { this.mobileSelect; this.wheelsData = config.wheels; this.jsonType = false; this.cascadeJsonData = []; 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.isPC = true; this.init(config); } MobileSelect.prototype = { constructor: MobileSelect, init: function(config){ var _this = this; _this.keyMap = config.keyMap ? config.keyMap : {id:'id', value:'value', childs:'childs'}; _this.checkDataType(); _this.renderWheels(_this.wheelsData, config.cancelBtnText, config.ensureBtnText); _this.trigger = document.querySelector(config.trigger); if(!_this.trigger){ console.error('mobileSelect has been successfully installed, but no trigger found on your page.'); return false; } _this.wheel = getClass(_this.mobileSelect,'wheel'); _this.slider = getClass(_this.mobileSelect,'selectContainer'); _this.wheels = _this.mobileSelect.querySelector('.wheels'); _this.liHeight = _this.mobileSelect.querySelector('li').offsetHeight; _this.ensureBtn = _this.mobileSelect.querySelector('.ensure'); _this.cancelBtn = _this.mobileSelect.querySelector('.cancel'); _this.grayLayer = _this.mobileSelect.querySelector('.grayLayer'); _this.popUp = _this.mobileSelect.querySelector('.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.connector = config.connector ? config.connector : ' '; _this.trigger.style.cursor='pointer'; _this.setStyle(config); _this.setTitle(_this.titleText); _this.checkIsPC(); _this.checkCascade(); if (_this.cascade) { _this.initCascade(); } //定位 初始位置 if(_this.initPosition.length < _this.slider.length){ var diff = _this.slider.length - _this.initPosition.length; for(var i=0; i'+ '
'+ '
'+ '
'+ cancelText +'
'+ '
'+ '
'+ ensureText +'
'+ '
'+ '
'+ '
'+ '
'+ '
'+ '
'+ '
'+ '
'+ '
'+ '
'+ ''; document.body.appendChild(_this.mobileSelect); //根据数据长度来渲染 var tempHTML=''; for(var i=0; i'+wheelsData[i].data[j][_this.keyMap.value]+''; } }else{ for(var j=0; j'; } } 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); if(_this.isPC){ //如果是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; var curWheelLi = _this.slider[sliderIndex].getElementsByTagName('li'); for(var j=0; j 0){ _this.cascade = true; _this.cascadeJsonData = _this.wheelsData[0].data; break; } } }else{ _this.cascade = false; } }, generateArrData: function (targetArr) { var tempArr = []; var keyMap_id = this.keyMap.id; var keyMap_value = this.keyMap.value; for(var i=0; i0){ _this.initDeepCount = 0; _this.initCheckArrDeep(_this.cascadeJsonData[_this.initPosition[0]]); }else{ _this.checkArrDeep(_this.cascadeJsonData[0]); } _this.reRenderWheels(); }, initCheckArrDeep: function (parent) { var _this = this; if(parent){ if (_this.keyMap.childs in parent && parent[_this.keyMap.childs].length > 0) { _this.displayJson.push(_this.generateArrData(parent[_this.keyMap.childs])); _this.initDeepCount++; var nextNode = parent[_this.keyMap.childs][_this.initPosition[_this.initDeepCount]]; if(nextNode){ _this.initCheckArrDeep(nextNode); }else{ _this.checkArrDeep(parent[_this.keyMap.childs][0]); } } } }, checkArrDeep: function (parent) { //检测子节点深度 修改 displayJson var _this = this; if(parent){ if (_this.keyMap.childs in parent && parent[_this.keyMap.childs].length > 0) { _this.displayJson.push(_this.generateArrData(parent[_this.keyMap.childs])); //生成子节点数组 _this.checkArrDeep(parent[_this.keyMap.childs][0]);//检测下一个子节点 } } }, checkRange: function(index, posIndexArr){ var _this = this; var deleteNum = _this.displayJson.length-1-index; for(var i=0; i posIndexArr.length){ tempCount = _this.slider.length - posIndexArr.length; for(var i=0; i _this.displayJson.length){ var count = _this.wheel.length - _this.displayJson.length; for(var i=0; i'+_this.displayJson[i][j][_this.keyMap.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][_this.keyMap.value]+'
  • '; } tempHTML += '
'; tempWheel.innerHTML = tempHTML; _this.addListenerWheel(tempWheel, i); _this.wheels.appendChild(tempWheel); } _this.addListenerLi(i); })(i); } }, updateWheels:function(data){ var _this = this; if(_this.cascade){ _this.cascadeJsonData = data; _this.displayJson = []; _this.initCascade(); if(_this.initPosition.length < _this.slider.length){ var diff = _this.slider.length - _this.initPosition.length; for(var i=0; i'+data[j][_this.keyMap.value]+''; } _this.wheelsData[sliderIndex] = {data: data}; }else{ for(var j=0; j'; } _this.wheelsData[sliderIndex] = data; } _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((2*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; }, getValue: 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.getInnerHtml(i)); } } return temp; }, calcDistance: function(index){ return 2*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)-2)*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]); }, getInnerHtml: function(sliderIndex){ var _this = this; var index = _this.getIndex(_this.curDistance[sliderIndex]); return _this.slider[sliderIndex].getElementsByTagName('li')[index].innerHTML; }, 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-3)*_this.liHeight; //反弹 if(_this.curDistance[index] + _this.offsetSum > 2*_this.liHeight){ _this.curDistance[index] = 2*_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.getValue()); if(_this.cascade){ var tempPosArr = _this.getIndexArr(); tempPosArr[index] = _this.getIndex(_this.curDistance[index]); _this.checkRange(index, tempPosArr); } 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; 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-3)*_this.liHeight; //反弹 if(_this.curDistance[index] + _this.offsetSum > 2*_this.liHeight){ _this.curDistance[index] = 2*_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.getValue()); 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] = (2-index)*_this.liHeight; _this.movePosition(theLi.parentNode, _this.curDistance[sliderIndex]); } } }; if (typeof exports == "object") { module.exports = MobileSelect; } else if (typeof define == "function" && define.amd) { define([], function () { return MobileSelect; }) } else { window.MobileSelect = MobileSelect; } })();