You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
348 lines
15 KiB
348 lines
15 KiB
|
|
window.LArea = (function() {
|
|
var MobileArea = function() {
|
|
this.gearArea;
|
|
this.data;
|
|
this.index = 0;
|
|
this.value = [0, 0, 0];
|
|
}
|
|
MobileArea.prototype = {
|
|
init: function(params) {
|
|
this.params = params;
|
|
this.trigger = document.querySelector(params.trigger);
|
|
if(params.valueTo){
|
|
this.valueTo=document.querySelector(params.valueTo);
|
|
}
|
|
if(params.valueTo1){
|
|
this.valueTo1=document.querySelector(params.valueTo1);
|
|
}
|
|
this.keys = params.keys;
|
|
this.type = params.type||1;
|
|
switch (this.type) {
|
|
case 1:
|
|
case 2:
|
|
break;
|
|
default:
|
|
throw new Error('错误提示: 没有这种数据源类型');
|
|
break;
|
|
}
|
|
this.bindEvent();
|
|
},
|
|
getData: function(callback) {
|
|
var _self = this;
|
|
if (typeof _self.params.data == "object") {
|
|
_self.data = _self.params.data;
|
|
callback();
|
|
} else {
|
|
var xhr = new XMLHttpRequest();
|
|
xhr.open('get', _self.params.data);
|
|
xhr.onload = function(e) {
|
|
if ((xhr.status >= 200 && xhr.status < 300) || xhr.status === 0) {
|
|
var responseData = JSON.parse(xhr.responseText);
|
|
_self.data = responseData.data;
|
|
if (callback) {
|
|
callback()
|
|
};
|
|
}
|
|
}
|
|
xhr.send();
|
|
}
|
|
},
|
|
bindEvent: function() {
|
|
var _self = this;
|
|
//呼出插件
|
|
function popupArea(e) {
|
|
_self.gearArea = document.createElement("div");
|
|
_self.gearArea.className = "gearArea";
|
|
_self.gearArea.innerHTML = '<div class="area_ctrl slideInUp">' +
|
|
'<div class="area_btn_box">' +
|
|
'<div class="area_btn larea_cancel">取消</div>' +
|
|
'<div class="area_btn larea_finish">确定</div>' +
|
|
'</div>' +
|
|
'<div class="area_roll_mask">' +
|
|
'<div class="area_roll">' +
|
|
'<div>' +
|
|
'<div class="gear area_province" data-areatype="area_province"></div>' +
|
|
'<div class="area_grid">' +
|
|
'</div>' +
|
|
'</div>' +
|
|
'<div>' +
|
|
'<div class="gear area_city" data-areatype="area_city"></div>' +
|
|
'<div class="area_grid">' +
|
|
'</div>' +
|
|
'</div>' +
|
|
'<div>' +
|
|
'<div class="gear area_county" data-areatype="area_county"></div>' +
|
|
'<div class="area_grid">' +
|
|
'</div>' +
|
|
'</div>' +
|
|
'</div>' +
|
|
'</div>' +
|
|
'</div>';
|
|
document.body.appendChild(_self.gearArea);
|
|
areaCtrlInit();
|
|
var larea_cancel = _self.gearArea.querySelector(".larea_cancel");
|
|
larea_cancel.addEventListener('touchstart', function(e) {
|
|
_self.close(e);
|
|
});
|
|
var larea_finish = _self.gearArea.querySelector(".larea_finish");
|
|
larea_finish.addEventListener('touchstart', function(e) {
|
|
_self.finish(e);
|
|
});
|
|
var area_province = _self.gearArea.querySelector(".area_province");
|
|
var area_city = _self.gearArea.querySelector(".area_city");
|
|
var area_county = _self.gearArea.querySelector(".area_county");
|
|
area_province.addEventListener('touchstart', gearTouchStart);
|
|
area_city.addEventListener('touchstart', gearTouchStart);
|
|
area_county.addEventListener('touchstart', gearTouchStart);
|
|
area_province.addEventListener('touchmove', gearTouchMove);
|
|
area_city.addEventListener('touchmove', gearTouchMove);
|
|
area_county.addEventListener('touchmove', gearTouchMove);
|
|
area_province.addEventListener('touchend', gearTouchEnd);
|
|
area_city.addEventListener('touchend', gearTouchEnd);
|
|
area_county.addEventListener('touchend', gearTouchEnd);
|
|
}
|
|
//初始化插件默认值
|
|
function areaCtrlInit() {
|
|
_self.gearArea.querySelector(".area_province").setAttribute("val", _self.value[0]);
|
|
_self.gearArea.querySelector(".area_city").setAttribute("val", _self.value[1]);
|
|
_self.gearArea.querySelector(".area_county").setAttribute("val", _self.value[2]);
|
|
|
|
switch (_self.type) {
|
|
case 1:
|
|
_self.setGearTooth(_self.data);
|
|
break;
|
|
case 2:
|
|
_self.setGearTooth(_self.data[0]);
|
|
break;
|
|
}
|
|
}
|
|
//触摸开始
|
|
function gearTouchStart(e) {
|
|
e.preventDefault();
|
|
var target = e.target;
|
|
while (true) {
|
|
if (!target.classList.contains("gear")) {
|
|
target = target.parentElement;
|
|
} else {
|
|
break
|
|
}
|
|
}
|
|
clearInterval(target["int_" + target.id]);
|
|
target["old_" + target.id] = e.targetTouches[0].screenY;
|
|
target["o_t_" + target.id] = (new Date()).getTime();
|
|
var top = target.getAttribute('top');
|
|
if (top) {
|
|
target["o_d_" + target.id] = parseFloat(top.replace(/em/g, ""));
|
|
} else {
|
|
target["o_d_" + target.id] = 0;
|
|
}
|
|
target.style.webkitTransitionDuration = target.style.transitionDuration = '0ms';
|
|
}
|
|
//手指移动
|
|
function gearTouchMove(e) {
|
|
e.preventDefault();
|
|
var target = e.target;
|
|
while (true) {
|
|
if (!target.classList.contains("gear")) {
|
|
target = target.parentElement;
|
|
} else {
|
|
break
|
|
}
|
|
}
|
|
target["new_" + target.id] = e.targetTouches[0].screenY;
|
|
target["n_t_" + target.id] = (new Date()).getTime();
|
|
var f = (target["new_" + target.id] - target["old_" + target.id]) * 30 / window.innerHeight;
|
|
target["pos_" + target.id] = target["o_d_" + target.id] + f;
|
|
target.style["-webkit-transform"] = 'translate3d(0,' + target["pos_" + target.id] + 'em,0)';
|
|
target.setAttribute('top', target["pos_" + target.id] + 'em');
|
|
if(e.targetTouches[0].screenY<1){
|
|
gearTouchEnd(e);
|
|
};
|
|
}
|
|
//离开屏幕
|
|
function gearTouchEnd(e) {
|
|
e.preventDefault();
|
|
var target = e.target;
|
|
while (true) {
|
|
if (!target.classList.contains("gear")) {
|
|
target = target.parentElement;
|
|
} else {
|
|
break;
|
|
}
|
|
}
|
|
var flag = (target["new_" + target.id] - target["old_" + target.id]) / (target["n_t_" + target.id] - target["o_t_" + target.id]);
|
|
if (Math.abs(flag) <= 0.2) {
|
|
target["spd_" + target.id] = (flag < 0 ? -0.08 : 0.08);
|
|
} else {
|
|
if (Math.abs(flag) <= 0.5) {
|
|
target["spd_" + target.id] = (flag < 0 ? -0.16 : 0.16);
|
|
} else {
|
|
target["spd_" + target.id] = flag / 2;
|
|
}
|
|
}
|
|
if (!target["pos_" + target.id]) {
|
|
target["pos_" + target.id] = 0;
|
|
}
|
|
rollGear(target);
|
|
}
|
|
//缓动效果
|
|
function rollGear(target) {
|
|
var d = 0;
|
|
var stopGear = false;
|
|
function setDuration() {
|
|
target.style.webkitTransitionDuration = target.style.transitionDuration = '200ms';
|
|
stopGear = true;
|
|
}
|
|
clearInterval(target["int_" + target.id]);
|
|
target["int_" + target.id] = setInterval(function() {
|
|
var pos = target["pos_" + target.id];
|
|
var speed = target["spd_" + target.id] * Math.exp(-0.03 * d);
|
|
pos += speed;
|
|
if (Math.abs(speed) > 0.1) {} else {
|
|
var b = Math.round(pos / 2) * 2;
|
|
pos = b;
|
|
setDuration();
|
|
}
|
|
if (pos > 0) {
|
|
pos = 0;
|
|
setDuration();
|
|
}
|
|
var minTop = -(target.dataset.len - 1) * 2;
|
|
if (pos < minTop) {
|
|
pos = minTop;
|
|
setDuration();
|
|
}
|
|
if (stopGear) {
|
|
var gearVal = Math.abs(pos) / 2 || 0;
|
|
setGear(target, gearVal);
|
|
clearInterval(target["int_" + target.id]);
|
|
}
|
|
target["pos_" + target.id] = pos;
|
|
target.style["-webkit-transform"] = 'translate3d(0,' + pos + 'em,0)';
|
|
target.setAttribute('top', pos + 'em');
|
|
d++;
|
|
}, 30);
|
|
}
|
|
//控制插件滚动后停留的值
|
|
function setGear(target, val) {
|
|
val = Math.round(val);
|
|
target.setAttribute("val", val);
|
|
switch (_self.type) {
|
|
case 1:
|
|
_self.setGearTooth(_self.data);
|
|
break;
|
|
case 2:
|
|
switch(target.dataset['areatype']){
|
|
case 'area_province':
|
|
_self.setGearTooth(_self.data[0]);
|
|
break;
|
|
case 'area_city':
|
|
var ref = target.childNodes[val].getAttribute('ref');
|
|
var childData=[];
|
|
var nextData= _self.data[2];
|
|
for (var i in nextData) {
|
|
if(i==ref){
|
|
childData = nextData[i];
|
|
break;
|
|
}
|
|
};
|
|
_self.index=2;
|
|
_self.setGearTooth(childData);
|
|
break;
|
|
}
|
|
}
|
|
|
|
}
|
|
_self.getData(function() {
|
|
_self.trigger.addEventListener('click', popupArea);
|
|
});
|
|
},
|
|
//重置节点个数
|
|
setGearTooth: function(data) {
|
|
var _self = this;
|
|
var item = data || [];
|
|
var l = item.length;
|
|
var gearChild = _self.gearArea.querySelectorAll(".gear");
|
|
var gearVal = gearChild[_self.index].getAttribute('val');
|
|
var maxVal = l - 1;
|
|
if (gearVal > maxVal) {
|
|
gearVal = maxVal;
|
|
}
|
|
gearChild[_self.index].setAttribute('data-len', l);
|
|
if (l > 0) {
|
|
var id = item[gearVal][this.keys['id']];
|
|
var childData;
|
|
switch (_self.type) {
|
|
case 1:
|
|
childData = item[gearVal].child
|
|
break;
|
|
case 2:
|
|
var nextData= _self.data[_self.index+1]
|
|
for (var i in nextData) {
|
|
if(i==id){
|
|
childData = nextData[i];
|
|
break;
|
|
}
|
|
};
|
|
break;
|
|
}
|
|
var itemStr = "";
|
|
for (var i = 0; i < l; i++) {
|
|
itemStr += "<div class='tooth' ref='" + item[i][this.keys['id']] + "'>" + item[i][this.keys['name']] + "</div>";
|
|
}
|
|
gearChild[_self.index].innerHTML = itemStr;
|
|
gearChild[_self.index].style["-webkit-transform"] = 'translate3d(0,' + (-gearVal * 2) + 'em,0)';
|
|
gearChild[_self.index].setAttribute('top', -gearVal * 2 + 'em');
|
|
gearChild[_self.index].setAttribute('val', gearVal);
|
|
_self.index++;
|
|
if (_self.index > 2) {
|
|
_self.index = 0;
|
|
return;
|
|
}
|
|
_self.setGearTooth(childData);
|
|
} else {
|
|
gearChild[_self.index].innerHTML = "<div class='tooth'></div>";
|
|
gearChild[_self.index].setAttribute('val', 0);
|
|
if(_self.index==1){
|
|
gearChild[2].innerHTML = "<div class='tooth'></div>";
|
|
gearChild[2].setAttribute('val', 0);
|
|
}
|
|
_self.index = 0;
|
|
}
|
|
},
|
|
finish: function(e) {
|
|
var _self = this;
|
|
var area_province = _self.gearArea.querySelector(".area_province");
|
|
var area_city = _self.gearArea.querySelector(".area_city");
|
|
var area_county = _self.gearArea.querySelector(".area_county");
|
|
var provinceVal = parseInt(area_province.getAttribute("val"));
|
|
var provinceText = area_province.childNodes[provinceVal].textContent;
|
|
var provinceCode = area_province.childNodes[provinceVal].getAttribute('ref');
|
|
var cityVal = parseInt(area_city.getAttribute("val"));
|
|
var cityText = area_city.childNodes[cityVal].textContent;
|
|
var cityCode = area_city.childNodes[cityVal].getAttribute('ref');
|
|
var countyVal = parseInt(area_county.getAttribute("val"));
|
|
var countyText = area_county.childNodes[countyVal].textContent;
|
|
var countyCode = area_county.childNodes[countyVal].getAttribute('ref');
|
|
//_self.trigger.value = provinceText + ((cityText)?(',' + cityText):(''))+ ((countyText)?(',' + countyText):(''));
|
|
_self.trigger.innerHTML = provinceText + ((cityText)?(',' + cityText):(''))+ ((countyText)?(',' + countyText):(''));
|
|
_self.valueTo1.value = provinceText + ((cityText)?(',' + cityText):(''))+ ((countyText)?(',' + countyText):(''));
|
|
_self.value = [provinceVal, cityVal, countyVal];
|
|
if(this.valueTo){
|
|
this.valueTo.value= provinceVal + ',' + cityVal + ',' + countyVal;
|
|
//this.valueTo.value= provinceCode +((cityCode)?(',' + cityCode):('')) + ((countyCode)?(',' + countyCode):(''));
|
|
}
|
|
_self.close(e);
|
|
},
|
|
close: function(e) {
|
|
e.preventDefault();
|
|
var _self = this;
|
|
var evt = new CustomEvent('input');
|
|
_self.trigger.dispatchEvent(evt);
|
|
document.body.removeChild(_self.gearArea);
|
|
_self.gearArea=null;
|
|
}
|
|
}
|
|
return MobileArea;
|
|
})() |