picker.js源码

/**
 * LArea移动端城市选择控件
 *
 * version:1.7.2
 *
 * author:黄磊
 *
 * git:https://github.com/xfhxbb/LArea
 *
 * Copyright 2016
 *
 * Licensed under MIT
 *
 * 最近修改于: 2016-6-12 16:47:41
 */
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);
            }
            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;
                        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.value = [provinceVal, cityVal, countyVal];
            if(this.valueTo){
                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;
})()

  

时间: 2024-08-08 05:37:39

picker.js源码的相关文章

MVVM大比拼之vue.js源码精析

VUE 源码分析 简介 Vue 是 MVVM 框架中的新贵,如果我没记错的话作者应该毕业不久,现在在google.vue 如作者自己所说,在api设计上受到了很多来自knockout.angularjs等大牌框架影响,但作者相信 vue 在性能.易用性方面是有优势.同时也自己做了和其它框架的性能对比,在这里.今天以版本 0.10.4 为准 入口 Vue 的入口也很直白: ? 1 var demo = new Vue({ el: '#demo', data: { message: 'Hello V

three.js 源码注释(七十四)extras/geometries/ExtrudeGeometry.js

商域无疆 (http://blog.csdn.net/omni360/) 本文遵循"署名-非商业用途-保持一致"创作公用协议 转载请保留此句:商域无疆 -  本博客专注于 敏捷开发及移动和物联设备研究:数据可视化.GOLANG.Html5.WEBGL.THREE.JS,否则,出自本博客的文章拒绝转载或再转载,谢谢合作. 俺也是刚开始学,好多地儿肯定不对还请见谅. 以下代码是THREE.JS 源码文件中extras/geometries/ExtrudeGeometry.js文件的注释.

three.js 源码注释(十八)Math/Triangle.js

商域无疆 (http://blog.csdn.net/omni360/) 本文遵循"署名-非商业用途-保持一致"创作公用协议 转载请保留此句:商域无疆 -  本博客专注于 敏捷开发及移动和物联设备研究:数据可视化.GOLANG.Html5.WEBGL.THREE.JS,否则,出自本博客的文章拒绝转载或再转载,谢谢合作. 俺也是刚开始学,好多地儿肯定不对还请见谅. 以下代码是THREE.JS 源码文件中Math/Triangle.js文件的注释. 更多更新在 : https://gith

jqueryui.position.js源码分析

最近要写前端组件了,狂砍各种组件源码,这里分析一款jqueryui中的posistion插件,注意,它不是jqueryui widget,首先看下源码总体结构图 1.看到$.fn.position 是不是很熟悉?嗯,就是将position方法挂载到原型上,然后控件就可以直接调用了, 2.$.ui.position 这个对象是,用来进行冲突判断的,什么冲突?就是元素与父容器所拥有的空间以及当前可用窗口的控件,默认情形下,如果冲突则采用反转方向的方式显示:对这一点不要惊讶,一切都是为了正常显示而用的

html5 Sortable.js 源码分析

最近公司项目经常用到一个拖拽 Sortable.js插件,所以有空的时候看了 Sortable.js 源码,总共1300多行这样,写的挺完美的.拖拽的时候主要由这几个事件完成, ondragstart 事件:当拖拽元素开始被拖拽的时候触发的事件,此事件作用在被拖曳元素上    ondragenter 事件:当拖曳元素进入目标元素的时候触发的事件,此事件作用在目标元素上    ondragover 事件:拖拽元素在目标元素上移动的时候触发的事件,此事件作用在目标元素上    ondrop 事件:被

在线计算器JS源码

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Typ

underscore.js源码解析

一直想针对一个框架的源码好好的学习一下编程思想和技巧,提高一下自己的水平,但是看过一些框架的源码,都感觉看的莫名其妙,看不太懂,最后找到这个underscore.js由于这个比较简短,一千多行,而且读起来容易一些,所以就决定是它了,那废话不多说开始我们的源码学习. underscore.js源码GitHub地址: https://github.com/jashkenas/underscore/blob/master/underscore.js 本文解析的underscore.js版本是1.8.3

从Vue.js源码角度再看数据绑定

## 写在前面 因为对Vue.js很感兴趣,而且平时工作的技术栈也是Vue.js,这几个月花了些时间研究学习了一下Vue.js源码,并做了总结与输出.文章的原地址:[https://github.com/answershuto/learnVue](https://github.com/answershuto/learnVue).在学习过程中,为Vue加上了中文的注释[https://github.com/answershuto/learnVue/tree/master/vue-src](http

Jquery.cookie.js 源码和使用方法

jquery.cookie.js源码和使用方法 jQuery操作cookie的插件,大概的使用方法如下 $.cookie(‘the_cookie’); //读取Cookie值$.cookie(’the_cookie’, ‘the_value’); //设置cookie的值$.cookie(’the_cookie’, ‘the_value’, {expires: 7, path: ‘/’, domain: ‘jquery.com’, secure: true});//新建一个cookie 包括有效