目錄
一.說明
mui的picker插件功能不滿足當前需求,在picker的基礎上新做個插件,帶有搜索功能。
實現可以 實時搜索,實時改變列表選項。
新建myMuiSearchPicker.js 和 myMuiSearchPicker.css
筆記:
1.關於選項條高度,在第一遍初始化時,高度是組件默認高度。
在mui.picker.js中設置的
在自定義組件中,設置選項條。
在設置完數據後,要再一次初始化,並重新計算項目位置。這裏計算項目位置不要傳true
2.組件位置
通過設置top,top是定值
top = 屏幕高 - 組件高
3.組件的滾動顯示高度
二.上代碼
1.html
引用 mui.js/css 和 mui.picker.js/css 或者用min版的
var searchPicker = new mui.SearchPicker({ title:"位置選擇", placeholder:"搜索位置", data:[{ value: "", text: "未選擇" },{ value: "first", text: "第一項" }, { value: "second", text: "第二項" }, { value: "third", text: "第三項" }] });
2.css
.searchPicker{ bottom:-400px !important; background-color: #fff; border-top: 0; border-top-left-radius: 14px; border-top-right-radius: 14px; z-index:99999 !important; } .searchPicker.mui-active{ /* bottom:0 !important;*/ /* top: calc( 100% - 428px) !important;*/ } .searchPicker .mui-poppicker-header{ padding:0 6px !important; } .searchPicker .mui-poppicker-btn-ok{ float:right; margin:9px 7px; border: 1px solid rgba(254,45,76,1) !important; background-color: rgba(254,45,76,1) !important; } .searchBtnCancel{ float:right; font-size: 20px !important; margin: 13px 5px; padding: 0 !important; line-height: 0; border-radius: 20px; } .searchPicker .mui-poppicker-body{ height:380px; border-top:0 !important; overflow-y:hidden; } .searchPicker .mui-picker{ height:560px !important; } .searchPicker .mui-search{ width:90%; margin-left: auto; margin-right: auto; } .searchPicker .mui-placeholder{ text-align: left !important; padding-left:10px; } .searchPicker .pickerTitle{ display:inline-block; position:absolute; width:100%; height:46px; line-height:46px; font-size: 16px; text-align: center; color:#0C0C0C; font-weight: 600; } .searchPicker .mui-picker-inner{ -webkit-mask-box-image: -webkit-linear-gradient(bottom, transparent, transparent 5%, #fff 10%, #fff 93%, transparent 95%, transparent); } .searchPicker .mui-pciker-list,.searchPicker .mui-pciker-rule{ top:10% !important; height:40px !important; } .searchPicker .mui-pciker-rule-ft { border-top: solid 1px rgba(254,45,76,1) !important; border-bottom: solid 1px rgba(254,45,76,1) !important; } .searchPicker .mui-pciker-list{ height:40px !important; line-height:40px; }
3.js
/** * 彈出選擇列表插件 * 此組件依賴 listpcker ,請在頁面中先引入 mui.picker.css + mui.picker.js * varstion 1.0.0 * by Liyuqi */ (function($, document) { $.dom = function(str) { if (typeof(str) !== 'string') { if ((str instanceof Array) || (str[0] && str.length)) { //如果是數組 return [].slice.call(str); } else { return [str]; } } if (!$.__create_dom_div__) { $.__create_dom_div__ = document.createElement('div'); } $.__create_dom_div__.innerHTML = str; return [].slice.call($.__create_dom_div__.childNodes); //返回創建div的子節點 }; var panelBuffer = '<div class="mui-poppicker searchPicker">\ <div class="mui-poppicker-header">\ <div class="pickerTitle"></div>\ <button class="mui-btn searchBtnCancel"><span class="mui-icon mui-icon-closeempty"></span></button>\ <button class="mui-btn mui-btn-blue mui-poppicker-btn-ok">確定選擇</button>\ <div class="mui-poppicker-clear"></div>\ </div>\ <div class="mui-poppicker-body">\ <div class="mui-input-row mui-search" style="text-align: left">\ <input type="search" class="mui-input-clear" class=placeholder="">\ </div>\ </div>\ </div>'; var pickerBuffer = '<div class="mui-picker">\ <div class="mui-picker-inner">\ <div class="mui-pciker-rule mui-pciker-rule-ft"></div>\ <ul class="mui-pciker-list">\ </ul>\ <div class="mui-pciker-rule mui-pciker-rule-bg"></div>\ </div>\ </div>'; //定義彈出選擇器類 var SearchPicker = $.SearchPicker = $.Class.extend({ //構造函數 init: function(options) { var self = this; self.options = options || {}; self.options.title= options.title||''; self.options.placeholder= options.placeholder||''; self.options.data= options.data||[]; /*self.options.buttons = self.options.buttons || ['x', '確定'];*/ self.panel = $.dom(panelBuffer)[0]; document.body.appendChild(self.panel); self.title=self.panel.querySelector('.pickerTitle'); self.ok = self.panel.querySelector('.mui-poppicker-btn-ok'); self.cancel = self.panel.querySelector('.searchBtnCancel'); self.body = self.panel.querySelector('.mui-poppicker-body'); self.input = self.panel.querySelector('input[type="search"]'); $('.mui-input-row input').input(); self.spanPlaceholder = self.body.querySelector('.mui-placeholder span:last-child'); self.spanPlaceholder.textContent=''; /*self.searchClean= self.panel.querySelector('mui-icon-clear');*/ self.mask = $.createMask(); self.title.innerText=self.options.title; self.input.placeholder=self.options.placeholder; self.top = (document.body.clientHeight - 428)+"px"; /*self.cancel.innerText = self.options.buttons[0];*/ /* self.ok.innerText = self.options.buttons[1];*/ self.cancel.addEventListener('tap', function(event) { self.hide(); }, false); self.ok.addEventListener('tap', function(event) { if (self.callback) { var rs = self.callback(self.getSelectedItems()); if (rs !== false) { self.hide(); } } self.setData(self.options.data); self.body.querySelector(".mui-input-row").classList.remove("mui-active"); self.input.blur(); }, false); self.body.querySelector('.mui-placeholder').addEventListener('tap',function(e){ self.body.querySelector(".mui-input-row").classList.add("mui-active"); self.input.focus(); },false); self.input.addEventListener('tap',function(e){ self.body.querySelector(".mui-input-row").classList.add("mui-active"); self.input.blur(); self.input.focus(); },false); self.input.addEventListener('focus',function(){ self.panel.style.top = self.top; }); self.input.addEventListener('input', function() { self.panel.style.top = self.top; self.searchClean= self.input.nextSibling; self.searchClean.addEventListener('tap',sc,false); var filter = this.value; var filterList= []; if (filter) { for(var i=0; i<self.options.data.length;i++){ if(self.options.data[i].text.search(filter)!= -1){ filterList.push(self.options.data[i]); } } self.setData(filterList); } else { self.setData(self.options.data); } self.pickers[0].setSelectedIndex(0, 1000); },false); self.input.addEventListener("keydown",function(e){ if(e.keyCode==13||e.key=="Enter"){ self.body.querySelector(".mui-input-row").classList.remove("mui-active"); self.input.blur(); } },false); function sc(){ if(!self.searchClean.value){ self.setData(self.options.data); } self.searchClean.removeEventListener('tap',sc,false); } self.mask[0].addEventListener('tap', function() { self.hide(); }, false); self._createPicker(); //防止滾動穿透 self.panel.addEventListener($.EVENT_START, function(event) { event.preventDefault(); }, false); self.panel.addEventListener($.EVENT_MOVE, function(event) { event.preventDefault(); }, false); if(self.options.data){ self.setData(self.options.data); } }, _createPicker: function() { var self = this; var layer = self.options.layer || 1; var width = (100 / layer) + '%'; self.pickers = []; for (var i = 1; i <= layer; i++) { var pickerElement = $.dom(pickerBuffer)[0]; pickerElement.style.width = width; self.body.appendChild(pickerElement); var picker = $(pickerElement).picker(); self.pickers.push(picker); pickerElement.addEventListener('change', function(event) { var nextPickerElement = this.nextSibling; if (nextPickerElement && nextPickerElement.picker) { var eventData = event.detail || {}; var preItem = eventData.item || {}; nextPickerElement.picker.setItems(preItem.children); } }, false); pickerElement.addEventListener('touchstart',function(e){ self.body.querySelector(".mui-input-row").classList.remove("mui-active"); self.input.blur(); },false); pickerElement.querySelector(".mui-pciker-rule-ft").addEventListener('tap',function(event) { if (self.callback) { var rs = self.callback(self.getSelectedItems()); if (rs !== false) { self.hide(); } } self.setData(self.options.data); self.body.querySelector(".mui-input-row").classList.remove("mui-active"); self.input.blur(); }, false) } }, //填充數據 setData: function(data) { var self = this; data = data || []; self.pickers[0].setItems(data); self.pickers[0].init(); self.pickers[0].calcElementItemPostion(); }, //獲取選中的項(數組) getSelectedItems: function() { var self = this; var items = []; for (var i in self.pickers) { if(self.pickers.hasOwnProperty(i)) { // 修復for in會訪問繼承屬性造成items報錯情況 var picker = self.pickers[i]; items.push(picker.getSelectedItem() || {}); } } return items; }, //顯示 show: function(callback) { var self = this; self.callback = callback; self.mask.show(); document.body.classList.add($.className('poppicker-active-for-page')); self.panel.classList.add($.className('active')); //處理物理返回鍵 self.__back = $.back; $.back = function() { self.hide(); }; setTimeout(function () { self.panel.style.top = (document.body.clientHeight - 428) + "px"; },0); }, //隱藏 hide: function() { var self = this; self.panel.style.top = document.body.clientHeight+"px"; if (self.disposed) return; self.panel.classList.remove($.className('active')); self.body.querySelector('.mui-search').classList.remove($.className('active')); self.input.value=''; self.mask.close(); document.body.classList.remove($.className('poppicker-active-for-page')); //處理物理返回鍵 $.back=self.__back; if(self.options.data){ self.setData(self.options.data); } }, dispose: function() { var self = this; self.hide(); setTimeout(function() { self.panel.parentNode.removeChild(self.panel); for (var name in self) { self[name] = null; delete self[name]; } self.disposed = true; }, 300); } }); })(mui, document);