| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428 |
- /*
- * 版权所有 (C) 2015 知启蒙(ZHIQIM) 保留所有权利。
- *
- * 指定登记&发行网站: https://www.zhiqim.com/ 欢迎加盟知启蒙,[编程有你,知启蒙一路随行]。
- *
- * 本文采用《知启蒙登记发行许可证》,除非符合许可证,否则不可使用该文件!
- * 1、您可以免费使用、修改、合并、出版发行和分发,再授权软件、软件副本及衍生软件;
- * 2、您用于商业用途时,必须在原作者指定的登记网站,按原作者要求进行登记;
- * 3、您在使用、修改、合并、出版发行和分发时,必须包含版权声明、许可声明,及保留原作者的著作权、商标和专利等知识产权;
- * 4、您在互联网、移动互联网等大众网络下发行和分发再授权软件、软件副本及衍生软件时,必须在原作者指定的发行网站进行发行和分发;
- * 5、您可以在以下链接获取一个完整的许可证副本。
- *
- * 许可证链接:http://zhiqim.org/licenses/zhiqim_register_publish_license.htm
- *
- * 除非法律需要或书面同意,软件由原始码方式提供,无任何明示或暗示的保证和条件。详见完整许可证的权限和限制。
- */
-
- +(function(Z)
- {//BEGIN
- // @version v1.1.0 @author zouzhigang 2015-11-12 新建与整理
- /************************************************************************/
- //下拉列表,包括属性和方法
- /************************************************************************/
- // 1、配置方式,必须包括data-role="dropdown"表示是下拉列表
- // 2、可选属性data-onchange表示修改的函数,类似于select
- // 2、可选属性data-options值为样式格式event:click;width:160px;item-width:160px;
- // 3、支持的参数值
- // 1)event 表示该窗口的触发方式,click|hover,默认click
- // 2)width 表示下拉列表宽度,默认等于elem的宽度,类似于select
- // 3)height 表示下拉列表高度,默认200px时会出现滚动条,可以通过设计该值进行修改
- // 4)item-width 表示下拉项的宽度,默认等于width,一行一个类似于select,如果设置成width/2,则表示一行两个
- // 4、举例如下:
- // <div class="z-dropdown" data-role="z-dropdown" data-options="" data-onchange="onChangeProvice" style="width:160px;">
- // <span class="z-default" id="proviceId" value="2">湖南省</span><span class="z-float-right"><i class="z-arrow"></i></span>
- // <ul class="z-list">
- // <span value="1">广东省</span>
- // <span value="2" selected>湖南省</span>
- // <span value="3">广西壮族自治区</span>
- // <span value="3">江西省</span>
- // </ul>
- // </div>
- /************************************************************************/
- /********************************************/
- //提示类定义,包括属性和方法
- /********************************************/
- Z.Dropdown = Z.Class.newInstance();
- Z.Dropdown.prototype =
- {
- defaults :
- {//缺省值
- elem: null,
- hasSelected: true//firefox第一次focus不会show
- },
-
- init: function()
- {//初始化
- this.$elem = Z.$elem(this.elem, "Z.Dropdown");
-
- this.$default = this.$elem.find(".z-default");
- this.$input = this.$default.children('input');
- this.$arrow = this.$elem.find("i.z-float-right.z-font");
- this.$list = this.$elem.find(".z-list");
- this.$spans = this.$list.find("span");
- if (this.$list.length == 0)
- return;
-
- //获取配置的属性
- var options = Z.AR.toObject(this.$elem.attr("data-options"), ";");
- var expression = this.$elem.attr("data-onchange");
- if (Z.T.isString(expression))
- this.onchange = Z.evals(expression);
-
- //初始化列表高度
- this.event = options && options.event || "click";
- this.stop = options && options.stop || "false";
- var maxHeight = Z.S.prefixNum(options && options.maxHeight || "200");
- this.$list.css("maxHeight", maxHeight);
-
- //初始化条目宽高
- this.width = options && options.width || this.$elem.offsetWidth();
- var itemWidth = Z.S.prefixNum(options && options.itemWidth || this.width);
- var itemHeight = Z.S.prefixNum(options && options.itemHeight || "30");
- this.$spans.css({width: itemWidth, height: itemHeight, lineHeight: itemHeight-6});
-
- //把条目的高度缓存起来
- this.$list.show();
- this.itemHeight = this.$spans.offsetHeight();
- this.$list.hide();
-
- //初始化成功
- this.status = 0;
-
- //初始化注册移入移出事件,鼠标在元素和提示上显示
- this.$spans.click(this.select, this);
- if (this.event == "click")
- {
- this.$elem.click(this.show, this);
- Z(document).click(this.hide, this);
- }
- else
- {
- this.$elem.mouseover(this.show, this);
- this.$elem.mouseout(this.hide, this);
- this.$list.mouseover(this.show, this);
- this.$list.mouseout(this.hide, this);
- }
-
- if (this.$input.length > 0)
- {
- this.$input.on('focus',this.focus, this);
- this.$input.on('input',this.show, this);
- this.$input.on('blur',this.blur, this);
- }
- },
- focus: function(e)
- {
- this.$input.attr("placeholder", this.$input.attr("data-value"));
- this.$input.val("");
-
- if (Z.B.firefox && this.hasSelected)
- {//firefox第一次focus不会show
- this.hasSelected = false;
- this.show(e);
- }
- },
- show: function(e)
- {
- if (this.stop == "true")
- {//默认为false,即向上冒泡,以支持多个下拉列表时相互关闭,当父节点有click事件时,可设置为true,不冒泡
- Z.E.stop(e);
- }
-
- var target = Z.E.target(e);
- if (this.event == "click" && this.status == 1 && !(target instanceof HTMLInputElement))
- {//第二次点击表示关闭,如果input下点击不处理,箭头处理
- this.close();
- return;
- }
-
- //把列表恢复为初始模式
- this.status = 1;
- this.$elem.addClass("z-active");
- this.$arrow.removeClass("z-arrowhead-down").addClass("z-arrowhead-up");
-
- if (this.$input.length > 0)
- {
- this.$list.removeClass("z-none").css("height", "auto");
- this.$spans.removeClass("zi-hide");
-
- if (target instanceof HTMLInputElement)
- {//如果是从input点击的执行搜索,箭头不执行,显示全部
- this.search();
- }
- }
-
- //定义到元素的下方
- var top = this.$elem.offsetHeight() - 2;//上下边框2px
- var left = -1;//左边框1px
-
- this.$list.inBlock().css({top: top, left: left, width: this.width});
-
- var listRect = this.$list[0].getBoundingClientRect();
- var topBody = listRect.top;
- var height = listRect.height;
-
- if (topBody > height && Z.D.clientHeight() - topBody - height < 0)
- {//如果顶部够高,底部不够高时,则向上弹出
- top = top - height - this.$elem.offsetHeight() + 2;
- this.$list.css("top", top);
- }
- },
- hide:function(e)
- {
- if (this.stop == "true")
- {//默认为false,即向上冒泡,以支持多个下拉列表时相互关闭,当父节点有click事件时,可设置为true,不冒泡
- Z.E.stop(e);
- }
-
- //鼠标在元素和提示中间不关闭
- var x = Z.E.clientX(e);
- var y = Z.E.clientY(e);
- var tx = this.$elem.clientX();
- var ty = this.$elem.clientY();
- var tw = this.$elem.offsetWidth();
- var th = this.$elem.offsetHeight();
-
- if (x > tx && x < (tx+tw) && y > ty && y < (ty+th))
- return;
-
- this.close();
- },
- search: function()
- {
- var val = this.$input.val();
-
- this.$spans.addClass("zi-hide");
- this.$list.removeClass("z-none");
- this.$spans.each(function(elem)
- {//检索字符串是否存在
- if(Z(elem).text().indexOf(val) > -1)
- Z(elem).removeClass("zi-hide");
- });
-
- var num = this.$spans.length - this.$list.find(".zi-hide").length;
- this.$list.css("height", this.itemHeight * num + 2);
-
- //如果不存在匹配对象,显示提示
- if (this.$list.find(".zi-hide").length == this.$spans.length)
- {
- this.$list.addClass('z-none').css("height", this.itemHeight);
- }
- },
- blur: function(e)
- {//输入框退出时,恢复输入框
- this.$input.val(this.$input.attr("data-value"));
- },
- setValue: function(value)
- {
- if (Z.V.isEmpty(value))
- return;
-
- var $selected;
- this.$spans.each(function(item)
- {
- var $span = Z(item);
- if (value == $span.attr("value")){
- $selected = $span;
- return true;
- }
- });
-
- if ($selected)
- {//找到
- this.selected($selected);
- //设置值时,需要检查是否是z-select,是同步到select中
- var selectId = this.$elem.attr("data-id");
- if (selectId)
- {
- var sel = Z.D.id(selectId);
- if (sel){
- Z.Select.click($selected[0], sel);
- }
- }
- }
- },
- select: function(e)
- {
- Z.E.stop(e);
- this.selected(Z(Z.E.target(e)));
- },
- selected: function($selected)
- {
- this.$spans.each(function(item)
- {//先清理选中
- Z(item).removeClass("z-selected").removeAttr("selected");
- });
-
- $selected.addClass("z-selected");
-
- if (this.$input.length > 0)
- {
- this.$input.attr('data-value', $selected.text()).val($selected.text());
- }
- else
- {
- this.$default.val($selected.val());
- this.$default.text($selected.text());
- }
-
- this.hasSelected = true;
- this.close();
-
- if (this.onchange)
- this.onchange($selected.val());
- },
- close: function()
- {
- this.status = 0;
- this.$elem.removeClass("z-active");
- this.$arrow.removeClass("z-arrowhead-up").addClass("z-arrowhead-down");
- this.$list.hide();
- },
- remove: function()
- {
- this.$elem.remove();
- }
- };
- /********************************************/
- //刷新静态函数和第一次加载
- /********************************************/
- Z.Dropdown.load = function(target)
- {//加载
- Z.$selector("[data-role=z-dropdown]", target).each(function(elem){
- new Z.Dropdown({elem: elem});
- });
- };
- Z.onload(Z.Dropdown.load);
- /********************************************/
- //选择框定义和加载转换成下拉列表对象
- /********************************************/
- Z.Select = function(e)
- {
- Z.E.stop(e);
- Z.Select.click(Z.E.current(e), this);
- }
- Z.Select.click = function(target, elem)
- {
- var index = Z(target).attr("index");
- var oldIndex = elem.selectedIndex;
- for (var i=0;i<elem.length;i++)
- {//修改选中
- elem.options[i].selected = (index == i);
- }
- if (elem.onchange && oldIndex != index){
- elem.onchange();
- }
- if (elem.onblur){
- elem.onblur();
- }
- };
- Z.Select.get = function(id)
- {
- var $role = Z("[data-id="+id+"]");
- if ($role.length == 0)
- return null;
-
- return new Z.Dropdown({elem: $role[0]});
- };
- Z.Select.load = function(target)
- {
- Z.$selector(".z-role-select", target).each(function(elem)
- {//先删除目标范围内的下拉列表
- new Z.Dropdown({elem: elem}).remove();
- });
-
- Z.$selector("select[data-role=z-select],select[data-role=z-select-search]", target).each(function(elem)
- {//再加载目标范围内的数据
- var random = "Z_Select_"+Z.random(10);
- var $elem = Z(elem).hidden().attr("data-id", random);
- var isSearch = $elem.attr("data-role") == "z-select-search";
-
- var width = $elem.offsetWidth();
- var height = $elem.offsetHeight();
-
- var $cover = Z.$cover($elem);
-
- var id = Z.S.trim($elem.attr("id"));
- var name = Z.S.trim($elem.attr("name"))
- var options = "event:click;" + Z.S.trim($elem.attr("data-options"));
- var classes = Z.S.trim($elem.attr("data-class"));
- var type = $elem.attr('data-type');
-
- var dropdown = '<div class="z-dropdown z-role-select">'
- + '<span class="z-default z-text-clip" value=""></span><i class="z-float-right z-font z-arrowhead-down"></i>'
- + '<ul class="z-list"></ul>'
- + '</div>';
-
- var $role = Z(dropdown).appendTo($cover)
- .css({position: "absolute", left: 0, top: 0, width: width, height: height})
- .cssMaybe("padding-left", $elem.css("paddingLeft"))
- .cssMaybe("padding-right", $elem.css("paddingRight"))
- .cssMaybe("padding-top", $elem.css("paddingTop"))
- .cssMaybe("padding-bottom", $elem.css("paddingBottom"))
- .addClass(classes)
- .attr("id", random).attr("data-id", id).attr("data-name", name)
- .attr("data-options", options);
-
- //如果是模糊查找选择框
- if(isSearch)
- {
- $role.find(".z-default").append('<input type="text" class="zi-bd-none zi-w100p zi-h100p" placeholder="请选择" data-value="" value="">');
- }
-
- var hasSelected = null;
- for (var i=0;i<elem.length;i++)
- {
- var option = elem.options[i];
-
- var span = '<span index="'+i+'" value="'+option.value+'"';
- if (option.selected){
- hasSelected = option;
- span += " selected"
- }
- span += '>'+(Z.V.isEmpty(option.text)?" ":option.text)+'</span>';
- var $span = Z(span);
-
- //如果有配置点击事件,则设置
- if (option["onclick"]){
- $span.attr("onclick", option["onclick"]);
- }
-
- //再增加单击修改到select去的事件
- $span.click(Z.Select, elem);
-
- $role.find('.z-list').append($span);
- }
-
- //如果未选中取第一个
- if (hasSelected == null){
- hasSelected = (elem.length>0)?elem.options[0]:null;
- }
-
- if (hasSelected)
- {
- if (isSearch){
- $role.find('.z-default > input').attr("data-value", hasSelected.text).val(hasSelected.text);
- }
- else{
- $role.find('.z-default').attr("value", hasSelected.value).text(hasSelected.text);
- }
- }
-
- //转成下拉列表
- new Z.Dropdown({elem: $role[0]});
- });
- };
- Z.onload(Z.Select.load);
- //END
- })(zhiqim);
|