组件效果:
搜索效果:
组件js 代码:
/* * * 全局空间 SearchBox * */var SearchBox = {};/* * * 静态方法集 * @name _method * */SearchBox._method = { /* 选择元素 */ $:function (arg, context) { var tagAll, n, eles = [], i, sub = arg.substring(1); context = context || document; if (typeof arg == ‘string‘) { switch (arg.charAt(0)) { case ‘#‘: return document.getElementById(sub); break; case ‘.‘: if (context.getElementsByClassName) return context.getElementsByClassName(sub); tagAll = SearchBox._method.$(‘*‘, context); n = tagAll.length; for (i = 0; i < n; i++) { if (tagAll[i].className.indexOf(sub) > -1) eles.push(tagAll[i]); } return eles; break; default: return context.getElementsByTagName(arg); break; } } }, /* 绑定事件 */ on:function (node, type, handler) { node.addEventListener ? node.addEventListener(type, handler, false) : node.attachEvent(‘on‘ + type, handler); }, /* 获取事件 */ getEvent:function(event){ return event || window.event; }, /* 获取事件目标 */ getTarget:function(event){ return event.target || event.srcElement; }, /* 获取元素位置 */ getPosition:function (node) { var scrollx = document.documentElement.scrollLeft || document.body.scrollLeft, scrolly = document.documentElement.scrollTop || document.body.scrollTop; var position = node.getBoundingClientRect(); return {top:position.top + scrolly, right:position.right + scrollx, bottom:position.bottom + scrolly, left:position.left + scrollx } }, /* 添加样式名 */ addClass:function (c, node) { if(!node)return; node.className = SearchBox._method.hasClass(c,node) ? node.className : node.className + ‘ ‘ + c ; }, /* 移除样式名 */ removeClass:function (c, node) { var reg = new RegExp("(^|\\s+)" + c + "(\\s+|$)", "g"); if(!SearchBox._method.hasClass(c,node))return; node.className = reg.test(node.className) ? node.className.replace(reg, ‘‘) : node.className; }, /* 是否含有CLASS */ hasClass:function (c, node) { if(!node || !node.className)return false; return node.className.indexOf(c)>-1; }, /* 阻止冒泡 */ stopPropagation:function (event) { event = event || window.event; event.stopPropagation ? event.stopPropagation() : event.cancelBubble = true; }, /* 去除两端空格 */ trim:function (str) { return str.replace(/^\s+|\s+$/g,‘‘); }}; /* * * 城市控件构造函数 * @init * */ SearchBox.init = function () { this.initialize.apply(this, arguments);}; SearchBox.init.prototype = { constructor:SearchBox.init, /* 初始化 */ initialize :function (options) { this.destroy(); var input = options.inputId; var navItem = options.navItem; SearchBox.toggleTab = options.toggleTab; SearchBox.onSearchValueChange = options.onSearchValueChange; SearchBox.attrTextModel = options.attrTextModel; SearchBox.contentList = options.contentList; SearchBox.searchData = options.searchData; this.currentPage = 1; this.searchValue = []; this.input = SearchBox._method.$(‘#‘+ input); this.createNavbar(navItem); this.inputEvent(); }, scrollEvent: function(){ var that = this; $(this.rootDiv).find(‘.item-box‘).scroll(function(){ if($(this).scrollTop() == 0){ // 到顶了 if(that.currentPage > 1){ $(".loading-bottom").remove(); $(this).prepend("<div class=‘loading loading-top‘><img src=‘../public/img/loading.gif‘/></div>"); that.currentPage--; SearchBox.contentList = SearchBox.toggleTab(that.currentPage, that.index); that.createItemBox(true); } }else if(($(this).scrollTop() + $(this).outerHeight()) >= $(this)[0].scrollHeight){ // 到底了 if (that.currentPage < that.pagination.totalPage) { $(".loading-top").remove(); $(this).append("<div class=‘loading loading-bottom‘><img src=‘../public/img/loading.gif‘/></div>"); that.currentPage++; SearchBox.contentList = SearchBox.toggleTab(that.currentPage, that.index); that.createItemBox(true); $(this).scrollTop(10); } } }); }, scrollSearchEvent: function(){ var that = this; $(this.rootDiv).find(‘.mCustomScrollbar‘).scroll(function(){ var value = SearchBox._method.trim(that.input.value); if($(this).scrollTop() == 0){ // 到顶了 if(that.currentPage > 1){ $(".loading-bottom").remove(); $(this).prepend("<div class=‘loading loading-top‘><img src=‘../public/img/loading.gif‘/></div>"); that.currentPage--; SearchBox.searchData = SearchBox.onSearchValueChange(value,that.currentPage); that.searchValue = SearchBox.searchData.data; that.searchPagination = SearchBox.searchData.pagination; that.createUl(); } }else if(($(this).scrollTop() + $(this).outerHeight()) >= $(this)[0].scrollHeight){ // 到底了 if (that.currentPage < that.searchPagination.totalPage) { $(".loading-top").remove(); $(this).append("<div class=‘loading loading-bottom‘><img src=‘../public/img/loading.gif‘/></div>"); that.currentPage++; SearchBox.searchData = SearchBox.onSearchValueChange(value,that.currentPage); that.searchPagination = SearchBox.searchData.pagination; if(that.searchPagination.currentPage == that.searchPagination.totalPage && SearchBox.searchData.data.length < 10){ that.searchValue = that.searchValue.concat(SearchBox.searchData.data) }else{ that.searchValue = SearchBox.searchData.data; } $(this).scrollTop(10); that.createUl(); } } }); }, destroy: function(){ if($(‘.search-box-wrap‘)) { $(‘.search-box-wrap‘).remove(); } }, /* * @createNavbar * 创建navbar * */ createNavbar: function(navItem){ var _html = ‘‘; if(navItem && navItem.length){ _html += ‘<ul>‘; _html += ‘<li class="on">‘+ ‘热门‘ +‘</li>‘; navItem.forEach(function(val, index){ if(index==navItem.length-1){ _html += ‘<li>‘+ ‘其他‘ +‘</li>‘; }else{ _html += ‘<li>‘+ val +‘</li>‘; } }); _html += ‘</ul>‘; } SearchBox.navItem = _html; }, /* * * @createWarp * 创建城市BOX HTML 框架 * */ createWarp:function(element){ var div = this.rootDiv = document.createElement(‘div‘); var that = this; // 设置DIV阻止冒泡 SearchBox._method.on(this.rootDiv,‘click‘,function(event){ SearchBox._method.stopPropagation(event); }); // 设置点击文档隐藏弹出的城市选择框 SearchBox._method.on(document, ‘click‘, function (event) { event = SearchBox._method.getEvent(event); var target = SearchBox._method.getTarget(event); if(target == that.input) return false; if (that.searchBox)SearchBox._method.addClass(‘hide‘, that.searchBox); if (that.ul)SearchBox._method.addClass(‘hide‘, that.ul); }); div.className = ‘search-box-wrap‘; div.style.position = ‘absolute‘; div.style.top = 34 + ‘px‘; div.style.zIndex = 999999; var childdiv = this.searchBox = document.createElement(‘div‘); childdiv.className = ‘search-box‘; childdiv.id = ‘searchBox‘; childdiv.innerHTML = SearchBox.navItem; var itemBox = this.itemBox = document.createElement(‘div‘); itemBox.className = ‘item-box‘; childdiv.appendChild(itemBox); div.appendChild(childdiv); this.createItemBox(false); }, /* * * @createitemBox * TAB下面DIV:hot,a-h,i-p,q-z 分类HTML生成,DOM操作 * {HOT:{hot:[]},ABCDEFGH:{a:[1,2,3],b:[1,2,3]},IJKLMNOP:{},QRSTUVWXYZ:{}} **/ createItemBox:function(flag){ var contentList = SearchBox.contentList.data; this.pagination = SearchBox.contentList.pagination; $(".loading").remove(); if(contentList && contentList.length){ if(flag && this.pagination.currentPage == this.pagination.totalPage && contentList.length < 10){ var _html = this.itemBox.innerHTML; }else{ var _html = ‘‘; } contentList.forEach(function(val, index){ _html += ‘<a href="javascript:;" data-name=‘+JSON.stringify(val)+‘>‘+ val.name +‘(‘+ val.code + ‘)‘ +‘</a>‘; }); } this.itemBox.innerHTML = _html || ‘‘; //document.body.appendChild(this.rootDiv); this.input.parentNode.appendChild(this.rootDiv); this.tabChange(); this.linkEvent(); }, /* * * tab按字母顺序切换 * @ tabChange * */ tabChange:function(){ var lis = SearchBox._method.$(‘li‘,this.searchBox); var divs = SearchBox._method.$(‘div‘,this.itemBox); var that = this; for(var i=0,n=lis.length;i<n;i++){ lis[i].index = i; lis[i].onclick = function(){ for(var j=0;j<n;j++){ SearchBox._method.removeClass(‘on‘,lis[j]); SearchBox._method.addClass(‘hide‘,divs[j]); } that.index = this.innerHTML; SearchBox.contentList = SearchBox.toggleTab(that.currentPage,this.innerHTML); that.createItemBox(false); SearchBox._method.addClass(‘on‘,this); SearchBox._method.removeClass(‘hide‘,divs[this.index]); }; } }, /* * * 城市LINK事件 * @linkEvent * */ linkEvent:function(){ var links = SearchBox._method.$(‘a‘,this.itemBox); var that = this; for(var i=0,n=links.length;i<n;i++){ links[i].onclick = function(){ var dataName = $(this).attr(‘data-name‘); that.input.value = this.innerHTML; SearchBox.attrTextModel(that.input.value,JSON.parse(dataName)); SearchBox._method.addClass(‘hide‘,that.searchBox); } } }, /* * * INPUT城市输入框事件 * @inputEvent * */ inputEvent:function(){ var that = this; SearchBox._method.on(this.input,‘click‘,function(event){ event = event || window.event; if(!that.searchBox){ that.createWarp(); }else if(!!that.searchBox && SearchBox._method.hasClass(‘hide‘,that.searchBox)){ // slideul 不存在或者 slideul存在但是是隐藏的时候 两者不能共存 if(!that.ul || (that.ul && SearchBox._method.hasClass(‘hide‘,that.ul))){ SearchBox._method.removeClass(‘hide‘,that.searchBox); } } that.scrollEvent(); }); SearchBox._method.on(this.input,‘blur‘,function(){ }); SearchBox._method.on(this.input,‘keyup‘,function(event){ event = event || window.event; var keycode = event.keyCode; SearchBox._method.addClass(‘hide‘,that.searchBox); var value = SearchBox._method.trim(that.input.value); SearchBox.searchData = SearchBox.onSearchValueChange(value,that.currentPage); that.searchValue = SearchBox.searchData.data; that.searchPagination = SearchBox.searchData.pagination; that.createUl(); that.scrollSearchEvent(); // 下拉菜单显示的时候捕捉按键事件 if(that.ul && !SearchBox._method.hasClass(‘hide‘,that.ul) && !that.isEmpty){ that.KeyboardEvent(event,keycode); } }); }, /* * * 生成下拉选择列表 * @ createUl * */ createUl:function () { var that = this; var str; var value = SearchBox._method.trim(this.input.value); $(".loading").remove(); // 当value不等于空的时候执行 if (value !== ‘‘) { var reg = new RegExp("^" + value + "|\\|" + value, ‘gi‘); // 此处需设置中文输入法也可用onpropertychange var searchResult = []; for (var i = 0, n = that.searchValue.length; i < n; i++) { if (searchResult.length !== 0) { str = ‘<li class="cityname" data-name=‘+JSON.stringify(that.searchValue[i])+‘>‘ + that.searchValue[i].name + ‘(‘+ that.searchValue[i].code + ‘)‘ + ‘</li>‘; } else { str = ‘<li class="cityname" data-name=‘+JSON.stringify(that.searchValue[i])+‘>‘ + that.searchValue[i].name +‘(‘+ that.searchValue[i].code + ‘)‘ + ‘</li>‘; } searchResult.push(str); } this.isEmpty = false; // 如果搜索数据为空 if (searchResult.length == 0) { this.isEmpty = true; str = ‘<li class="empty">对不起,没有找到 "<em>‘ + value + ‘</em>"</li>‘; searchResult.push(str); } // 如果slideul不存在则添加ul if (!this.ul) { var ul = this.ul = document.createElement(‘ul‘); ul.className = ‘cityslide mCustomScrollbar‘; this.rootDiv && this.rootDiv.appendChild(ul); // 记录按键次数,方向键 this.count = 0; } else if (this.ul && SearchBox._method.hasClass(‘hide‘, this.ul)) { this.count = 0; SearchBox._method.removeClass(‘hide‘, this.ul); } this.ul.innerHTML = searchResult.join(‘‘); // 绑定Li事件 this.liEvent(); }else{ SearchBox._method.addClass(‘hide‘,this.ul); SearchBox._method.removeClass(‘hide‘,this.searchBox); } }, /* * * 特定键盘事件,上、下、Enter键 * @ KeyboardEvent * */ KeyboardEvent:function(event,keycode){ var lis = SearchBox._method.$(‘li‘,this.ul); var len = lis.length; switch(keycode){ case 40: //向下箭头↓ this.count++; if(this.count > len-1) this.count = 0; for(var i=0;i<len;i++){ SearchBox._method.removeClass(‘on‘,lis[i]); } SearchBox._method.addClass(‘on‘,lis[this.count]); break; case 38: //向上箭头↑ this.count--; if(this.count<0) this.count = len-1; for(i=0;i<len;i++){ SearchBox._method.removeClass(‘on‘,lis[i]); } SearchBox._method.addClass(‘on‘,lis[this.count]); break; case 13: // enter键 this.input.value = lis[this.count].innerHTML; SearchBox._method.addClass(‘hide‘,this.ul); SearchBox._method.addClass(‘hide‘,this.ul); break; default: break; } }, /* * * 下拉列表的li事件 * @ liEvent * */ liEvent:function(){ var that = this; var lis = SearchBox._method.$(‘li‘,this.ul); for(var i = 0,n = lis.length;i < n;i++){ SearchBox._method.on(lis[i],‘click‘,function(event){ event = SearchBox._method.getEvent(event); var target = SearchBox._method.getTarget(event); var dataName = $(target).attr(‘data-name‘); if(dataName){ that.input.value = target.innerHTML; SearchBox.attrTextModel(target.innerHTML,JSON.parse(dataName)); SearchBox._method.addClass(‘hide‘,that.ul); } }); SearchBox._method.on(lis[i],‘mouseover‘,function(event){ event = SearchBox._method.getEvent(event); var target = SearchBox._method.getTarget(event); SearchBox._method.addClass(‘on‘,target); }); SearchBox._method.on(lis[i],‘mouseout‘,function(event){ event = SearchBox._method.getEvent(event); var target = SearchBox._method.getTarget(event); SearchBox._method.removeClass(‘on‘,target); }) } }}; 组件css代码:
*{margin:0;padding:0;box-sizing:border-box;}.search-box-wrap{font:14px ‘Source Sans Pro‘,‘Helvetica Neue‘,Helvetica,Arial,sans-serif,\5b8b\4f53;background:#fff;text-align:left;}.cityslide{width:400px;list-style:none;margin:0;padding:0;border:1px solid #A9B2BD;overflow:auto;max-height:260px;}.cityslide li{border-bottom: 1px solid #ddd;text-align: left;list-style:none;overflow:hidden;height:34px;padding:0px 10px;line-height:34px;font-weight:normal;width: 100%;}.cityslide li.on{background:#01AAED;color:#555;cursor:pointer;}.cityslide li:hover{background:#01AAED;color:#555;cursor:pointer;}.cityslide li.empty{background:#fff2e8;color:#555;}.cityslide li.empty em{color:red;font-style:normal;}.cityname{float:left;}.cityspell{float:right;}.search-box{width:400px;border:1px solid #ddd;overflow:hidden;}.search-box ul{margin:0;padding:0;overflow:hidden;padding-top: 5px}.search-box ul li:first-child{margin-left:5px;}.search-box ul li{line-height: 24px;float:left;list-style:none;padding:2px;border-bottom:1px solid #DDD;cursor:pointer;display:inline;color:#01AAED;width: auto}.search-box ul li.on{border-bottom-color:#555;position:relative;width: auto}.hide{display:none;}p.tip{color:#555;line-height:20px;padding:5px;margin:0;text-indent:3px;}.item-box{width:400px;border-top:1px solid #ddd;margin-top:-1px;clear:left;overflow:auto;_margin-bottom:8px;max-height: 260px;}.cityTab{overflow:hidden;}.cityinput{ font-size: 12px; padding-left: 2px; border: 1px solid #ddd; }.item-box a{padding-left:10px;line-height:34px;display:block;color:#555;text-decoration:none;border-bottom: 1px solid #ddd;}.item-box a:hover{color:#555;background: #01AAED;}.item-box .loading-top{margin-top: 0px}.item-box .loading img {position:relative;top:10px; } 组件引入:
<input ng-model="orderProduct" placeholder="请输入名称或编码" id="select-product" ng-enter="search()" ng-trim="true" type="text" maxlength="30" autocomplete="off">
ID索引
$scope.contentList = orderSearchService.getProductAllData({‘urlParams‘: {‘isHot‘: true}});$scope.navItem = orderSearchService.getProductNavItem();
var productBox = new SearchBox.init({ inputId:"select-product", searchData:[], navItem: $scope.navItem.data, tabIndex:‘热门‘, contentList: $scope.contentList.data, toggleTab: function(currentPage,index){ this.tabIndex = index; var config = { ‘urlParams‘: { ‘isHot‘:false, ‘pageIndex‘: currentPage || 1, ‘pageSize‘: 10, ‘capital‘: index } }; if(index == "热门"){ config.urlParams.isHot = true; config.urlParams.capital = ‘‘; } if(index == "其他"){ config.urlParams.isHot = false; config.urlParams.capital = ‘_‘; } var result = orderSearchService.getProductAllData(config); return {data:result.data,pagination:result.pagination} }, onSearchValueChange:function(data,currentPage) { var config = { ‘urlParams‘: { ‘q‘:data, ‘isHot‘:false, ‘pageIndex‘: currentPage || 1, ‘pageSize‘: 10, ‘capital‘: ‘‘ } }; var result = orderSearchService.getProductAllData(config); return {data:result.data,pagination:result.pagination}; }, attrTextModel: function (name, data) { $scope.orderProduct = name || ‘‘; $scope.orderProductUid = data.uid || ‘‘; $scope.$apply(); }});
原文地址:https://www.cnblogs.com/lovemiao/p/8580883.html
时间: 2024-11-05 22:53:46