MMIS Prototype
眾所周知,比較古老的圓角的做法是通過表格和圖像構成。但隨著AJAX的流行、CSS + DIV的頁面布局技術的風靡,古老的做法顯得蒼白無力,所以人們不斷尋求改進的方法。本文的實現就是一種現在比較流行的做法。
實現原理
其實這種方法的原理很簡單——在要圓角的元素的上下堆放一些邊緣(MARGIN)不同的<DIV>元素(也有的使用其它元素的,如<B>等,不過原理是一樣的),如下圖所示:
清單1 原理圖
接下來的問題就是計算margin的長度。這也不難只要運用一下初中所學的勾股定理便可以求出來,如下圖所示:
清單2 MARGIN求解圖
具體編碼
下面該工具類的源碼:
var
Corner
=
{
? ?
//
標志圓角位置的旗標
? ?TOP_LEFT: ? ?
0x1
,
? ?TOP_RIGHT: ? ?
0x2
,
? ?BOTTOM_LEFT: ?
0x4
,
? ?BOTTOM_RIGHT:
0x8
,
? ?ALL: ? ? ? ? ?
0xf
,
? ?

? ?
/**/
/*
*******************************************************
? ?* target: 要圓角的目標元素
? ?* radius: 圓角的半徑,默認值為5
? ?* flags: 圓角位置的旗標或其組合,默認值為全部
? ?* backgroundColor: 圓角的背景色,默認值為目標元素的背景色
? ?*******************************************************
*/
? ?round:
function
(target,
radius, flags, backgroundColor)
{
? ? ? ?
var
t
=
$(target);
? ? ? ?
var
r
=
radius
||
5
;
? ? ? ?
var
f
=
flags
||
Corner.ALL;
? ? ? ?
var
c
=
Element.getStyle(t,
'backgroundColor');
? ? ? ?
var
b
=
backgroundColor
||
c;
? ? ? ?
? ? ? ?
//
修正在IE里元素樣式為FLOAT時,圓角DIV寬度為0的BUG
? ? ? ?
var
ft
=
Element.getStyle(t, '
float
');

? ? ? ?
if
(navigator.appVersion.match(
/
\bMSIE\b
/
)
&&
ft
!=
'none'
&&
!
t.style.width)
{ ? ? ? ? ? ?

? ? ? ? ? ?Element.setStyle(t,
{ width: Element.getWidth(t)
+
'px' }
);
? ? ? ?}
? ? ? ?
? ? ? ?
//
創建DIV,并把目標元素的內容剪切到其中
? ? ? ?
var
d
=
document.createElement('div'); ? ? ? ? ?
? ? ? ?d.innerHTML
=
t.innerHTML;
? ? ? ?t.innerHTML
=
''; ? ? ? ?
? ? ? ?
? ? ? ?
//
設置新DIV的背景色為目標元素的背景色,并目標元素為透明背景
? ? ? ?Element.setStyle(
d,
{ backgroundColor: c }
); ? ? ?

? ? ? ?Element.setStyle( t,
{ backgroundColor: 'transparent' }
); ? ? ?
? ? ? ?
? ? ? ?
//
設置新DIV的高度為目標元素的高度
? ? ? ?
var
h
=
t.style.height;
? ? ? ?
var
nh
=
0
;

? ? ? ?
if
(h)
{

? ? ? ? ? ?Element.setStyle( d,
{ height: h }
);
? ? ? ? ? ?nh
=
parseInt(h);
? ? ? ?}
? ?
? ? ? ? ? ? ? ?
? ? ? ?
? ? ? ?
//
設置新DIV的縮進
? ? ? ?
var
p
=
Element.getStyle(t, 'padding');

? ? ? ?
if
(p)
{

? ? ? ? ? ?Element.setStyle( d,
{ padding: p }
);
? ? ? ? ? ?

? ? ? ? ? ?Element.setStyle( t,
{ padding: '0px 0px 0px 0px' }
);
? ? ? ?}
? ?
? ? ?
? ? ? ?
? ? ? ?
//
創建用于新DIV和圓角DIV的文檔片段,這樣避免每次設置元素樣式或添加新元素時重繪頁面,提高效率
? ? ? ?
var
ds
=
document.createDocumentFragment();
? ? ? ? ? ? ? ?
? ? ? ?
var
ls
=
null
;
? ? ? ?
//
創建頂部圓角DIV
? ? ? ?
if
(f
&
(Corner.TOP_LEFT
|
Corner.TOP_RIGHT))
{
? ? ? ? ? ?ls
=
Corner._createRoundFragment(r, f, b ,
false
); ? ? ? ? ? ?
? ? ? ? ? ?ds.appendChild(ls); ? ? ?
? ? ??
? ? ? ? ? ?nh
+=
r;
? ? ? ?}
? ?
? ?
? ? ? ?
? ? ? ?ds.appendChild(d);
? ? ? ?
? ? ? ?
//
創建底部圓角DIV
? ? ? ?
if
(f
&
(Corner.BOTTOM_LEFT
|
Corner.BOTTOM_RIGHT))
{
? ? ? ? ? ?ls
=
Corner._createRoundFragment(r, f, b,
true
); ? ? ? ? ? ?
? ? ? ? ? ?ds.appendChild(ls);?
? ? ? ? ? ?nh
+=
r;
? ? ? ?}
?
? ? ? ?

? ? ? ?
if
(h)
{

? ? ? ? ? ?Element.setStyle( t,
{ height: nh
+
'px' }
); ?
? ?
? ? ? ?}
? ?
? ?
? ? ? ?
? ? ? ?t.appendChild(ds); ??
? ?}
,
? ?

? ?_createRoundFragment:
function
(r, f, c, b)
{
? ? ? ?
var
ls
=
document.createDocumentFragment();
? ? ? ?
var
l
=
null
;
? ? ? ?
var
m
=
ml
=
mr
=
null
;
? ? ? ?
var
j
=
0
;

? ? ? ?
for
(i
=
1
; i
<=
r; i
++
)
{
? ? ? ? ? ?l
=
document.createElement('div');
? ? ? ? ? ?
? ? ? ? ? ?
//
計算margin
? ? ? ? ? ?j
=
b
?
i : r
-
i
+
1
;
? ? ? ? ? ?m
=
Math.sqrt(r
*
r
-
j
*
j); ?
? ? ? ? ?
? ? ? ? ? ?m
=
Math.round(r
-
m)
+
'px';
? ? ? ? ? ?

? ? ? ? ? ?
if
(b)
{
? ? ? ? ? ? ? ?ml
=
f
&
Corner.BOTTOM_LEFT
?
m : '0px';
? ? ? ? ? ? ? ?mr
=
f
&
Corner.BOTTOM_RIGHT
?
m : '0px'; ? ? ? ? ? ?

? ? ? ? ? ?}
else
{
? ? ? ? ? ? ? ?ml
=
f
&
Corner.TOP_LEFT
?
m : '0px';
? ? ? ? ? ? ? ?mr
=
f
&
Corner.TOP_RIGHT
?
m : '0px'; ? ? ? ? ? ?
? ? ? ? ? ?}
? ? ? ? ? ?Element.setStyle( l,
{ backgroundColor: c,
? ? ? ? ? ? ? ? ? ? ? ?
? ? ? ? ? fontSize: '1px',
? ? ? ? ? ? ? ? ? ? ? ?
? ? ? ? ? height: '1px', ? ? ? ? ?
? ? ? ? ? ? ? ? ? ? ? ??
? ? ? ? ? ? ? ? ? ? ? ?
? ? ? ? ? marginLeft: ml,
? ? ? ? ? ? ? ? ? ? ? ?
? ? ? ? ? marginRight: mr,
? ? ? ? ? ? ? ? ? ? ? ?
? ? ? ? ? overflowX: 'hidden',
? ? ? ? ? ? ? ? ? ? ? ?
? ? ? ? ? overflowY: 'hidden' }
);
? ? ? ? ? ?ls.appendChild(l);
? ? ? ?}
? ? ? ?
return
ls;
? ?}
}
清單3 實現代碼
因為Javascript是沒有方法重寫的,所以當你調用Corner.round('div1')和調用Coner.round('div1', 20)是一樣的,它們最終調用的都是Corner.round(target, radius, flags, backgroundColor),只過沒有賦值的參數會為undefined。這里有一個小技巧,就var
r = radius || 5,這里的“||”符號表示如果radius為undefined、null或0等值時,r的取值為5。
接著讓我們看看運行的頁面代碼:
<!
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
>
? ?
<
title
>
RounderCorner Prototype
</
title
>
??
? ?
<
script
type
="text/javascript"
src
="scripts/prototype-1.5.0.js"
></
script
>
? ?
<
script
type
="text/javascript"
src
="scripts/Corner.js"
></
script
>
? ?
<
script
type
="text/javascript"
>
? ?
//
<![CDATA[ ? ? ?
? ? Event.observe(window,
'load', init,
false
);
? ??
? ?
function
init() { ? ? ?
?
? ? ? ? Corner.round('div1');
? ? ? ? Corner.round('div2',
20
, Corner.TOP_LEFT
|
Corner.BOTTOM_RIGHT);
? ? ? ? Corner.round('div3',
20
,
Corner.ALL, 'Red');
? ? }
? ?
//
]]>
? ?
</
script
>
? ?
</
head
>
<
body
>
? ?
<
div
id
="div1"
style
="width: 318px; height:
103px; background-color: #ffcccc"
>
? ? ? ? Corner.round('div1');
</
div
>
? ?
<
br
/>
? ?
<
div
id
="div2"
style
="width: 317px; height:
100px; background-color: #cccccc"
>
? ? ? ? Corner.round('div2', 20, Corner.TOP_LEFT | Corner.BOTTOM_RIGHT);
</
div
>
? ?
<
br
/>
? ?
<
div
id
="div3"
style
="width: 315px; height:
100px; background-color: #ccffcc"
>
? ? ? ? Corner.round('div3', 20, Corner.ALL, 'Red');
</
div
>
</
body
>
</
html
>
清單4 測試代碼
上述代碼很簡單明了,相信大家都明白。下面看一下運行截圖吧。
清單5 運行截圖
總結
以上代碼只作拋磚引玉之用,所以還有很多功能沒有實現。
posted on 2007-03-23 01:37
Max 閱讀(6544)
評論(12) 編輯 收藏 所屬分類:
方法與技巧(Tips & tricks)