We design with web standards.
In: Javascript| Yaohaixiao's
4 6 2009DOME: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 < 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 < 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 < 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 > 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 > 0) { left += 33.6; if (left > 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 < 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 && loadingImg) { photoContainer.removeChild(shardow); photoContainer.removeChild(loadingImg); } }, 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' }); } } })(); 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' }); }
基本的思路就是这些了,不知道我说的够不够清晰。
In: Javascript| Yaohaixiao's
4 6 2009演示地址: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 JavaScript和Writing Efficient JavaScript。
In: CSS
25 5 2009Author: 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:

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:

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:

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; }

In: Resource
21 5 2009演示地址: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 © 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]
站 长:姚海啸
性 别:男
学 历:大专
职 业:WEB前端工程师
MSN:haixiao_yao@hotmail.com
电子邮件:haixiao_yao@yahoo.com.cn
奋斗目标:成为一位国际级的前端工程师,呵呵!!