|
發表者 |
討論內容 |
冷日 (冷日) |
發表時間:2010/3/17 14:54 |
- Webmaster

- 註冊日: 2008/2/19
- 來自:
- 發表數: 15771
|
- [轉貼]通用Combobox(Select)以至一般控件的設計與實現
通用Combobox(Select)以至一般控件的設計與實現 2009年06月14日 由 Bgser本文涉及到combobox設計與實現上的一些方法論,並提供了一個參考實現. Combobox(以下簡稱combox),也就是通常的意義上的Select控件,最具代表的是html裡的select元素, 它可以在有限的空間內提供多個選項給用戶選擇,這個與菜單十分相似,並作為表單元素將數據提交到服務器. 種種原因使得有時有必要自定義一個combox控件,來代替自帶的select,來分析一下html的select有什麼基本功能. >與form集成,字段可提交 >控件禁用或禁用單個選項 >選擇,可以指定選擇任意項或不選 >鍵盤導航 支持鍵盤上下鍵導航選項,ENTER,ESC鍵關閉下拉並響應 >滾動 如果列表項過多而下拉空間有限,就應該出現滾動條, 並且在用戶選擇選項過程中,選項要相應的滾動到可視範圍內 >下拉框下拉時定位到可視範圍內 >下拉框上下文切換時自動消失 即點擊combox外時下拉框自動消失 如果是自定義的combox控件,可擴展功能有 >可編輯或不可編輯 >控件自定事件 >ajax加載 根據響應動態加載項 >過濾 用戶在輸入過程中過濾條項並自動定位 >定制下拉框 下拉框彈出的內容是可定制的,根據實現需要定制,如一個列表,一顆樹,一個表格等 >在定制下拉框後combox的基本行為保持不應 自定下拉框後不能改變控件應用的基本行為,如選擇,鍵導航等 >多樣式支持,如控件的hover,點擊,下拉時都有不同外觀效果,下拉框具有陰影等 如果自定義combox控件,以上的基本功能是要實現的,不同方式有不同實現,越靈活就越不簡單,. 現在考慮一個在封閉式環境下的實現, 這所謂的封閉環境是指為特定的需求應用而實現,代碼考慮不重用,在響應過程中不與外界進行通訊,功能與控件完全一體化,具有很強的針對性實現,
這種實現較為簡單,根據需求可部分實現select功能,有時為了設計與實現上的便利,用到多種的hack. 例如在HTML模板上的設計,可將下拉框的HTML組織在控制自身裡, 而不是將下拉框的加在BODY中,這種設計簡單明瞭,下拉定位方便,但也造成下拉框不夠通用,在樣式控制方面也要一定的技巧. 這類封閉環境下的產物常見有的一些自動完成控件,拿來就可以用. 下面來考慮一個通用的,可擴的設計方案 這裡所謂通用,是指一個集成的環境裡面,不同應用是共享的,代碼是可重用的,來對上面combox所有功能分析一下,給控件解耦,提取出一些獨立的功能,並給出一個與combox無關的控件設計模型. 一個控件模型可由以下一個或多個模型的組合而成 1.事件模型(event model) 具有事件模型的控件有添加事件監聽器,發送,和移除事件的能力. 給控件建立事件模型是很有意義的,外部可監聽控件一些感興趣的事件並利用事件進行通訊,如MVC模型的實現多是基於事件(消息)的驅動. 實現了事件模型的控件具有可擴性,因為事件可有多個監聽器,或者說通常意義上的回調,這個當然與單個回調效果不一樣了. 有必要說說HTML事件模型與自定的不同,HTML受限於HTML結點而不是控件的事件,並且外界並不能向結點發送事件. 2.選擇模型(selection model) 具有選擇模型的控件具有單選,多選,並給合鍵盤導航選擇等功能. 3.加載模型(loading model) 加載模型使得控件有自動Ajax加載並組裝數據的能力 4.裝飾模型(decoration model) 裝飾模型與前面的幾個模型不同,前面的通常是控件自身就支持,或是控件組成的不可或缺部分,而裝飾模型不是控件自身就有的,它顯得可有可無,只起來裝飾效果, 而裝飾時充分利用了其它的幾個模型,例如在加載的時候給控件裝飾一個」加載中」圖標,利用事件模型作監聽,利用加載模型加載前觸發,在加載後移除效果. 此外不同應用還可獨立出不同的模型,這裡就不多說了. 通用的控件建好模型後,利用這些設計一個通用而功能齊全的combox控件.
combox控件根據視圖劃分為觸發部分和下拉部分,其中下拉部分作為一個外部控件引入. 為了支持下拉的靈活實現,並且要求不同實現要具有一致的行為,下拉部分這控件必須支持上面所說的幾個模型. 這樣一來,Combobox就具有了大部分功能,並且行為始終保持一致. 實現參考: http://www.bgscript.com/bgjs/samples/combo.html 講一下實現參考例子裡的內容: 裡面的combox的下拉控件都實現了以上幾種模型, 下拉框作為selector引入到combox, selector在裡面的分別是組控件,樹型控件和小視圖分組控件, 它們在combox中都表現出一致的行為,不加修改就可放到combox中. 下拉時出現loading圖標和樹型控件的loading圖標是裝飾模型實現後引起的效果, 它監聽由加載模型觸發的open,final事件並作出相應的處理. 聲明: 轉載請註明轉自 背光腳本 - www.bgscript.com 原文出處:通用Combobox(Select)以至一般控件的设计与实现 » bgscript.com - JavaScript脚本编程与WEB应用开发 | JavaScript前端开发 WEB前端技术 用户体验
|
|
冷日 (冷日) |
發表時間:2010/3/17 14:56 |
- Webmaster

- 註冊日: 2008/2/19
- 來自:
- 發表數: 15771
|
- [轉貼]BackLight實現 Select - Combox 控件
BackLight實現 Select - Combox 控件 2009年06月11日 由 Bgser    - 支持鍵盤導航
- 支持滾動跟進
- 條目過濾
- Ajax動態加載
- 與Form集成,可直接提交
- 與CSelectedContainer結合,可自定任意下拉框
演示地址: http://www.bgscript.com/bgjs/samples/combo.html 聲明: 轉載請註明轉自 背光腳本 - www.bgscript.com 原文出處:BackLight实现 Select - Combox 控件 » bgscript.com - JavaScript脚本编程与WEB应用开发 | JavaScript前端开发 WEB前端技术 用户体验
|
|
冷日 (冷日) |
發表時間:2010/3/17 14:59 |
- Webmaster

- 註冊日: 2008/2/19
- 來自:
- 發表數: 15771
|
- [分享]通用Combobox(Select)範例原始碼
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>CCombox
</title>
<script>
var CTemplate = {
BLANK_IMG: '../default/s.gif'
};
</script>
<script type="text/javascript" src="../bglib-all-debug.js"></script>
<script type="text/javascript" src="../more/folderview.js"></script>
<link rel="stylesheet" href="../default/global.css" type="text/css"/>
<link rel="stylesheet" href="../default/ru_share.css" type="text/css"/>
<link rel="stylesheet" href="resources/example.css" type="text/css"/>
<style>
.g-tree .g-panel-body, .g-folderview-wrap{border:1px solid #CCC;border-top:0;}
.g-folderview-ctx dd{margin:5px;}
</style>
</head>
<body lang="zh">
<p> 下拉框作為selector引入到combox,
<br/> selector在裡面的分別是組控件,樹型控件和小視圖分組控件,
<br/> 它們在combox中都表現出一致的行為,不加修改就可放到combox中.
<br/> 下拉時出現loading圖標和樹型控件的loading圖標是裝飾模型實現後引起的效果,
<br/> 它監聽由加載模型觸發的open,final事件並作出相應的處理.
<br/> 在firebug下可察看事件
</p>
<div style="margin:20px 30px;position:relative;"> <h2>帶滾動條,默認下拉,可編輯</h2>
<div id="def_combo">
</div> <h2>隨內容伸縮,下拉,可編輯</h2>
<div id="auto_combo">
</div> <h2>禁用</h2>
<div id="disable_combo">
</div> <h2>不可編輯</h2>
<div id="unedit_combo">
</div> <h2>自定下拉控件和過濾方式</h2>
<div id="tree_combo">
</div> <h2>自定下拉控件和過濾方式 + 滾動 + Ajax動態加載</h2>
<div id="tree_ajax_combo">
</div> <h2>只要基於CSelectedContainer容器類的控件都可以</h2>
<div id="other_combo">
</div>
</div>
</body>
</html>
<script>
Event.ready(function(){
//
// 默認下拉
//
var cb = new CCombox({showTo:'def_combo', autoRender:true,width:300,array:[
{title:'粉綠色',icon:'icoIbx'},
{title:'粉紅色',icon:'icoDft'},
{title:'藍色',icon:'icoIbx'},
{title:'清除記錄',icon:'icoDel' ,disabled:true},
{title:'粉紅色',icon:'icoDft'},
{title:'藍色',icon:'icoNote'},
{title:'清除記錄',icon:'icoDel'},
{title:'粉綠色',icon:'icoIbx'},
{title:'粉紅色',icon:'icoDft'},
{title:'藍色',icon:'icoDft'},
{title:'清除記錄',icon:'icoDel' ,disabled:true},
{title:'粉紅色',icon:'icoDft'},
{title:'藍色',icon:'icoNote'},
{title:'清除記錄',icon:'icoDel'}
]});
cb.select(2);
cb.setScrollorHeight(150);
cb = new CCombox({showTo:'auto_combo', autoRender:true,width:300,array:[
{title:'粉綠色',icon:'icoIbx'},
{title:'粉紅色',icon:'icoDft'},
{title:'藍色',icon:'icoIbx'},
{title:'清除記錄',icon:'icoDel' ,disabled:true},
{title:'粉紅色',icon:'icoDft'},
{title:'藍色',icon:'icoNote'},
{title:'清除記錄',icon:'icoDel'},
{title:'粉綠色',icon:'icoIbx'},
{title:'粉紅色',icon:'icoDft'},
{title:'藍色',icon:'icoDft'},
{title:'清除記錄',icon:'icoDel' ,disabled:true},
{title:'粉紅色',icon:'icoDft'},
{title:'藍色',icon:'icoNote'},
{title:'清除記錄',icon:'icoDel'}
]});
//不可編輯
cb = new CCombox({showTo:'unedit_combo', autoRender:true,uneditable:true, width:300,array:[
{title:'粉綠色',icon:'icoIbx'},
{title:'粉紅色',icon:'icoDft'},
{title:'藍色',icon:'icoIbx'},
{title:'清除記錄',icon:'icoDel' ,disabled:true},
{title:'粉紅色',icon:'icoDft'},
{title:'藍色',icon:'icoNote'},
{title:'清除記錄',icon:'icoDel'},
{title:'粉綠色',icon:'icoIbx'},
{title:'粉紅色',icon:'icoDft'},
{title:'藍色',icon:'icoDft'},
{title:'清除記錄',icon:'icoDel' ,disabled:true},
{title:'粉紅色',icon:'icoDft'},
{title:'藍色',icon:'icoNote'},
{title:'清除記錄',icon:'icoDel'}
]});
//禁用
cb = new CCombox({showTo:'disable_combo', disabled: true, autoRender:true,uneditable:true, width:300});
// ----------------------------------
// 下拉為樹
//自定義過濾
function treeFilter(matcher, caller){
var caller = caller || window, fn = arguments.callee;
if(this.children){
var cm = true;
CC.each(this.children, (function(){
if(!matcher.call(caller,this) && !this.nodes){
this.display(0);
cm = false;
return;
}
this.display(1);
if(this.nodes && this.expanded)
fn.call(this, matcher, caller);
}));
}
}
var tree = new CTree({title:'tree', showTo:document.body, hidden:true,filter:treeFilter});
tree.root.fromArray([
{title:'disabled item',nodes:true,disabled:true},
{title:'B'},
{title:'C',nodes:true}
]);
tree.root.$(2).fromArray([
{title:'disabled A',nodes:true,disabled:true},
{title:'B',disabled:true},
{title:'items',nodes:true}
]);
tree.render();
//指定selector
cb = new CCombox({showTo:'tree_combo', selector:tree, autoRender:true,width:350});
tree = new CTree({title:'tree2', url:'/q?bg_q=test_group',
autoConnect:true, showTo:document.body, hidden:true,filter:treeFilter});
tree.root.fromArray([
{title:'Back Light 點擊展開', nodes:true},
{title:'BCDEFJDFL;AJSDL'},
{title:'disabled item',nodes:true,disabled:true},
{title:'BCDEFJDFL;AJSDL'},
{title:'C',nodes:true},
{title:'item something',disabled:true},
{title:'BCD人物事件'},
{title:'CDEFASLDFJ', nodes:true},
{title:'disabled item',nodes:true,disabled:true},
{title:'AAAAAAAAAAAAAA'},
{title:'WEB前端'}
]);
tree.root.$(2).fromArray([
{title:'disabled A',nodes:true,disabled:true},
{title:'B',disabled:true},
{title:'items',nodes:true}
]);
tree.render();
tree.root.expand();
//指定selector
cb = new CCombox({showTo:'tree_ajax_combo', autoRender:true,selector:tree, width:350});
cb.setScrollorHeight(150);
//
// 其它基於CSelectedContainer容器的控件
//
var foldview = new CFolderView({
showTo:document.body,
navKeyEvent : true,
hidden:true,
shadow:true,
title:'請選擇其中一項',
autoRender:true
});
//指定selector
cb = new CCombox({showTo:'other_combo', selector:foldview, autoRender:true,width:320});
cb.selector.on('comboxshow', function(){
//content loaded
if(this.loaded){
return;
}
//方便顯示loading..
this.setHeight(100);
this.on('load',(function(){
this.style('height','');
this.height = false;
}));
this.on('final',(function(){
//更新數量
this.setTitle(this.title);
}));
this.connect('http://www.bgscript.com/q?bg_q=foldview_data');
});
});
</script>
|
|
|