JavaScript must be enabled in order for you to view this page. However, it seems JavaScript is either disabled or not supported by your browser. To view this page, enable JavaScript by changing your browser options, then Try again! .

 
我的论坛
Google 网上论坛 Beta 版
Do Best Developer
访问此论坛

Hello JavaScript

Google在韩国的主页非常漂亮,抓图如下:

Google韩国首页

之所以提到这个页面是因为在这个页面中实现动画效果的方式非常有趣,也告诉我们JavaScript可以用到这种境界。你可以查看Google的源代码,可惜这些代码经过了混淆器的处理不是很容易读。不过这里有对Google代码的简化版。

单击查看运行效果,相关代码如下:

var Binding = function (func, owner) {
    var args = func.args || [];
    args = args.concat(Array["prototype"]["slice"].call(arguments, 2));
    if (func.owner) {
        owner = func.owner;
    }
    if (func.code) {
        func = func.code;
    }
    var cacheFunc = function () {
        var tempArgs = args.concat(Array["prototype"]["slice"].call(arguments));
        return func.apply(owner, tempArgs);
    };
    cacheFunc.args = args;
    cacheFunc.owner = owner;
    cacheFunc.code = func;
    return cacheFunc;
};

Function["prototype"].bind = function (owner) {
    return Binding.apply(null, [this, owner].concat(Array["prototype"]["slice"].call(arguments, 1)));
};

Function["prototype"].inherits = function (baseClass) {
    function inheritance() {
    }
    inheritance.prototype = baseClass["prototype"];
    this.prototype = new inheritance();
    this["prototype"].constructor = this;
    this.superClass = baseClass.prototype;
};

var Event = function (event) {
    this.type = event["type"];
    this.target = event["target"] || event.srcElement;
    this.currentTarget = event["currentTarget"] || event.srcElement;//there is something wrong now
	//eventPhase
	//bubbles
	//cancelable 
    this.timeStamp = new Date();
	
	//only for mouse event
    this.relatedTarget = null;
    if (typeof event["relatedTarget"] != "undefined") {
        this.relatedTarget = event["relatedTarget"];
    } else {
        if (this["type"] == "mouseover") {
            this.relatedTarget = event.fromElement;
        } else {
            if (this["type"] == "mouseout") {
                this.relatedTarget = event.toElement;
            }
        }
    }
    this.event = event;
};

var Listener = function (obj) {
    this.obj = obj;    
};
Listener["prototype"].listen = function (element, eventName, func) {
	var owner = this.obj;
    if (element.addEventListener) {
        element.addEventListener(eventName, function(event){func.call(owner,new Event(event));}, false);
    } else {
        if (element.attachEvent) {
            element.attachEvent("on" + eventName, function(){func.call(owner,new Event(window.event));});
        } else {
            throw Error("Object {" + element + "} does not 
            support event listeners.");
        }
    }
};
Listener["prototype"].unlisten = function (element, eventName, func) {
};
Listener["prototype"].handleEvent = function () {
};

var Animation = function (element, frames, ySpritePosition, animationSpeed, mouseoutTime,textId) {
    Listener.call(this,this);
    
    this.el = element;
    this.mouseTimeout = null;
    this.mouseTimeoutTime = mouseoutTime;
    
    this.frames = frames - 1;
    this.ySpritePosition = ySpritePosition;    
    
    this.animationSpeed = animationSpeed;
    this.animationSpeedTimeout = null;
    
    this.panelElement = this.el.getElementsByTagName("span")[0];
    
    this.frameWidth = this.panelElement["offsetWidth"];
    
    this.flyTip = textId ? new FlyTip(this, textId) : undefined;
    
    this.step = -1;
    
    this.currentFrame = 1;
    this.listen(this.el, "mouseover", this.start);
    this.listen(this.el, "mouseout", this.stop);
    this.listen(document, "mouseout", this.quit);
};

Animation.inherits(Listener);
Animation["prototype"].play = function (step, playFrame) {
    if (step !== undefined) {
        this.step = step;
        this.mouseTimeout = window.clearTimeout(this.mouseTimeout);
        this.animationSpeedTimeout = window.clearTimeout(this.animationSpeedTimeout);
    }
    if (playFrame !== undefined) {
        this.currentFrame = playFrame;
    }
    var position = "-" + this.frameWidth * this.currentFrame + "px " + this.ySpritePosition;
    this.panelElement["style"].backgroundPosition = position;
    if (this.step == 1 && this.currentFrame >= this.frames) {
        this.currentFrame = this.frames - 1;
        return;
    } else {
        if (this.step == -1 && this.currentFrame <= 0) {
            this.currentFrame = 1;
            return;
        } else {
            if (this.flyTip && this.step == 1 && !this.flyTip.isShowing) {
                this.flyTip.show();
            } else {
                if (this.flyTip && this.step == -1 && this.flyTip.isShowing) {
                    this.flyTip.hide();
                }
            }
        }
    }
    
    this.animationSpeedTimeout = window.setTimeout(this["play"].bind(this, undefined, this.currentFrame += this.step), this.animationSpeed);
};
Animation["prototype"].start = function (event) {
    this.mouseTimeout = window.clearTimeout(this.mouseTimeout);
    if (this.step == -1) {
        this.mouseTimeout = window.setTimeout(this["play"].bind(this, 1, undefined), this.mouseTimeoutTime / 3);
    }
};
Animation["prototype"].stop = function (event) {
    this.mouseTimeout = window.clearTimeout(this.mouseTimeout);
    if (this.step == 1) {
        this.mouseTimeout = window.setTimeout(this["play"].bind(this, -1, undefined), this.mouseTimeoutTime);
    }
};
Animation["prototype"].quit = function (event) {
    if (event["relatedTarget"] || this.currentFrame == 1) {
        return;
    }
    this.mouseTimeout = window.setTimeout(this["play"].bind(this, -1, undefined), this.mouseTimeoutTime);
};

var FlyTip = function (animation, textId) {
    Listener.call(this,this);
    this.animation = animation;
    
    var textDiv = document.getElementById(textId);
    
    this.el = textDiv.cloneNode(true);
    this.el.id = this.animation.el.id + "-tt";    
    this.el.className = textDiv.className;
    this.el["style"].display = "none";
    
    var divs = this.el.getElementsByTagName("div");
    for(i=0;i<divs["length"];i++){
    	if(divs[i].className == textId+"-text"){
    		var textTextDiv = divs[i];
    
		    this.panelElement = textTextDiv.appendChild(document.createElement("span"));
		    this.panelElement.appendChild(document.createTextNode(
		    this.animation.el.getAttribute("title")));
		    this.animation.el.setAttribute("title", "");
    	}
    }    
    
    document["body"].appendChild(this.el);
    
    this.isShowing = false;
    this.listen(this.el, "mouseover", this.start);
    this.listen(this.el, "mouseout", this.stop);
};
FlyTip.inherits(Listener);

FlyTip["prototype"].start = function (event) {
    window.clearTimeout(this.animation.mouseTimeout);
};
FlyTip["prototype"].stop = function (event) {
    window.clearTimeout(this.animation.mouseTimeout);
    this.animation.mouseTimeout = window.setTimeout(this.animation["play"].bind(
    this.animation, -1, this.animation.frames - 2), this.animation.mouseTimeoutTime);
};
FlyTip["prototype"].show = function () {
    this.isShowing = true;
    
    var textDivStyle = this.el["style"];
    textDivStyle.visibility = "hidden";
    textDivStyle.display = "block";
     
    var height = this.el.offsetHeight;
    var width = this.panelElement["offsetWidth"]+14;
    
    var rect = {};
    if(this.animation.el.getBoundingClientRect){
    	var box = this.animation.el.getBoundingClientRect();
    	rect.left = box["left"];
    	rect.top = box["top"];
    }else{//getBoxObjectFor
    	var box = document.getBoxObjectFor(this.animation.el);
    	rect.left = box.x;
    	rect.top = box.y; 
    } 

    textDivStyle.width = width+"px";
    textDivStyle.left = rect["left"]-width/2+7+"px";
    textDivStyle.top = rect["top"]-height+"px"; 
    textDivStyle.opacity = "1";
    
    textDivStyle.visibility = "visible";
};
FlyTip["prototype"].hide = function () {
    this.isShowing = false;
    this.el["style"].display = "none";
};

var animations = {};

animations.svcToolbarYSpritePosition = {to:"0px"};
animations.svcToolbarFrames = 7;
animations.svcToolbarAnimationSpeed = 75;
animations.svcToolbarMouseoutTime = 100;

animations.init = function () {    
	var svcToolbarElement = document.getElementById("svc-toolbar");    
    var allA = svcToolbarElement.getElementsByTagName("a");
    
    for (var i = 0, j = allA["length"]; i < j; i++) {
        var aElement = allA[i], aIdnotI = aElement.id.replace("-i", "");
        var animation = new Animation(aElement, animations.svcToolbarFrames, animations.svcToolbarYSpritePosition[aIdnotI], animations.svcToolbarAnimationSpeed, animations.svcToolbarMouseoutTime, "tt");
    }
    
    try {
        document.execCommand("BackgroundImageCache", false, true);
    }
    catch (Error) {
    }
};
var _anis = animations;

(function () {   
_anis.init();
})();