/*! * 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 = '
' + '
' + '
' + '
' + '
' + '
' + '
' + '
' + '
' + '
' + '
' + '
' + '
' + mask + '
' + '
' + '
'; 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 = ''; 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; })();