以下是 js鼠标悬停弹性滑动导航菜单特效代码 的示例演示效果:
部分效果截图:
HTML代码(index.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" />
<title>js鼠标悬停弹性滑动导航菜单</title>
<!--[if lte IE 6]><script src="js/DD_belatedPNG_0.0.8a.js" type="text/javascript"></script><script type="text/javascript">DD_belatedPNG.fix('li');</script><![endif]-->
<style type="text/css">
* { padding: 0; margin: 0; }
li { list-style: none; }
body { background: #333; }
#box { width: 600px; height: 518px; background: url(images/box.jpg) no-repeat; position: absolute; top: 50%; left: 50%; margin: -259px 0 0 -300px; }
#box a { text-decoration: none; }
#box h2 { font-weight: normal; padding-left: 25px; line-height: 60px; color: #ccc; }
#box h2 a { font-size: 14px; color: #999; }
#box h2 a:hover { color: #ebebeb; text-decoration: underline; position: relative; top: 1px; }
#box ul { width: 490px; height: 65px; position: absolute; top: 50%; left: 50%; margin: -30px 0 0 -245px; }
#box li { width: 163px; height: 65px; float: left; background: url(images/btn.png) no-repeat; position: relative; }
#box img { position: absolute; left: 50%; bottom: 8px; z-index: 3; width: 0; margin-left: 0; }
#box li a { width: 152px; height: 44px; padding-top: 8px; text-align: center; font-size: 14px; font-weight: bold; font-family: arial; color: #fff; line-height: 18px; position: absolute; top: 4px; left: 4px; z-index: 2; }
#box li a span { color: #999; font-weight: normal; font-size: 12px; }
#box .bg { width: 152px; height: 0px; background: #03080e; position: absolute; left: 4px; top: 56px; z-index: 1; overflow:hidden; }
#box h1 { position: absolute; bottom: 0; left: 0; }
#box h1 a { display: block; width: 280px; height: 57px; background: url(images/footer.gif) no-repeat; }
#box h1 a:hover { background: url(images/footer.gif) no-repeat 0 -57px; }
#box h1 span { display: none; }
</style>
<script type="text/javascript" src="move.js"></script>
</head>
<body>
<div id="box">
<h2>
<a href="#">弹性滑动导航效果</a>
</h2>
<ul>
<li>
<img src="images/1.jpg" alt="javascript高级前端开发课程"/>
<a href="#">JavaScript<br /><span>高级前端开发课程</span></a>
<span class="bg"></span>
</li>
<li>
<img src="images/2.jpg" alt="XHTML+CSS高级页面架构师课程" />
<a href="#">XHTML+CSS<br /><span>高级页面架构师课程</span></a>
<span class="bg"></span>
</li>
<li>
<img src="images/3.jpg" alt="CSS网页制作零基础网页制作课程" />
<a href="#">CSS网页制作<br /><span>零基础网页制作课程</span></a>
<span class="bg"></span>
</li>
</ul>
<h1><a href="#"><span>弹性滑动导航效果</span></a></h1>
</div>
</body>
</html>
JS代码(DD_belatedPNG_0.0.8a.js):
/*** DD_belatedPNG:Adds IE6 support:PNG images for CSS background-image and HTML <IMG/>.* Author:Drew Diller* Email:drew.diller@gmail.com* URL:http://www.dillerdesign.com/experiment/DD_belatedPNG/* Version:0.0.8a* Licensed under the MIT License:http://dillerdesign.com/experiment/DD_belatedPNG/#license** Example usage:* DD_belatedPNG.fix('.png_bg');
// argument is a CSS selector* DD_belatedPNG.fixPng( someNode );
// argument is an HTMLDomElement**/
/*PLEASE READ:Absolutely everything in this script is SILLY. I know this. IE's rendering of certain pixels doesn't make sense,so neither does this code!*/
var DD_belatedPNG ={
ns:'DD_belatedPNG',imgSize:{
}
,delay:10,nodesFixed:0,createVmlNameSpace:function (){
/* enable VML */
if (document.namespaces && !document.namespaces[this.ns]){
document.namespaces.add(this.ns,'urn:schemas-microsoft-com:vml');
}
}
,createVmlStyleSheet:function (){
/* style VML,enable behaviors */
/*Just in case lots of other developers have addedlots of other stylesheets using document.createStyleSheetand hit the 31-limit mark,let's not use that method!further reading:http://msdn.microsoft.com/en-us/library/ms531194(VS.85).aspx*/
var screenStyleSheet,printStyleSheet;
screenStyleSheet = document.createElement('style');
screenStyleSheet.setAttribute('media','screen');
document.documentElement.firstChild.insertBefore(screenStyleSheet,document.documentElement.firstChild.firstChild);
if (screenStyleSheet.styleSheet){
screenStyleSheet = screenStyleSheet.styleSheet;
screenStyleSheet.addRule(this.ns + '\\:*','{
behavior:url(#default#VML)}
');
screenStyleSheet.addRule(this.ns + '\\:shape','position:absolute;
');
screenStyleSheet.addRule('img.' + this.ns + '_sizeFinder','behavior:none;
border:none;
position:absolute;
z-index:-1;
top:-10000px;
visibility:hidden;
');
/* large negative top value for avoiding vertical scrollbars for large images,suggested by James O'Brien,http://www.thanatopsic.org/hendrik/ */
this.screenStyleSheet = screenStyleSheet;
/* Add a print-media stylesheet,for preventing VML artifacts from showing up in print (including preview). */
/* Thanks to R�mi Pr�vost for automating this! */
printStyleSheet = document.createElement('style');
printStyleSheet.setAttribute('media','print');
document.documentElement.firstChild.insertBefore(printStyleSheet,document.documentElement.firstChild.firstChild);
printStyleSheet = printStyleSheet.styleSheet;
printStyleSheet.addRule(this.ns + '\\:*','{
display:none !important;
}
');
printStyleSheet.addRule('img.' + this.ns + '_sizeFinder','{
display:none !important;
}
');
}
}
,readPropertyChange:function (){
var el,display,v;
el = event.srcElement;
if (!el.vmlInitiated){
return;
}
if (event.propertyName.search('background') != -1 || event.propertyName.search('border') != -1){
DD_belatedPNG.applyVML(el);
}
if (event.propertyName == 'style.display'){
display = (el.currentStyle.display == 'none') ? 'none':'block';
for (v in el.vml){
if (el.vml.hasOwnProperty(v)){
el.vml[v].shape.style.display = display;
}
}
}
if (event.propertyName.search('filter') != -1){
DD_belatedPNG.vmlOpacity(el);
}
}
,vmlOpacity:function (el){
if (el.currentStyle.filter.search('lpha') != -1){
var trans = el.currentStyle.filter;
trans = parseInt(trans.substring(trans.lastIndexOf('=')+1,trans.lastIndexOf(')')),10)/100;
el.vml.color.shape.style.filter = el.currentStyle.filter;
/* complete guesswork */
el.vml.image.fill.opacity = trans;
/* complete guesswork */
}
}
,handlePseudoHover:function (el){
setTimeout(function (){
/* wouldn't work as intended without setTimeout */
DD_belatedPNG.applyVML(el);
}
,1);
}
,/*** This is the method to use in a document.* @param{
String}
selector - REQUIRED - a CSS selector,such as '#doc .container'**/
fix:function (selector){
if (this.screenStyleSheet){
var selectors,i;
selectors = selector.split(',');
/* multiple selectors supported,no need for multiple calls to this anymore */
for (i=0;
i<selectors.length;
i++){
this.screenStyleSheet.addRule(selectors[i],'behavior:expression(DD_belatedPNG.fixPng(this))');
/* seems to execute the function without adding it to the stylesheet - interesting... */
}
}
}
,applyVML:function (el){
el.runtimeStyle.cssText = '';
this.vmlFill(el);
this.vmlOffsets(el);
this.vmlOpacity(el);
if (el.isImg){
this.copyImageBorders(el);
}
}
,attachHandlers:function (el){
var self,handlers,handler,moreForAs,a,h;
self = this;
handlers ={
resize:'vmlOffsets',move:'vmlOffsets'}
;
if (el.nodeName == 'A'){
moreForAs ={
mouseleave:'handlePseudoHover',mouseenter:'handlePseudoHover',focus:'handlePseudoHover',blur:'handlePseudoHover'}
;
for (a in moreForAs){
if (moreForAs.hasOwnProperty(a)){
handlers[a] = moreForAs[a];
}
}
}
for (h in handlers){
if (handlers.hasOwnProperty(h)){
handler = function (){
self[handlers[h]](el);
}
;
el.attachEvent('on' + h,handler);
}
}
el.attachEvent('onpropertychange',this.readPropertyChange);
}
,giveLayout:function (el){
el.style.zoom = 1;
if (el.currentStyle.position == 'static'){
el.style.position = 'relative';
}
}
,copyImageBorders:function (el){
var styles,s;
styles ={
'borderStyle':true,'borderWidth':true,'borderColor':true}
;
for (s in styles){
if (styles.hasOwnProperty(s)){
el.vml.color.shape.style[s] = el.currentStyle[s];
}
}
}
,vmlFill:function (el){
if (!el.currentStyle){
return;
}
else{
var elStyle,noImg,lib,v,img,imgLoaded;
elStyle = el.currentStyle;
}
for (v in el.vml){
if (el.vml.hasOwnProperty(v)){
el.vml[v].shape.style.zIndex = elStyle.zIndex;
}
}
el.runtimeStyle.backgroundColor = '';
el.runtimeStyle.backgroundImage = '';
noImg = true;
if (elStyle.backgroundImage != 'none' || el.isImg){
if (!el.isImg){
el.vmlBg = elStyle.backgroundImage;
el.vmlBg = el.vmlBg.substr(5,el.vmlBg.lastIndexOf('")')-5);
}
else{
el.vmlBg = el.src;
}
lib = this;
if (!lib.imgSize[el.vmlBg]){
/* determine size of loaded image */
img = document.createElement('img');
lib.imgSize[el.vmlBg] = img;
img.className = lib.ns + '_sizeFinder';
img.runtimeStyle.cssText = 'behavior:none;
position:absolute;
left:-10000px;
top:-10000px;
border:none;
margin:0;
padding:0;
';
/* make sure to set behavior to none to prevent accidental matching of the helper elements! */
imgLoaded = function (){
this.width = this.offsetWidth;
/* weird cache-busting requirement! */
this.height = this.offsetHeight;
lib.vmlOffsets(el);
}
;
img.attachEvent('onload',imgLoaded);
img.src = el.vmlBg;
img.removeAttribute('width');
img.removeAttribute('height');
document.body.insertBefore(img,document.body.firstChild);
}
el.vml.image.fill.src = el.vmlBg;
noImg = false;
}
el.vml.image.fill.on = !noImg;
el.vml.image.fill.color = 'none';
el.vml.color.shape.style.backgroundColor = elStyle.backgroundColor;
el.runtimeStyle.backgroundImage = 'none';
el.runtimeStyle.backgroundColor = 'transparent';
}
,/* IE can't figure out what do when the offsetLeft and the clientLeft add up to 1,and the VML ends up getting fuzzy... so we have to push/enlarge things by 1 pixel and then clip off the excess */
vmlOffsets:function (el){
var thisStyle,size,fudge,makeVisible,bg,bgR,dC,altC,b,c,v;
thisStyle = el.currentStyle;
size ={
'W':el.clientWidth+1,'H':el.clientHeight+1,'w':this.imgSize[el.vmlBg].width,'h':this.imgSize[el.vmlBg].height,'L':el.offsetLeft,'T':el.offsetTop,'bLW':el.clientLeft,'bTW':el.clientTop}
;
fudge = (size.L + size.bLW == 1) ? 1:0;
/* vml shape,left,top,width,height,origin */
makeVisible = function (vml,l,t,w,h,o){
vml.coordsize = w+','+h;
vml.coordorigin = o+','+o;
vml.path = 'm0,0l'+w+',0l'+w+','+h+'l0,'+h+' xe';
vml.style.width = w + 'px';
vml.style.height = h + 'px';
vml.style.left = l + 'px';
vml.style.top = t + 'px';
}
;
makeVisible(el.vml.color.shape,(size.L + (el.isImg ? 0:size.bLW)),(size.T + (el.isImg ? 0:size.bTW)),(size.W-1),(size.H-1),0);
makeVisible(el.vml.image.shape,(size.L + size.bLW),(size.T + size.bTW),(size.W),(size.H),1 );
bg ={
'X':0,'Y':0}
;
if (el.isImg){
bg.X = parseInt(thisStyle.paddingLeft,10) + 1;
bg.Y = parseInt(thisStyle.paddingTop,10) + 1;
}
else{
for (b in bg){
if (bg.hasOwnProperty(b)){
this.figurePercentage(bg,size,b,thisStyle['backgroundPosition'+b]);
}
}
}
el.vml.image.fill.position = (bg.X/size.W) + ',' + (bg.Y/size.H);
bgR = thisStyle.backgroundRepeat;
dC ={
'T':1,'R':size.W+fudge,'B':size.H,'L':1+fudge}
;
/* these are defaults for repeat of any kind */
altC ={
'X':{
'b1':'L','b2':'R','d':'W'}
,'Y':{
'b1':'T','b2':'B','d':'H'}
}
;
if (bgR != 'repeat' || el.isImg){
c ={
'T':(bg.Y),'R':(bg.X+size.w),'B':(bg.Y+size.h),'L':(bg.X)}
;
/* these are defaults for no-repeat - clips down to the image location */
if (bgR.search('repeat-') != -1){
/* now let's revert to dC for repeat-x or repeat-y */
v = bgR.split('repeat-')[1].toUpperCase();
c[altC[v].b1] = 1;
c[altC[v].b2] = size[altC[v].d];
}
if (c.B > size.H){
c.B = size.H;
}
el.vml.image.shape.style.clip = 'rect('+c.T+'px '+(c.R+fudge)+'px '+c.B+'px '+(c.L+fudge)+'px)';
}
else{
el.vml.image.shape.style.clip = 'rect('+dC.T+'px '+dC.R+'px '+dC.B+'px '+dC.L+'px)';
}
}
,figurePercentage:function (bg,size,axis,position){
var horizontal,fraction;
fraction = true;
horizontal = (axis == 'X');
switch(position){
case 'left':case 'top':bg[axis] = 0;
break;
case 'center':bg[axis] = 0.5;
break;
case 'right':case 'bottom':bg[axis] = 1;
break;
default:if (position.search('%') != -1){
bg[axis] = parseInt(position,10) / 100;
}
else{
fraction = false;
}
}
bg[axis] = Math.ceil( fraction ? ( (size[horizontal?'W':'H'] * bg[axis]) - (size[horizontal?'w':'h'] * bg[axis]) ):parseInt(position,10) );
if (bg[axis] % 2 === 0){
bg[axis]++;
}
return bg[axis];
}
,fixPng:function (el){
el.style.behavior = 'none';
var lib,els,nodeStr,v,e;
if (el.nodeName == 'BODY' || el.nodeName == 'TD' || el.nodeName == 'TR'){
/* elements not supported yet */
return;
}
el.isImg = false;
if (el.nodeName == 'IMG'){
if(el.src.toLowerCase().search(/\.png$/) != -1){
el.isImg = true;
el.style.visibility = 'hidden';
}
else{
return;
}
}
else if (el.currentStyle.backgroundImage.toLowerCase().search('.png') == -1){
return;
}
lib = DD_belatedPNG;
el.vml ={
color:{
}
,image:{
}
}
;
els ={
shape:{
}
,fill:{
}
}
;
for (v in el.vml){
if (el.vml.hasOwnProperty(v)){
for (e in els){
if (els.hasOwnProperty(e)){
nodeStr = lib.ns + ':' + e;
el.vml[v][e] = document.createElement(nodeStr);
}
}
el.vml[v].shape.stroked = false;
el.vml[v].shape.appendChild(el.vml[v].fill);
el.parentNode.insertBefore(el.vml[v].shape,el);
}
}
el.vml.image.shape.fillcolor = 'none';
/* Don't show blank white shapeangle when waiting for image to load. */
el.vml.image.fill.type = 'tile';
/* Makes image show up. */
el.vml.color.fill.on = false;
/* Actually going to apply vml element's style.backgroundColor,so hide the whiteness. */
lib.attachHandlers(el);
lib.giveLayout(el);
lib.giveLayout(el.offsetParent);
el.vmlInitiated = true;
lib.applyVML(el);
/* Render! */
}
}
;
try{
document.execCommand("BackgroundImageCache",false,true);
/* TredoSoft Multiple IE doesn't like this,so try{
}
it */
}
catch(r){
}
DD_belatedPNG.createVmlNameSpace();
DD_belatedPNG.createVmlStyleSheet();
JS代码(move.js):
function css(obj,attr,value){
if(arguments.length==2)return parseFloat(obj.currentStyle?obj.currentStyle[attr]:document.defaultView.getComputedStyle(obj,false)[attr]);
else if(arguments.length==3)switch(attr){
case 'width':case 'height':case 'paddingLeft':case 'paddingTop':case 'paddingRight':case 'paddingBottom':value=Math.max(value,0);
case 'left':case 'top':case 'marginLeft':case 'marginTop':case 'marginRight':case 'marginBottom':obj.style[attr]=value+'px';
break;
case 'opacity':obj.style.filter="alpha(opacity:"+value*100+")";
obj.style.opacity=value;
break;
default:obj.style[attr]=value;
}
return function (attr_in,value_in){
css(obj,attr_in,value_in)}
;
}
var MIAOV_MOVE_TYPE={
BUFFER:1,FLEX:2}
;
function miaovStartMove2(obj,oTarget,iType,fnCallBack,fnDuring){
var fnMove=null;
if(obj.timer){
clearInterval(obj.timer);
}
switch(iType){
case MIAOV_MOVE_TYPE.BUFFER:fnMove=miaovDoMoveBuffer;
break;
case MIAOV_MOVE_TYPE.FLEX:fnMove=miaovDoMoveFlex;
break;
}
obj.timer=setInterval(function (){
fnMove(obj,oTarget,fnCallBack,fnDuring);
}
,30);
}
function miaovDoMoveBuffer(obj,oTarget,fnCallBack,fnDuring){
var bStop=true;
var attr='';
var speed=0;
var cur=0;
for(attr in oTarget){
cur=css(obj,attr);
if(Math.abs(oTarget[attr]-cur)>=1)//if(oTarget[attr]!=cur){
bStop=false;
speed=(oTarget[attr]-cur)/5;
speed=speed>0?Math.ceil(speed):Math.floor(speed);
css(obj,attr,cur+speed);
}
}
if(fnDuring)fnDuring.call(obj);
if(bStop){
clearInterval(obj.timer);
obj.timer=null;
if(fnCallBack)fnCallBack.call(obj);
}
}
function miaovDoMoveFlex(obj,oTarget,fnCallBack,fnDuring){
var bStop=true;
var attr='';
var speed=0;
var cur=0;
for(attr in oTarget){
if(!obj.oSpeed)obj.oSpeed={
}
;
if(!obj.oSpeed[attr])obj.oSpeed[attr]=0;
cur=css(obj,attr);
if(Math.abs(oTarget[attr]-cur)>=1 || Math.abs(obj.oSpeed[attr])>=1){
bStop=false;
obj.oSpeed[attr]+=(oTarget[attr]-cur)/5;
obj.oSpeed[attr]*=0.7;
css(obj,attr,cur+obj.oSpeed[attr]);
}
}
if(fnDuring)fnDuring.call(obj);
if(bStop){
clearInterval(obj.timer);
obj.timer=null;
if(fnCallBack)fnCallBack.call(obj);
}
}
window.onload=function (){
var oDiv=document.getElementById('box');
var aLi=oDiv.getElementsByTagName('ul')[0].getElementsByTagName('li');
var iTime=400;
var iTime2=200;
var i=0;
var duringA=function (){
css(this,'marginLeft',-(css(this,'width'))/2-1);
}
;
for(i=0;
i<aLi.length;
i++){
aLi[i].onmouseover=function (){
var oImg=this.getElementsByTagName('img')[0];
var oA=this.getElementsByTagName('a')[0];
var oBg=this.getElementsByTagName('span')[1];
if(this.timer){
clearTimeout(this.timer);
this.timer=null;
return;
}
oA.onmouseover=oImg.onmouseover=oBg.onmouseover=function (ev){
if(this.parentNode.timer){
clearTimeout(this.parentNode.timer);
this.parentNode.timer=null;
(ev||event).cancelBubble=true;
}
}
;
oImg.onmouseout=oA.onmouseout=oBg.onmouseout=function (ev){
var oParent=this.parentNode;
if(oParent.timer)clearTimeout(oParent.timer);
oParent.timer=setTimeout(function (){
oParent.onmouseout();
oParent.timer=null;
}
,200);
(ev||event).cancelBubble=true;
}
;
miaovStartMove2(oImg,{
width:153}
,MIAOV_MOVE_TYPE.FLEX,function (){
css(this,'marginLeft',-78);
}
,duringA);
miaovStartMove2(oA,{
top:56,paddingTop:36,paddingBottom:36}
,MIAOV_MOVE_TYPE.FLEX);
miaovStartMove2(oBg,{
height:115}
,MIAOV_MOVE_TYPE.BUFFER);
}
;
aLi[i].onmouseout=function (){
var oImg=this.getElementsByTagName('img')[0];
var oA=this.getElementsByTagName('a')[0];
var oBg=this.getElementsByTagName('span')[1];
miaovStartMove2(oImg,{
width:0}
,MIAOV_MOVE_TYPE.BUFFER,function (){
css(this,'marginLeft',0);
}
,duringA);
miaovStartMove2(oA,{
top:4,paddingTop:8,paddingBottom:0}
,MIAOV_MOVE_TYPE.BUFFER);
miaovStartMove2(oBg,{
height:0}
,MIAOV_MOVE_TYPE.BUFFER);
}
;
}
}
;