众所周知,比较古老的圆角的做法是通过表格和图像构成。但随着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 运行截图
分享到:
相关推荐
3. **prototype.js**:Prototype是另一个广泛使用的JavaScript库,它提供了许多实用的函数和类,增强了JavaScript的基础功能。orange.js可能构建在Prototype之上,利用其强大的面向对象特性。 4. **effects.js**:...
CustomDoubleRectangle.prototype.paintVertexShape = function(c, x, y, w, h) { c.begin(); c.roundrect(x, y, w, h, 8, 8); // 内部矩形 c.fillAndStroke(); c.setStrokeColor(this.stroke); c....
第七章通过创建一个基于表格的应用程序,深入介绍了UITableView及其协议的使用,包括如何设计用户界面、如何将数据源(DataSource)和委托(Delegate)连接起来,以及如何在表格视图中添加缩略图和隐藏状态栏。...
1. **选择器扩展**:新增了类选择器、伪类和伪元素,如nth-child()、:before、:after等,提高了样式的灵活性。 2. **边框与背景**:引入圆角边框(border-radius)、阴影效果(box-shadow)和线性渐变(linear-...
在Flash中使用ActionScript与HTML中的JavaScript进行交互,可以通过Flash Player提供的`ExternalInterface`类来实现: ```actionscript // Flash中的ActionScript var result:String = ExternalInterface.call(...
MooTools是一个基于JavaScript的轻量级框架,专注于简洁的代码和易于扩展的设计: - **链式调用**:支持链式方法调用,使得代码更加流畅。 - **CSS选择器**:使用CSS选择器进行元素的选择。 - **动画库**:内置了...
- **伪类和伪元素**:使用`:hover`、`:first-child`等伪类和`::before`、`::after`等伪元素增强网页效果。 - **CSS3特性**:了解CSS3的新特性,如圆角、阴影、渐变等。 - **响应式设计**:深入理解响应式设计的概念...
5. **CSS选择符与继承**:选择符包括通配选择符`*`、类型选择符(如`p`)、属性选择符(如`[target]`)、包含选择符(如`div p`)、子对象选择符(如`ul > li`)、ID选择符(如`#id`)、类选择符(如`.class`)、...
- **CSS 兼容性**:如圆角、阴影等 CSS3 属性的支持程度。 - **JavaScript 兼容性**:如 ES6 特性的支持度。 - **解决方法**: - 使用前缀(如 `-webkit-`)。 - 调整 CSS 代码以适应不同浏览器的解析规则。 - ...