演示地址:http://www.yaohaixiao.com/effects/samples/ytabs/
下载地址:http://www.yaohaixiao.com/effects/source/ytabs.rar

好久没有更新自己的BLOG了,之前有一个星期是ISP的服务器挂了,好了也也不恢复我的空间,非要我去问,结果扯理由说是我的站点没有备案,晕,当我不知道,我访问他们的站点页面就显示“服务器再更新维护中!!”,“维护”用得了一个星期吗?哎,不提了,看看我整的这段代码吧:

[code]
var YTabs = function(){
var D = document;

return {
stopEvent: function(evt){
this.stopPropagation(evt);
this.preventDefault(evt);
},
stopPropagation: function(evt){
if (evt.stopPropagation) {
evt.stopPropagation();
}
else {
evt.cancelBubble = true;
}
},
preventDefault: function(evt){
if (evt.preventDefault) {
evt.preventDefault();
}
else {
evt.returnValue = false;
}
},
hasClass: function(elem, className){
var has = new RegExp(”(?:^|\\s+)” + className + “(?:\\s+|$)”);
return has.test(elem.className);
},
addClass: function(elem, className){
if (this.hasClass(elem, className)) {
return;
}
elem.className = [elem.className, className].join(” “);
},
removeClass: function(elem, className){
var replace = new RegExp(”(?:^|\\s+)” + className + “(?:\\s+|$)”, “g”);
if (!this.hasClass(elem, className)) {
return;
}
var o = elem.className;
elem.className = o.replace(replace, ” “);
if (this.hasClass(elem, className)) {
this.removeClass(elem, className);
}
},
getByClassName: function(className, tag, rootTag){
var elems = [], i, tempCnt = D.getElementById(rootTag).getElementsByTagName(tag), len = tempCnt.length;
for (i = 0; i < len; i++) {
if (YTabs.hasClass(tempCnt[i], className)) {
elems.push(tempCnt[i]);
}
}
if (elems.length < 1) {
return false;
}
else {
return elems;
}
},
tabs: function(){
var j, len = arguments.length;
for (j = 0; j < len; j += 1) {
(function(config){
var tabCnt = (config.tabId) ? D.getElementById(config.tabId) : (config.tabRoot || null), tabs = (config.tTag) ? tabCnt.getElementsByTagName(config.tTag) : (config.tabs || null), contents = (config.cTag) ? tabCnt.getElementsByTagName(config.cTag) : (config.contents || null), defaultClass = config.defaultClass || ‘current’, defaultIndex = config.defaultIndex || 0, lastIndex = defaultIndex, previousClass = config.previousClass || ”, previousClassTab = null, hideAll = config.hideAll || false, evtName = config.evt || ‘mouseover’, i, length = tabs.length, lastTab = tabs[defaultIndex], lastTabClass = config.lastTabClass || ”, lastContent = contents[defaultIndex];
if (tabs && contents) {
if (!hideAll) {
YTabs.addClass(lastTab, defaultClass);
lastContent.style.display = ‘block’;
}
else {
YTabs.removeClass(lastTab, defaultClass);
lastContent.style.display = ‘none’;
}
for (i = 0; i < length; i += 1) {
if (i !== defaultIndex) {
YTabs.removeClass(tabs[i], ‘current’);
contents[i].style.display = ‘none’;
}
tabs[i]['on' + evtName] = function(index){
return function(event){
var currentContent = contents[index];
YTabs.removeClass(lastTab, (YTabs.hasClass(lastTab, defaultClass) ? defaultClass : ‘current’));
if (this === tabs[defaultIndex]) {
YTabs.addClass(this, defaultClass);
}
else {
YTabs.addClass(this, ‘current’);
}
if (previousClass) {
if (previousClassTab) {
YTabs.removeClass(previousClassTab, previousClass);
}
if (index !== 0) {
YTabs.addClass(tabs[index - 1], previousClass);
if ((index - 1) === defaultIndex) {
YTabs.removeClass(tabs[index - 1], defaultClass);
}
previousClassTab = (tabs[index - 1]);
}
}
lastContent.style.display = “none”;
currentContent.style.display = “block”;
lastContent = currentContent;
lastTab = this;
lastIndex = index;
if (evtName === ‘click’) {
var evt = event || window.event;
YTabs.stopEvent(evt);
}
}
}(i);
if (hideAll && evtName === ‘mouseover’) {
tabs[i]['onmouseout'] = function(index){
return function(){
if (lastTab === this) {
YTabs.removeClass(this, (YTabs.hasClass(this, defaultClass) ? defaultClass : ‘current’));
}
if (previousClassTab) {
YTabs.removeClass(previousClassTab, previousClass);
}
contents[index].style.display = ‘none’;
}
}(i);
}
}
}
})(arguments[j]);
}
},
moveElement: function(element, final_x, final_y, speed){
if (!D.getElementById) {
return false;
}
var elem = (typeof element === ’string’) ? D.getElementById(element) : element;
var style = elem.style;
if (timer) {
clearTimeout(timer);
}
if (!style.left) {
style.left = ‘0′;
}
if (!style.top) {
style.top = ‘0′;
}
var xpos = parseInt(style.left, 10);
var ypos = parseInt(style.top, 10);
if (xpos == final_x && ypos == final_y) {
return true;
}
if (xpos < final_x) {
var dist = Math.ceil((final_x - xpos) / 10);
xpos = xpos + dist;
}
if (xpos > final_x) {
var dist = Math.ceil((xpos - final_x) / 10);
xpos = xpos - dist;
}
if (ypos < final_y) {
var dist = Math.ceil((final_y - ypos) / 10);
ypos = ypos + dist;
}
if (ypos > final_y) {
var dist = Math.ceil((ypos - final_y) / 10);
ypos = ypos - dist;
}
style.left = xpos + ‘px’;
style.top = ypos + ‘px’;
var timer = setTimeout(function(){
YTabs.moveElement(element, final_x, final_y, speed);
}, speed);
}
};
}();

[/code]

简单功能:
1、可以自定义事件–evt : ‘click’ || ‘mouseover’
2、可以自定义默认显示标签–defaultIndex: 0~n(当然N不能超过标签的最大索引值)
3、还是跟我的划过变色一样,一次可以控制多个对象,当然你也可以一次一个,多次调用
4、可以根据标签导航的id值(tabId),设置标签容器,然后通过导航标签的XHTML标签(tTag)通过 tabId.getElementsByTagName(tTag)获取所有标签,同时也可以直接通过函数获取所有的导航标签(tabs)和要显示的内容 (contents)。这样基本可以适应多变的布局样式。
5、另外的一个处理,就是不需要像有些朋友的代码,每次通过遍历标签项(tabs)和内容项(contents)来设置当前标签和当前内容的样式。因为你 需要设置样式只有4个(1个当前标签(currentTab),1个上次点击标签(lastTab),1个当前内容(currentContent),1 个上次显示内容(lastContent))节点样式。
6、如果采用点击事件,那么我就阻止了li或这其他tab标签里链接的事件触发。而当脚本不能运行或禁用时,用户有可以点击这些链接到相应的页面,算是个向后兼容。

到今天为止一共展示出了10个标签导航的示例,应该常用的一些滑动门导航效果这里都有了。我选的这些效果都比较有代表性,实用性也强,都是我从YAHOO、MSN、淘宝、京东等这样的大站点收集整理出来的,希望对加大的开发有帮助。有空我还会更新更多的我看到的或想到的其他表现形式的实用的滑动门。呵呵,看完这些例子,可能有人会发现:“哦,原来这个效果只是一个滑动门啊!”,呵呵,其实就是这样的。只不过我们的WEB工程师们添加了动画效果,使用了更炫的表现形式。而这些东西的本质都是一样的,滑动门。至少我是这么理解的。

我想经常来这了的朋友以前肯定看到过类似的帖子,我这个帖子算是做个补充,给出了更加完整的和丰富的示例。呵呵,重点也在这里,这里的示例是可以直接运用到实际开发中的,大家应该仔细看看这些示例的XHTML代码结构和CSS的布局技巧。特别是对刚接触前端开发的朋友。

我概要的介绍些这里用到的主要两个技巧:

1、浮动元素的特性:
A、浮动非替换元素要指定一个明确的宽度;否则,它们会尽可能地窄。
B、按照CSS规范,浮动元素(floats)会被移出文档流,不会影响到块状盒子的布局而只会影响内联盒子(通常是文本)的排列。
技巧:使用overflow:hidden使浮动元素的父节点获得高度
C、假如在一行之上只有极少的空间可供浮动元素,那么这个元素会跳至下一行,这个过程会持续到某一行拥有足够的空间为止。
(不过我的实际经验告诉我,Chorme目前会一直接在一排浮动,不会换行。一个BUG!!)
技巧:所以为了兼容,在你需要清除浮动,希望换行的地方给改节点设置clear:both;
D、浮动元素会生成一个块级框,而不论它本身是何种元素。
技巧:如果你视图直接给a或span这样的行内元素设置line-height,height是不起任何作用的,但是如果给他们加上float:left/right;那么这个设置就生效了。

还有:设置了margin-left/right的浮动元素,一定要记得使用display:inline;避免IE6中出现双倍的边距

2、position属性和设置了relative和absolute值的元素特性:

relative:元素框偏移某个距离。元素仍保持其未定位前的形状,它原本所占的空间仍保留
absolute:元素框从文档流完全删除,并相对于其包含块定位。包含块可能是文档中的另一个元素或者是初始包含块。元素原先在正常文档流中所占的空间会关闭,就好像元素原来不存在一样。元素定位后生成一个块级框,而不论原来它在正常流中生成何种类型的框

顺便说下:这里的一个“占空间”和一个“完全删除”就好像visibility:hidden;和display:none;

我的最后一个示例就是充分运用float的“会被移出文档流”,absolute的“从文档流完全删除”特性达到这个布局效果的。但是不幸的是在IE6中,即使absolute的display:none,但是float的威力依然存在,还会让它之后的float元素接在它后面浮动。所以我给每个h4设置了clear:right;把它左边的display:none的含有float的absolute元素的浮动清除掉,这样它们才能显示成一行。

好了,就这么大概的介绍下,其余的大家仔细去看吧,不要只看“热闹”,要看看里面的“门道”。

哎,说道JS的封装,大家要看的,就是如何使用闭包的特性,来模拟私有变量,私有方法和公用方法,特权方法(当然我的例子里有些没有涉及到),如何运用JS的灵活的语法特点.要彻底搞清楚JS中作用域的含义,什么能够在JS中构成作用域。唉,总之虽然我的JS封装得不怎么的,看时还是有不少门道的。当然,个人能力也十分有限,有什么不对和需要提高的,也请高手谅解这指点。

DOME:http://www.yaohaixiao.com/effects/carousel.html
实际运用:http://www.fg114.com/AESH10010161/1/photos.aspx

这个小效果很早就写了,刚好最近公司需要这样的效果,就直接用了。很实用的一个效果,今天也跟大家一起分享。

核心的代码:

Core.widget.Carousel = (function(){
    var Dom = Core.Dom;
    var Event = Core.Event;
    var Builder = Core.Builder;
 
    var samplesContainer = Dom.get('carousel_container');
    var samplesList = Dom.get('samples_list');
    var photoContainer = Dom.get('carousel_photo_container');
    var photo = Dom.get('carousel_photo');
    var photoIntro = Dom.get('carousel_photo_intro');
    var BtnLastPhoto = Dom.get('carousel_btn_lastpic');
    var BtnNextPhoto = Dom.get('carousel_btn_nextpic');
 
    var samplesItems = samplesList.getElementsByTagName('a');
    var i, len = samplesItems.length;
    var samplesItemWidth = 112;
    var oneScreenItemsNum = parseInt(samplesContainer.offsetWidth, 10) / samplesItemWidth;
    var lastIndex = 0;
    var curIndex = 0;
    var movedGroups = 0;
    var groups = len &lt; oneScreenItemsNum ? 0 : Math.ceil(len / oneScreenItemsNum) - 1;
    var samplesLeft = 0;
    var isVisited = [];
    var samplePhotos = [];
    var imgPath = [];
    var imgAlt = [];
 
    return {
        init: function(){
            var that = this, defaultPhoto = new Image();
            Dom.setStyle(samplesContainer, 'overflow', 'hidden');
            Dom.setStyle(samplesList, 'width', ((len * 112) + 'px'));
            for (i = 0; i &lt; len; i += 1) {
                isVisited[i] = false;
                samplePhotos[i] = samplesItems[i].getElementsByTagName('img')[0];
                imgPath[i] = samplesItems[i].getAttribute('href');
                imgAlt[i] = samplesItems[i].getElementsByTagName('img')[0].getAttribute('alt');
                Event.addListener(samplesItems[i], 'click', function(index){
                    return function(event){
                        var evt = event || window.event;
                        curIndex = index;
                        that.focusSample();
                        that.chgPhoto();
                        Event.stopEvent(evt);
                    }
                }(i));
            }
            defaultPhoto.src = photo.src;
            this.autoSize.call(defaultPhoto); // 给第一张图(如果超大)设置比例
            Event.addListener(BtnLastPhoto, 'click', this.lastPhotos);
            Event.addListener(BtnNextPhoto, 'click', this.nextPhotos);
        },
        lastPhotos: function(e){
            if (groups) {
                var evt = e || window.event;
                movedGroups -= 1;
                if (movedGroups &lt; 0) {
                    movedGroups = groups;
                    Core.widget.Carousel.move(oneScreenItemsNum * groups);
                }
                else {
                    Core.widget.Carousel.move(-oneScreenItemsNum);
                }
                Event.stopEvent(evt);
            }
        },
        nextPhotos: function(e){
            if (groups) {
                var evt = e || window.event;
                movedGroups += 1;
                if (movedGroups &gt; groups) {
                    movedGroups = 0;
                    Core.widget.Carousel.move(-oneScreenItemsNum * groups);
                }
                else {
                    Core.widget.Carousel.move(oneScreenItemsNum);
                }
                Event.stopEvent(evt);
            }
        },
        move: function(moveSteps){
            var left = 0;
            var sLeft = (samplesItemWidth * moveSteps);
            var timer = null;
            var scroll = function(){
                if (timer) {
                    clearTimeout(timer);
                }
                if (sLeft &gt; 0) {
                    left += 33.6;
                    if (left &gt; sLeft) {
                        if (Core.lang.isMoz) {
                            samplesLeft += sLeft;
                            samplesContainer.scrollLeft = samplesLeft;
                        }
                        else {
                            samplesLeft -= sLeft;
                            Dom.setStyle(samplesList, 'left', (samplesLeft + 'px'));
                        }
                        return false;
                    }
                    else {
                        if (Core.lang.isMoz) {
                            samplesContainer.scrollLeft = samplesLeft + left;
                        }
                        else {
                            Dom.setStyle(samplesList, 'left', (samplesLeft - left + 'px'));
                        }
                    }
                }
                else {
                    left -= 33.6;
                    if (left &lt; sLeft) {
                        if (Core.lang.isMoz) {
                            samplesLeft += sLeft;
                            samplesContainer.scrollLeft = samplesLeft;
                        }
                        else {
                            samplesLeft -= sLeft;
                            Dom.setStyle(samplesList, 'left', (samplesLeft + 'px'));
                        }
                        return false;
                    }
                    else {
                        if (Core.lang.isMoz) {
                            samplesContainer.scrollLeft = samplesLeft + left;
                        }
                        else {
                            Dom.setStyle(samplesList, 'left', (samplesLeft - left + 'px'));
                        }
                    }
                }
                timer = setTimeout(scroll, 5);
            };
            scroll();
        },
        focusSample: function(){
            Dom.setStyle(samplePhotos[lastIndex], 'opacity', 1);
            Dom.setStyle(samplePhotos[curIndex], 'opacity', .4);
            lastIndex = curIndex;
        },
        chgPhoto: function(){
            var that = this;
            var tempImage = new Image();
            var shardow = null;
            tempImage.src = imgPath[curIndex];
            if (!isVisited[curIndex]) {
                photoContainer.appendChild(Builder.Node('div', {
                    id: 'carousel_photo_shardow'
                }));
                shardow = Dom.get('carousel_photo_shardow');
                shardow.style.height = photoContainer.offsetHeight + 'px';
                photoContainer.appendChild(Builder.Node('img', {
                    id: 'carousel_photo_loading',
                    src: 'img/loading.gif',
                    alt: 'loading'
                }));
 
            }
            if (tempImage.complete) {// Mozllia
                that.loadPhoto.call(tempImage);
            }
            else {// IE
                Event.addListener(tempImage, 'load', function(){
                    that.loadPhoto.call(tempImage);
                });
            }
        },
        loadPhoto: function(){
            Core.widget.Carousel.autoSize.call(this);
            photo.src = imgPath[curIndex];
            photoIntro.innerHTML = imgAlt[curIndex];
            isVisited[curIndex] = true;
            shardow = Dom.get('carousel_photo_shardow');
            loadingImg = Dom.get('carousel_photo_loading');
            if (shardow &amp;&amp; loadingImg) {
                photoContainer.removeChild(shardow);
                photoContainer.removeChild(loadingImg);
            }
        },
        autoSize: function(){ // 分离出来了,专门控制图片比例
            var width = this.width;
            var height = this.height;
            imgPercent = width / height;
            if (width &gt; 800) {
                width = 800;
                height = (width / imgPercent);
            }
            Dom.setStyles(photo, {
                width: width + 'px',
                height: height + 'px'
            });
        }
    }
})();
Core.widget.Carousel.init();

这个主要程序比较麻烦点,可能也是有些朋友不清楚的,就是如果实现图片加载的时候出现loading效果。这个是用过创建一个Image对象,然后给这个对象付上图片路径,这样就可以根据Image对象的complete或者onload(一个是针对Mozilla一个是针对IE的)事件,处理页面加载完成后要处理的,这样我们就可以一步加载图片,其实主要是图片比较大,如果不全部加载完,我们就无法获得图片的高度和宽度,所有是有在complete后,才能知道图片有多大,然后判断,如果超大了,就要等比例缩小。而至于loading的效果,其实很简单,就是在这个加载过程中,给图片容器添加一个遮罩层和一个loading的gif图片:

// 如果图片没有加载过,就显示load
            // 如果已经加载过,浏览器会读缓存或者只是发送一个GET请求,服务器返回一个状态值,没有改变为304,只是传送一个值,所以加载图片会很快,就不需要再显示loading,因为图片已加载过,所以loading只是一闪而过,而不停点缩略图图片结果是一闪一闪的比较晃眼。
            if (!isVisited[curIndex]) {
                photoContainer.appendChild(Builder.Node('div', {
                    id: 'carousel_photo_shardow'
                }));
                shardow = Dom.get('carousel_photo_shardow');
                shardow.style.height = photoContainer.offsetHeight + 'px';
                photoContainer.appendChild(Builder.Node('img', {
                    id: 'carousel_photo_loading',
                    src: 'img/loading.gif',
                    alt: 'loading'
                }));
 
            }
            if (tempImage.complete) {// Mozllia
                that.loadPhoto.call(tempImage);
            }
            else {// IE
                Event.addListener(tempImage, 'load', function(){
                    that.loadPhoto.call(tempImage);
                });
            }

接着就是在加载完成后设置自动缩放和消除loading效果

loadPhoto: function(){
            Core.widget.Carousel.autoSize.call(this); //  图片自动缩放
            //  图片加载完毕,那么现在就要改变当前图片的图片路径了
            photo.src = imgPath[curIndex];
            photoIntro.innerHTML = imgAlt[curIndex];
            //  给加载过的图片做标记
            isVisited[curIndex] = true;
            shardow = Dom.get('carousel_photo_shardow');
            loadingImg = Dom.get('carousel_photo_loading');
            // 如果有loading,就去掉
            if (shardow && loadingImg) {
                photoContainer.removeChild(shardow);
                photoContainer.removeChild(loadingImg);
            }
 },

所以顺序就是在图片加载过程中,添加loading图片和遮罩层,加载完毕后,我们获得了图片的高和宽,根据这个值来决定是否按比例缩放,而同时需要改变当前图片(img标签)的路径,而清楚loading效果。计算比例的代码如下

// 这里的逻辑就不多介绍了,代码应该很明白了
 autoSize: function(){ // 分离出来了,专门控制图片比例
            var width = this.width;
            var height = this.height;
            imgPercent = width / height;
            if (width > 800) {
                width = 800;
                height = (width / imgPercent);
            }
            Dom.setStyles(photo, {
                width: width + 'px',
                height: height + 'px'
            });
 }

基本的思路就是这些了,不知道我说的够不够清晰。

演示地址:http://www.yaohaixiao.com/effects/zebra-table.html

< !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>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta http-equiv="Content-Language" content="utf-8" />
<meta name="robots" content="all" />
<title>Table隔行换色示例</title>
<style type="text/css">
<!--
*{margin:0;padding:0;}
body{text-align:center;background-color:#633801;color:#000;font:normal 12px Arial, Helvetica, sans-serif;}
div,span,p,li,dt,dd,h1,h2,h3,h4,h5,h6{text-align:left;}
img{border:0;}
ul,li{list-style-type:none;}
 
#main_table{margin:0 auto;width:500px;overflow:hidden;border:0;background-color:#FFF;}	
#main_table caption{border:solid #FFF;border-width:1px 1px 0;margin-top:20px;height:36px;line-height:36px;text-align:center;font-weight:bold;font-size:14px;overflow:hidden;background-color:#BF6B00;}
#main_table td{height:28px;line-height:28px;text-align:center;width:125px;}	
#main_table caption,#main_table td{font-family:Arial,sans-serif;}
#main_table thead tr{background-color:#5B3300;}
#main_table thead td{font-weight:bold;}
 
.odd{background-color:#986A2E;}
.even{background-color:#885A1F;}
#main_table caption,#main_table thead td,.odd,.even,.hover{color:#FFF;}
.hover{background-color:#BF6B00;cursor:pointer;}
-->
</style>
</head>
<body>
<table id="main_table" cellspacing="1">
<caption>Table隔行换色示例</caption>
<thead>
<tr>
<td>ID</td>
<td>Time</td>
<td>Award</td>
<td>Amount</td>
</tr>
</thead>	
<tbody id="tInfo">
<tr>
 <td>1</td>
 <td>2008.11.16</td>
 <td>¥50</td>
 <td>10</td>
</tr>
<tr>
 <td>2</td>
 <td>2008.11.16</td>
 <td>¥50</td>
 <td>10</td>
</tr>
<tr>
 <td>3</td>
 <td>2008.11.16</td>
 <td>¥50</td>
 <td>10</td>
</tr>
<tr>
 <td>4</td>
 <td>2008.11.16</td>
 <td>¥50</td>
 <td>10</td>
</tr>
<tr>
 <td>5</td>
 <td>2008.11.16</td>
 <td>¥50</td>
 <td>10</td>
</tr>
<tr>
 <td>6</td>
 <td>2008.11.16</td>
 <td>¥50</td>
 <td>10</td>
</tr>
<tr>
 <td>7</td>
 <td>2008.11.16</td>
 <td>¥50</td>
 <td>10</td>
</tr>
<tr>
 <td>8</td>
 <td>2008.11.16</td>
 <td>¥50</td>
 <td>10</td>
</tr>
<tr>
 <td>9</td>
 <td>2008.11.16</td>
 <td>¥50</td>
 <td>10</td>
</tr>
<tr>
 <td>10</td>
 <td>2008.11.16</td>
 <td>¥50</td>
 <td>10</td>
</tr>
</tbody>
</table>
<script type="text/javascript">
(function(){
	var sTable = document.getElementById('tInfo');
	var rows = sTable.getElementsByTagName('tr'), i, len = rows.length;
	var lastClass = '';
	if (sTable && len > 1) {
		for (var i = 0; i < len; i++) {
			rows[i].className = i % 2 == 0 ? 'even' : 'odd';
			rows[i].onmouseover = function(){
				lastClass = this.className;
				this.className = 'hover';
			};
			rows[i].onmouseout = function(){
				this.className = lastClass;
			};
		}
	}
})();
</script>
</script></body>
</html>

一个很简单的效果,没有什么特别的,我这里简单的想说的就是,以往大家把CSS和JS分离,这个也是现在大家共同的认识。我看到很多朋友喜欢直接用JS来设置CSS样式,这么做如果只是简单的修改一个样式,那么没有太大问题,但是如果你需要改一组样式,这么做就很不好了。

首先,这么做是不方便维护的。如果这个样式需要经常改动,在一大堆JS里找到这些要改的CSS属性就不那么惬意。而且很可能因为你的属性的书写错误而引起脚本错误,那就会更让你头大。其次,这么做JS的执行效率不高。因为你每修改一次样式,浏览器就会重绘页面,这个就会降低你脚本的执行效率,而具体的分析,大家可以看《Reflows & Repaints: CSS Performance making your JavaScript slow?》。其他就不多说了,这里也推荐大家看看《Javascript风格要素》和《JavaScript程序编码规范》,还有就是YUI的Maintainable JavaScriptWriting Efficient JavaScript

Clearing floats

In: CSS

25 5 2009

Author: PPK
From:http://www.quirksmode.org/

A common problem with float-based layouts is that the floats’ container doesn’t want to stretch up to accomodate the floats. If you want to add, say, a border around all floats (ie. a border around the container) you’ll have to command the browsers somehow to stretch up the container all the way.
The problem

Let’s try it. This is the CSS we’ll use throughout the page:

div.container {
	border: 1px solid #000000;
}
 
div.left {
	width: 45%;
	float: left;
}
 
div.right {
	width: 45%;
	float: right;
}

Now this happens:

clear-flaot-1

We want the black border to go around both our floating columns. That doesn’t happen, though. The container div itself has no height, since it only contains floating elements. Therefore the border stubbornly stays at the top of the floating columns.
The old solution

The old solution to this problem required you to add an extra element with clear: both to the container. Once it was in place the container contained a non-floating element, which means it stretches itself up to accomodate it:

clear-flaot-2

This can be done either by adding the extra element in the HTML source code (as the example above does) or by using the :after pseudo-class to generate it. Since Explorer (Win and Mac) doesn’t support :after this second solution was mainly of theoretical interest.

In any case, adding an HTML element for presentation’s sake is something we’ve learned to avoid. Unfortunately the problem could not be solved in any other way, until now.

The new solution

It was Alex Walker who first posted a new, simpler solution, though he gives the credits for actually inventing it to Paul O’Brien. In any case, the solution seems to be:

div.container {
	border: 1px solid #000000;
	<strong>overflow: auto;
	width: 100%</strong>
}

The width is necessary to trigger “hasLayout” in Explorer Windows (except for 7). This works:

clear-flaot-3

Now the border neatly fits around the floated elements.

The tricky bits

A few points merit extra attention:

1. The trick works with three of the four overflow values: auto, hidden and scroll. Of course, using the last value will show scrollbars, regardless of whether they’re needed or not.
2. Some browsers also need a width or height for the container div.
3. The browser may show scrollbars when the content escapes beyond the specified width.

width or height required

The use of a width or height declaration is required to make the effect work in Explorer Windows and Opera. If you don’t include it Explorer Windows continues to show the border at the top of the columns, as if there were no overflow. Opera completely hides the content of the container.

A width: 100% is a neat starting point, although more complicated layouts may require other values.

Explorer Mac: hidden

If Explorer Mac is still important to you, use overflow: hidden. This browser always shows scrollbars when you use overflow: auto; and I’m not sure why.

Unwanted scrollbars

As Dave Shea noted, this solution might cause unwanted scrollbars if the content escapes from the container box. Personally I wonder if this will be a serious problem. overflow: hidden makes sure that no scrollbars will ever be visible. Of course some content might be hidden instead, but if we make very sure that

1. the height of the container remains flexible (ie. “as much as needed”)
2. the widths of the combined floats never exceed the width of the container, and preferably remain slightly smaller to allow for some flexibility

this problem will never creep up.

On the other hand, never say never. In pure tests like the ones above the effect works fine. In real-world sites, where there’s plenty more CSS to confuse browsers, something will eventually go wrong somewhere. Until we reach that point, though, this technique will do nicely.

The complete effect

For completeness’ sake, here’s the code you need:

div.container {
	border: 1px solid #000000;
	overflow: hidden;
	width: 100%;
}
 
div.left {
	width: 45%;
	float: left;
}
 
div.right {
	width: 45%;
	float: right;
}

clear-flaot-4

演示地址:http://www.yaohaixiao.com/effects/flvplayer.html

下载地址:http://www.yaohaixiao.com/effects/source/google-map.rar

我觉得这个免费的软件已经很强大了,好像之后更新的版本的很多功能都没有用,只有好像作者就是专门在做广告插件了,而且还要通过他的服务器来运行,我觉得还是这个早期的独立版本比较实用。

[code]
<!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>
<meta http-equiv=”Content-Type” content=”text/html; charset=utf-8″ />
<title>JW Flv Player 3.16 -  Yaohaixiao’s Blog</title>
<link href=’css/layout.css’ type=”text/css” rel=”stylesheet” media=”all” />
<link href=’css/flvplayer.css’ id=”flvplayerCSS” type=”text/css” rel=”stylesheet” media=”screen” />
<link href=’css/message.css’ id=”messageCSS” type=”text/css” rel=”stylesheet” media=”screen” />
<style type=”text/css”>
div#player{
margin:50px auto;
width:680px;
height:400px;
padding:2px;
border:4px solid #999;
overflow:hidden;
background-color:#FFF;
}
</style>
</head>
<body>
<h1>JW Flv Player 3.16</h1>
<div id=”player”></div>
<div id=”footer”>

<p>Copyright &copy; 2008-2009 <a href=”http://www.yaohaixiao.com/”>yaohaixiao.com</a>, All right reserved.</p>
</div>
<script language=”javascript” type=”text/javascript” src=”js/swfobject.js”></script>
<script language=”javascript” type=”text/javascript”>
<!–
function fullFunctionPlayer(){
var player = new SWFObject(”swf/mediaplayer.swf”, “fullmediaplayer”, “680″, “400″, “8″);
player.addParam(”allowfullscreen”, “true”);
player.addParam(”allowscriptaccess”, “always”);
player.addParam(”seamlesstabbing”, “true”);
player.addVariable(”width”, “680″);
player.addVariable(”height”, “400″);
player.addVariable(’screencolor’, ‘0×000000′);
player.addVariable(’backcolor’, ‘0xCCCC66′);
player.addVariable(’frontcolor ‘, ‘0xFFFFFF’);
player.addVariable(’lightcolor’, ‘0×000000′);
player.addVariable(”file”, “swf/fullplaylist.xml”);
player.addVariable(”linkfromdisplay”, “true”);
player.addVariable(”showstop”, “true”);
player.addVariable(”showdownload”, “true”);
player.addVariable(”thumbsinplaylist”, “true”);
player.addVariable(”searchbar”, “false”);
player.addVariable(”autostart”, “false”);
player.addVariable(”autoscroll”, “true”);
player.addVariable(”displaywidth”, 480);
player.addVariable(”displayheight”, 400);
player.write(”player”);
}
fullFunctionPlayer();
//–>
</script>
<script language=”javascript” type=”text/javascript”>
<!–
var gaJsHost = ((”https:” == document.location.protocol) ? “https://ssl.” : “http://www.”);
document.write(unescape(”%3Cscript src=’” + gaJsHost + “google-analytics.com/ga.js’ type=’text/javascript’%3E%3C/script%3E”));
//–>
</script>
<script language=”javascript” type=”text/javascript”>
<!–
var pageTracker = _gat._getTracker(”UA-4473199-1″);
pageTracker._initData();
pageTracker._trackPageview();
//–>
</script>
</body>
</html>
[/code]



About Yaohaixiao

站 长:姚海啸
性 别:男
学 历:大专
职 业:WEB前端工程师
MSN:haixiao_yao@hotmail.com
电子邮件:haixiao_yao@yahoo.com.cn
奋斗目标:成为一位国际级的前端工程师,呵呵!!

My Work

订餐小秘书 订餐小秘书餐厅相册 订餐小秘书餐厅地图 爱唱久久 四川计算机软件重点实验室 荆楚网新闻频道首页

Categories

Archives

 

7月 2009
« 6    
 12345
6789101112
13141516171819
20212223242526
2728293031