以下是 框架边栏平滑菜单效果特效代码 的示例演示效果:
部分效果截图:
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=gb2312" />
<meta name="keywords" content="JS代码,菜单导航,JS广告代码,JS特效代码" />
<meta name="description" content="此代码内容为框架边栏平滑菜单效果,属于站长常用代码" />
<title>框架边栏平滑菜单效果</title>
<script type="text/javascript" src="js/prototype.js"></script>
<script type="text/javascript" src="js/effects.js"></script>
<script type="text/javascript" src="js/side-bar.js"></script>
<style>
a{outline: none;}
a:active{outline: none;}
#sideBar{
text-align:left;
}
#sideBar h2{
color:#FFFFFF;
font-size:110%;
font-family:arial;
margin:10px 10px 10px 10px;
font-weight:bold !important;
}
#sideBar h2 span{
font-size:125%;
font-weight:normal !important;
}
#sideBar ul{
margin:0px 0px 0px 0px;
padding:0px 0px 0px 0px;
}
#sideBar li{
margin:0px 10px 3px 10px;
padding:2px;
list-style-type:none;
display:block;
background-color:#DA1074;
width:177px;
color:#FFFFFF;
}
#sideBar li a{
width:100%;
}
#sideBar li a:link,
#sideBar li a:visited{
color:#FFFFFF;
font-family:verdana;
font-size:100%;
text-decoration:none;
display:block;
margin:0px 0px 0px 0px;
padding:0px;
width:100%;
}
#sideBar li a:hover{
color:#FFFFFF;
text-decoration:underline;
}
#sideBar{
position: absolute;
width: auto;
height: auto;
top: 140px;
right:0px;
background-image:url(images/background.gif);
background-position:top left;
background-repeat:repeat-y;
}
#sideBarTab{
float:left;
height:137px;
width:28px;
}
#sideBarTab img{
border:0px solid #FFFFFF;
}
#sideBarContents{
float:left;
overflow:hidden !important;
width:200px;
height:320px;
}
#sideBarContentsInner{
width:200px;
}
</style>
</head>
<body>
<div id="sideBar">
<a href="#" id="sideBarTab"><img src="images/slide-button.gif" alt="sideBar" title="sideBar" /></a>
<div id="sideBarContents" style="display:none;">
<div id="sideBarContentsInner">
<h2>side<span>bar</span></h2>
<ul>
<li><a href="#" target="_blank">Link One</a></li>
<li><a href="#" target="_blank">Link Two</a></li>
<li><a href="#" target="_blank">Link Three</a></li>
<li><a href="#" target="_blank">Link Four</a></li>
<li><a href="#" target="_blank">Link Five</a></li>
</ul>
</div>
</div>
</div>
</body>
</html>
JS代码(prototype.js):
/* Prototype JavaScript framework,version 1.5.0 * (c) 2005-2007 Sam Stephenson * * Prototype is freely distributable under the terms of an MIT-style license. * For details,see the Prototype web site:http://prototype.conio.net/ */
*--------------------------------------------------------------------------*/
var Prototype ={
Version:'1.5.0',BrowserFeatures:{
XPath:!!document.evaluate}
,ScriptFragment:'(?:<script.*?>)((\n|\r|.)*?)(?:<\/script>)',emptyFunction:function(){
}
,K:function(x){
return x}
}
var Class ={
create:function(){
return function(){
this.initialize.apply(this,arguments);
}
}
}
var Abstract = new Object();
Object.extend = function(destination,source){
for (var property in source){
destination[property] = source[property];
}
return destination;
}
Object.extend(Object,{
inspect:function(object){
try{
if (object === undefined) return 'undefined';
if (object === null) return 'null';
return object.inspect ? object.inspect():object.toString();
}
catch (e){
if (e instanceof RangeError) return '...';
throw e;
}
}
,keys:function(object){
var keys = [];
for (var property in object) keys.push(property);
return keys;
}
,values:function(object){
var values = [];
for (var property in object) values.push(object[property]);
return values;
}
,clone:function(object){
return Object.extend({
}
,object);
}
}
);
Function.prototype.bind = function(){
var __method = this,args = $A(arguments),object = args.shift();
return function(){
return __method.apply(object,args.concat($A(arguments)));
}
}
Function.prototype.bindAsEventListener = function(object){
var __method = this,args = $A(arguments),object = args.shift();
return function(event){
return __method.apply(object,[( event || window.event)].concat(args).concat($A(arguments)));
}
}
Object.extend(Number.prototype,{
toColorPart:function(){
var digits = this.toString(16);
if (this < 16) return '0' + digits;
return digits;
}
,succ:function(){
return this + 1;
}
,times:function(iterator){
$R(0,this,true).each(iterator);
return this;
}
}
);
var Try ={
these:function(){
var returnValue;
for (var i = 0,length = arguments.length;
i < length;
i++){
var lambda = arguments[i];
try{
returnValue = lambda();
break;
}
catch (e){
}
}
return returnValue;
}
}
/*--------------------------------------------------------------------------*/
var PeriodicalExecuter = Class.create();
PeriodicalExecuter.prototype ={
initialize:function(callback,frequency){
this.callback = callback;
this.frequency = frequency;
this.currentlyExecuting = false;
this.registerCallback();
}
,registerCallback:function(){
this.timer = setInterval(this.onTimerEvent.bind(this),this.frequency * 1000);
}
,stop:function(){
if (!this.timer) return;
clearInterval(this.timer);
this.timer = null;
}
,onTimerEvent:function(){
if (!this.currentlyExecuting){
try{
this.currentlyExecuting = true;
this.callback(this);
}
finally{
this.currentlyExecuting = false;
}
}
}
}
String.interpret = function(value){
return value == null ? '':String(value);
}
Object.extend(String.prototype,{
gsub:function(pattern,replacement){
var result = '',source = this,match;
replacement = arguments.callee.prepareReplacement(replacement);
while (source.length > 0){
if (match = source.match(pattern)){
result += source.slice(0,match.index);
result += String.interpret(replacement(match));
source = source.slice(match.index + match[0].length);
}
else{
result += source,source = '';
}
}
return result;
}
,sub:function(pattern,replacement,count){
replacement = this.gsub.prepareReplacement(replacement);
count = count === undefined ? 1:count;
return this.gsub(pattern,function(match){
if (--count < 0) return match[0];
return replacement(match);
}
);
}
,scan:function(pattern,iterator){
this.gsub(pattern,iterator);
return this;
}
,truncate:function(length,truncation){
length = length || 30;
truncation = truncation === undefined ? '...':truncation;
return this.length > length ? this.slice(0,length - truncation.length) + truncation:this;
}
,strip:function(){
return this.replace(/^\s+/,'').replace(/\s+$/,'');
}
,stripTags:function(){
return this.replace(/<\/?[^>]+>/gi,'');
}
,stripScripts:function(){
return this.replace(new RegExp(Prototype.ScriptFragment,'img'),'');
}
,extractScripts:function(){
var matchAll = new RegExp(Prototype.ScriptFragment,'img');
var matchOne = new RegExp(Prototype.ScriptFragment,'im');
return (this.match(matchAll) || []).map(function(scriptTag){
return (scriptTag.match(matchOne) || ['',''])[1];
}
);
}
,evalScripts:function(){
return this.extractScripts().map(function(script){
return eval(script)}
);
}
,escapeHTML:function(){
var div = document.createElement('div');
var text = document.createTextNode(this);
div.appendChild(text);
return div.innerHTML;
}
,unescapeHTML:function(){
var div = document.createElement('div');
div.innerHTML = this.stripTags();
return div.childNodes[0] ? (div.childNodes.length > 1 ? $A(div.childNodes).inject('',function(memo,node){
return memo+node.nodeValue}
):div.childNodes[0].nodeValue):'';
}
,toQueryParams:function(separator){
var match = this.strip().match(/([^?#]*)(#.*)?$/);
if (!match) return{
}
;
return match[1].split(separator || '&').inject({
}
,function(hash,pair){
if ((pair = pair.split('='))[0]){
var name = decodeURIComponent(pair[0]);
var value = pair[1] ? decodeURIComponent(pair[1]):undefined;
if (hash[name] !== undefined){
if (hash[name].constructor != Array) hash[name] = [hash[name]];
if (value) hash[name].push(value);
}
else hash[name] = value;
}
return hash;
}
);
}
,toArray:function(){
return this.split('');
}
,succ:function(){
return this.slice(0,this.length - 1) + String.fromCharCode(this.charCodeAt(this.length - 1) + 1);
}
,camelize:function(){
var parts = this.split('-'),len = parts.length;
if (len == 1) return parts[0];
var camelized = this.charAt(0) == '-' ? parts[0].charAt(0).toUpperCase() + parts[0].substring(1):parts[0];
for (var i = 1;
i < len;
i++) camelized += parts[i].charAt(0).toUpperCase() + parts[i].substring(1);
return camelized;
}
,capitalize:function(){
return this.charAt(0).toUpperCase() + this.substring(1).toLowerCase();
}
,underscore:function(){
return this.gsub(/::/,'/').gsub(/([A-Z]+)([A-Z][a-z])/,'#{
1}
_#{
2}
').gsub(/([a-z\d])([A-Z])/,'#{
1}
_#{
2}
').gsub(/-/,'_').toLowerCase();
}
,dasherize:function(){
return this.gsub(/_/,'-');
}
,inspect:function(useDoubleQuotes){
var escapedString = this.replace(/\\/g,'\\\\');
if (useDoubleQuotes) return '"' + escapedString.replace(/"/g,'\\"') + '"';
else return "'" + escapedString.replace(/'/g,'\\\'') + "'";
}
}
);
String.prototype.gsub.prepareReplacement = function(replacement){
if (typeof replacement == 'function') return replacement;
var template = new Template(replacement);
return function(match){
return template.evaluate(match)}
;
}
String.prototype.parseQuery = String.prototype.toQueryParams;
var Template = Class.create();
Template.Pattern = /(^|.|\r|\n)(#\{
(.*?)\}
)/;
Template.prototype ={
initialize:function(template,pattern){
this.template = template.toString();
this.pattern = pattern || Template.Pattern;
}
,evaluate:function(object){
return this.template.gsub(this.pattern,function(match){
var before = match[1];
if (before == '\\') return match[2];
return before + String.interpret(object[match[3]]);
}
);
}
}
var $break = new Object();
var $continue = new Object();
var Enumerable ={
each:function(iterator){
var index = 0;
try{
this._each(function(value){
try{
iterator(value,index++);
}
catch (e){
if (e != $continue) throw e;
}
}
);
}
catch (e){
if (e != $break) throw e;
}
return this;
}
,eachSlice:function(number,iterator){
var index = -number,slices = [],array = this.toArray();
while ((index += number) < array.length) slices.push(array.slice(index,index+number));
return slices.map(iterator);
}
,all:function(iterator){
var result = true;
this.each(function(value,index){
result = result && !!(iterator || Prototype.K)(value,index);
if (!result) throw $break;
}
);
return result;
}
,any:function(iterator){
var result = false;
this.each(function(value,index){
if (result = !!(iterator || Prototype.K)(value,index)) throw $break;
}
);
return result;
}
,collect:function(iterator){
var results = [];
this.each(function(value,index){
results.push((iterator || Prototype.K)(value,index));
}
);
return results;
}
,detect:function(iterator){
var result;
this.each(function(value,index){
if (iterator(value,index)){
result = value;
throw $break;
}
}
);
return result;
}
,findAll:function(iterator){
var results = [];
this.each(function(value,index){
if (iterator(value,index)) results.push(value);
}
);
return results;
}
,grep:function(pattern,iterator){
var results = [];
this.each(function(value,index){
var stringValue = value.toString();
if (stringValue.match(pattern)) results.push((iterator || Prototype.K)(value,index));
}
) return results;
}
,include:function(object){
var found = false;
this.each(function(value){
if (value == object){
found = true;
throw $break;
}
}
);
return found;
}
,inGroupsOf:function(number,fillWith){
fillWith = fillWith === undefined ? null:fillWith;
return this.eachSlice(number,function(slice){
while(slice.length < number) slice.push(fillWith);
return slice;
}
);
}
,inject:function(memo,iterator){
this.each(function(value,index){
memo = iterator(memo,value,index);
}
);
return memo;
}
,invoke:function(method){
var args = $A(arguments).slice(1);
return this.map(function(value){
return value[method].apply(value,args);
}
);
}
,max:function(iterator){
var result;
this.each(function(value,index){
value = (iterator || Prototype.K)(value,index);
if (result == undefined || value >= result) result = value;
}
);
return result;
}
,min:function(iterator){
var result;
this.each(function(value,index){
value = (iterator || Prototype.K)(value,index);
if (result == undefined || value < result) result = value;
}
);
return result;
}
,partition:function(iterator){
var trues = [],falses = [];
this.each(function(value,index){
((iterator || Prototype.K)(value,index) ? trues:falses).push(value);
}
);
return [trues,falses];
}
,pluck:function(property){
var results = [];
this.each(function(value,index){
results.push(value[property]);
}
);
return results;
}
,reject:function(iterator){
var results = [];
this.each(function(value,index){
if (!iterator(value,index)) results.push(value);
}
);
return results;
}
,sortBy:function(iterator){
return this.map(function(value,index){
return{
value:value,criteria:iterator(value,index)}
;
}
).sort(function(left,right){
var a = left.criteria,b = right.criteria;
return a < b ? -1:a > b ? 1:0;
}
).pluck('value');
}
,toArray:function(){
return this.map();
}
,zip:function(){
var iterator = Prototype.K,args = $A(arguments);
if (typeof args.last() == 'function') iterator = args.pop();
var collections = [this].concat(args).map($A);
return this.map(function(value,index){
return iterator(collections.pluck(index));
}
);
}
,size:function(){
return this.toArray().length;
}
,inspect:function(){
return '#<Enumerable:' + this.toArray().inspect() + '>';
}
}
Object.extend(Enumerable,{
map:Enumerable.collect,find:Enumerable.detect,select:Enumerable.findAll,member:Enumerable.include,entries:Enumerable.toArray}
);
var $A = Array.from = function(iterable){
if (!iterable) return [];
if (iterable.toArray){
return iterable.toArray();
}
else{
var results = [];
for (var i = 0,length = iterable.length;
i < length;
i++) results.push(iterable[i]);
return results;
}
}
Object.extend(Array.prototype,Enumerable);
if (!Array.prototype._reverse) Array.prototype._reverse = Array.prototype.reverse;
Object.extend(Array.prototype,{
_each:function(iterator){
for (var i = 0,length = this.length;
i < length;
i++) iterator(this[i]);
}
,clear:function(){
this.length = 0;
return this;
}
,first:function(){
return this[0];
}
,last:function(){
return this[this.length - 1];
}
,compact:function(){
return this.select(function(value){
return value != null;
}
);
}
,flatten:function(){
return this.inject([],function(array,value){
return array.concat(value && value.constructor == Array ? value.flatten():[value]);
}
);
}
,without:function(){
var values = $A(arguments);
return this.select(function(value){
return !values.include(value);
}
);
}
,indexOf:function(object){
for (var i = 0,length = this.length;
i < length;
i++) if (this[i] == object) return i;
return -1;
}
,reverse:function(inline){
return (inline !== false ? this:this.toArray())._reverse();
}
,reduce:function(){
return this.length > 1 ? this:this[0];
}
,uniq:function(){
return this.inject([],function(array,value){
return array.include(value) ? array:array.concat([value]);
}
);
}
,clone:function(){
return [].concat(this);
}
,size:function(){
return this.length;
}
,inspect:function(){
return '[' + this.map(Object.inspect).join(',') + ']';
}
}
);
Array.prototype.toArray = Array.prototype.clone;
function $w(string){
string = string.strip();
return string ? string.split(/\s+/):[];
}
if(window.opera){
Array.prototype.concat = function(){
var array = [];
for(var i = 0,length = this.length;
i < length;
i++) array.push(this[i]);
for(var i = 0,length = arguments.length;
i < length;
i++){
if(arguments[i].constructor == Array){
for(var j = 0,arrayLength = arguments[i].length;
j < arrayLength;
j++) array.push(arguments[i][j]);
}
else{
array.push(arguments[i]);
}
}
return array;
}
}
var Hash = function(obj){
Object.extend(this,obj ||{
}
);
}
;
Object.extend(Hash,{
toQueryString:function(obj){
var parts = [];
this.prototype._each.call(obj,function(pair){
if (!pair.key) return;
if (pair.value && pair.value.constructor == Array){
var values = pair.value.compact();
if (values.length < 2) pair.value = values.reduce();
else{
key = encodeURIComponent(pair.key);
values.each(function(value){
value = value != undefined ? encodeURIComponent(value):'';
parts.push(key + '=' + encodeURIComponent(value));
}
);
return;
}
}
if (pair.value == undefined) pair[1] = '';
parts.push(pair.map(encodeURIComponent).join('='));
}
);
return parts.join('&');
}
}
);
Object.extend(Hash.prototype,Enumerable);
Object.extend(Hash.prototype,{
_each:function(iterator){
for (var key in this){
var value = this[key];
if (value && value == Hash.prototype[key]) continue;
var pair = [key,value];
pair.key = key;
pair.value = value;
iterator(pair);
}
}
,keys:function(){
return this.pluck('key');
}
,values:function(){
return this.pluck('value');
}
,merge:function(hash){
return $H(hash).inject(this,function(mergedHash,pair){
mergedHash[pair.key] = pair.value;
return mergedHash;
}
);
}
,remove:function(){
var result;
for(var i = 0,length = arguments.length;
i < length;
i++){
var value = this[arguments[i]];
if (value !== undefined){
if (result === undefined) result = value;
else{
if (result.constructor != Array) result = [result];
result.push(value)}
}
delete this[arguments[i]];
}
return result;
}
,toQueryString:function(){
return Hash.toQueryString(this);
}
,inspect:function(){
return '#<Hash:{
' + this.map(function(pair){
return pair.map(Object.inspect).join(':');
}
).join(',') + '}
>';
}
}
);
function $H(object){
if (object && object.constructor == Hash) return object;
return new Hash(object);
}
;
ObjectRange = Class.create();
Object.extend(ObjectRange.prototype,Enumerable);
Object.extend(ObjectRange.prototype,{
initialize:function(start,end,exclusive){
this.start = start;
this.end = end;
this.exclusive = exclusive;
}
,_each:function(iterator){
var value = this.start;
while (this.include(value)){
iterator(value);
value = value.succ();
}
}
,include:function(value){
if (value < this.start) return false;
if (this.exclusive) return value < this.end;
return value <= this.end;
}
}
);
var $R = function(start,end,exclusive){
return new ObjectRange(start,end,exclusive);
}
var Ajax ={
getTransport:function(){
return Try.these( function(){
return new XMLHttpRequest()}
,function(){
return new ActiveXObject('Msxml2.XMLHTTP')}
,function(){
return new ActiveXObject('Microsoft.XMLHTTP')}
) || false;
}
,activeRequestCount:0}
Ajax.Responders ={
responders:[],_each:function(iterator){
this.responders._each(iterator);
}
,register:function(responder){
if (!this.include(responder)) this.responders.push(responder);
}
,unregister:function(responder){
this.responders = this.responders.without(responder);
}
,dispatch:function(callback,request,transport,json){
this.each(function(responder){
if (typeof responder[callback] == 'function'){
try{
responder[callback].apply(responder,[request,transport,json]);
}
catch (e){
}
}
}
);
}
}
;
Object.extend(Ajax.Responders,Enumerable);
Ajax.Responders.register({
onCreate:function(){
Ajax.activeRequestCount++;
}
,onComplete:function(){
Ajax.activeRequestCount--;
}
}
);
Ajax.Base = function(){
}
;
Ajax.Base.prototype ={
setOptions:function(options){
this.options ={
method:'post',asynchronous:true,contentType:'application/x-www-form-urlencoded',encoding:'UTF-8',parameters:''}
Object.extend(this.options,options ||{
}
);
this.options.method = this.options.method.toLowerCase();
if (typeof this.options.parameters == 'string') this.options.parameters = this.options.parameters.toQueryParams();
}
}
Ajax.Request = Class.create();
Ajax.Request.Events = ['Uninitialized','Loading','Loaded','Interactive','Complete'];
Ajax.Request.prototype = Object.extend(new Ajax.Base(),{
_complete:false,initialize:function(url,options){
this.transport = Ajax.getTransport();
this.setOptions(options);
this.request(url);
}
,request:function(url){
this.url = url;
this.method = this.options.method;
var params = this.options.parameters;
if (!['get','post'].include(this.method)){
// simulate other verbs over post params['_method'] = this.method;
this.method = 'post';
}
params = Hash.toQueryString(params);
if (params && /Konqueror|Safari|KHTML/.test(navigator.userAgent)) params += '&_=' // when GET,append parameters to URL if (this.method == 'get' && params) this.url += (this.url.indexOf('?') > -1 ? '&':'?') + params;
try{
Ajax.Responders.dispatch('onCreate',this,this.transport);
this.transport.open(this.method.toUpperCase(),this.url,this.options.asynchronous);
if (this.options.asynchronous) setTimeout(function(){
this.respondToReadyState(1)}
.bind(this),10);
this.transport.onreadystatechange = this.onStateChange.bind(this);
this.setRequestHeaders();
var body = this.method == 'post' ? (this.options.postBody || params):null;
this.transport.send(body);
/* Force Firefox to handle ready state 4 for synchronous requests */
if (!this.options.asynchronous && this.transport.overrideMimeType) this.onStateChange();
}
catch (e){
this.dispatchException(e);
}
}
,onStateChange:function(){
var readyState = this.transport.readyState;
if (readyState > 1 && !((readyState == 4) && this._complete)) this.respondToReadyState(this.transport.readyState);
}
,setRequestHeaders:function(){
var headers ={
'X-Requested-With':'XMLHttpRequest','X-Prototype-Version':Prototype.Version,'Accept':'text/javascript,text/html,application/xml,text/xml,*/
*'}
;
if (this.method == 'post'){
headers['Content-type'] = this.options.contentType + (this.options.encoding ? ';
charset=' + this.options.encoding:'');
/* Force "Connection:close" for older Mozilla browsers to work * around a bug where XMLHttpRequest sends an incorrect * Content-length header. See Mozilla Bugzilla #246651. */
if (this.transport.overrideMimeType && (navigator.userAgent.match(/Gecko\/(\d{
4}
)/) || [0,2005])[1] < 2005) headers['Connection'] = 'close';
}
// user-defined headers if (typeof this.options.requestHeaders == 'object'){
var extras = this.options.requestHeaders;
if (typeof extras.push == 'function') for (var i = 0,length = extras.length;
i < length;
i += 2) headers[extras[i]] = extras[i+1];
else $H(extras).each(function(pair){
headers[pair.key] = pair.value}
);
}
for (var name in headers) this.transport.setRequestHeader(name,headers[name]);
}
,success:function(){
return !this.transport.status || (this.transport.status >= 200 && this.transport.status < 300);
}
,respondToReadyState:function(readyState){
var state = Ajax.Request.Events[readyState];
var transport = this.transport,json = this.evalJSON();
if (state == 'Complete'){
try{
this._complete = true;
(this.options['on' + this.transport.status] || this.options['on' + (this.success() ? 'Success':'Failure')] || Prototype.emptyFunction)(transport,json);
}
catch (e){
this.dispatchException(e);
}
if ((this.getHeader('Content-type') || 'text/javascript').strip(). match(/^(text|application)\/(x-)?(java|ecma)script(;
.*)?$/i)) this.evalResponse();
}
try{
(this.options['on' + state] || Prototype.emptyFunction)(transport,json);
Ajax.Responders.dispatch('on' + state,this,transport,json);
}
catch (e){
this.dispatchException(e);
}
if (state == 'Complete'){
// avoid memory leak in MSIE:clean up this.transport.onreadystatechange = Prototype.emptyFunction;
}
}
,getHeader:function(name){
try{
return this.transport.getResponseHeader(name);
}
catch (e){
return null}
}
,evalJSON:function(){
try{
var json = this.getHeader('X-JSON');
return json ? eval('(' + json + ')'):null;
}
catch (e){
return null}
}
,evalResponse:function(){
try{
return eval(this.transport.responseText);
}
catch (e){
this.dispatchException(e);
}
}
,dispatchException:function(exception){
(this.options.onException || Prototype.emptyFunction)(this,exception);
Ajax.Responders.dispatch('onException',this,exception);
}
}
);
Ajax.Updater = Class.create();
Object.extend(Object.extend(Ajax.Updater.prototype,Ajax.Request.prototype),{
initialize:function(container,url,options){
this.container ={
success:(container.success || container),failure:(container.failure || (container.success ? null:container))}
this.transport = Ajax.getTransport();
this.setOptions(options);
var onComplete = this.options.onComplete || Prototype.emptyFunction;
this.options.onComplete = (function(transport,param){
this.updateContent();
onComplete(transport,param);
}
).bind(this);
this.request(url);
}
,updateContent:function(){
var receiver = this.container[this.success() ? 'success':'failure'];
var response = this.transport.responseText;
if (!this.options.evalScripts) response = response.stripScripts();
if (receiver = $(receiver)){
if (this.options.insertion) new this.options.insertion(receiver,response);
else receiver.update(response);
}
if (this.success()){
if (this.onComplete) setTimeout(this.onComplete.bind(this),10);
}
}
}
);
Ajax.PeriodicalUpdater = Class.create();
Ajax.PeriodicalUpdater.prototype = Object.extend(new Ajax.Base(),{
initialize:function(container,url,options){
this.setOptions(options);
this.onComplete = this.options.onComplete;
this.frequency = (this.options.frequency || 2);
this.decay = (this.options.decay || 1);
this.updater ={
}
;
this.container = container;
this.url = url;
this.start();
}
,start:function(){
this.options.onComplete = this.updateComplete.bind(this);
this.onTimerEvent();
}
,stop:function(){
this.updater.options.onComplete = undefined;
clearTimeout(this.timer);
(this.onComplete || Prototype.emptyFunction).apply(this,arguments);
}
,updateComplete:function(request){
if (this.options.decay){
this.decay = (request.responseText == this.lastText ? this.decay * this.options.decay:1);
this.lastText = request.responseText;
}
this.timer = setTimeout(this.onTimerEvent.bind(this),this.decay * this.frequency * 1000);
}
,onTimerEvent:function(){
this.updater = new Ajax.Updater(this.container,this.url,this.options);
}
}
);
function $(element){
if (arguments.length > 1){
for (var i = 0,elements = [],length = arguments.length;
i < length;
i++) elements.push($(arguments[i]));
return elements;
}
if (typeof element == 'string') element = document.getElementById(element);
return Element.extend(element);
}
if (Prototype.BrowserFeatures.XPath){
document._getElementsByXPath = function(expression,parentElement){
var results = [];
var query = document.evaluate(expression,$(parentElement) || document,null,XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,null);
for (var i = 0,length = query.snapshotLength;
i < length;
i++) results.push(query.snapshotItem(i));
return results;
}
;
}
document.getElementsByClassName = function(className,parentElement){
if (Prototype.BrowserFeatures.XPath){
var q = ".//*[contains(concat(' ',@class,' '),' " + className + " ')]";
return document._getElementsByXPath(q,parentElement);
}
else{
var children = ($(parentElement) || document.body).getElementsByTagName('*');
var elements = [],child;
for (var i = 0,length = children.length;
i < length;
i++){
child = children[i];
if (Element.hasClassName(child,className)) elements.push(Element.extend(child));
}
return elements;
}
}
;
/*--------------------------------------------------------------------------*/
if (!window.Element) var Element = new Object();
Element.extend = function(element){
if (!element || _nativeExtensions || element.nodeType == 3) return element;
if (!element._extended && element.tagName && element != window){
var methods = Object.clone(Element.Methods),cache = Element.extend.cache;
if (element.tagName == 'FORM') Object.extend(methods,Form.Methods);
if (['INPUT','TEXTAREA','SELECT'].include(element.tagName)) Object.extend(methods,Form.Element.Methods);
Object.extend(methods,Element.Methods.Simulated);
for (var property in methods){
var value = methods[property];
if (typeof value == 'function' && !(property in element)) element[property] = cache.findOrStore(value);
}
}
element._extended = true;
return element;
}
;
Element.extend.cache ={
findOrStore:function(value){
return this[value] = this[value] || function(){
return value.apply(null,[this].concat($A(arguments)));
}
}
}
;
Element.Methods ={
visible:function(element){
return $(element).style.display != 'none';
}
,toggle:function(element){
element = $(element);
Element[Element.visible(element) ? 'hide':'show'](element);
return element;
}
,hide:function(element){
$(element).style.display = 'none';
return element;
}
,show:function(element){
$(element).style.display = '';
return element;
}
,remove:function(element){
element = $(element);
element.parentNode.removeChild(element);
return element;
}
,update:function(element,html){
html = typeof html == 'undefined' ? '':html.toString();
$(element).innerHTML = html.stripScripts();
setTimeout(function(){
html.evalScripts()}
,10);
return element;
}
,replace:function(element,html){
element = $(element);
html = typeof html == 'undefined' ? '':html.toString();
if (element.outerHTML){
element.outerHTML = html.stripScripts();
}
else{
var range = element.ownerDocument.createRange();
range.selectNodeContents(element);
element.parentNode.replaceChild( range.createContextualFragment(html.stripScripts()),element);
}
setTimeout(function(){
html.evalScripts()}
,10);
return element;
}
,inspect:function(element){
element = $(element);
var result = '<' + element.tagName.toLowerCase();
$H({
'id':'id','className':'class'}
).each(function(pair){
var property = pair.first(),attribute = pair.last();
var value = (element[property] || '').toString();
if (value) result += ' ' + attribute + '=' + value.inspect(true);
}
);
return result + '>';
}
,recursivelyCollect:function(element,property){
element = $(element);
var elements = [];
while (element = element[property]) if (element.nodeType == 1) elements.push(Element.extend(element));
return elements;
}
,ancestors:function(element){
return $(element).recursivelyCollect('parentNode');
}
,descendants:function(element){
return $A($(element).getElementsByTagName('*'));
}
,immediateDescendants:function(element){
if (!(element = $(element).firstChild)) return [];
while (element && element.nodeType != 1) element = element.nextSibling;
if (element) return [element].concat($(element).nextSiblings());
return [];
}
,previousSiblings:function(element){
return $(element).recursivelyCollect('previousSibling');
}
,nextSiblings:function(element){
return $(element).recursivelyCollect('nextSibling');
}
,siblings:function(element){
element = $(element);
return element.previousSiblings().reverse().concat(element.nextSiblings());
}
,match:function(element,selector){
if (typeof selector == 'string') selector = new Selector(selector);
return selector.match($(element));
}
,up:function(element,expression,index){
return Selector.findElement($(element).ancestors(),expression,index);
}
,down:function(element,expression,index){
return Selector.findElement($(element).descendants(),expression,index);
}
,previous:function(element,expression,index){
return Selector.findElement($(element).previousSiblings(),expression,index);
}
,next:function(element,expression,index){
return Selector.findElement($(element).nextSiblings(),expression,index);
}
,getElementsBySelector:function(){
var args = $A(arguments),element = $(args.shift());
return Selector.findChildElements(element,args);
}
,getElementsByClassName:function(element,className){
return document.getElementsByClassName(className,element);
}
,readAttribute:function(element,name){
element = $(element);
if (document.all && !window.opera){
var t = Element._attributeTranslations;
if (t.values[name]) return t.values[name](element,name);
if (t.names[name]) name = t.names[name];
var attribute = element.attributes[name];
if(attribute) return attribute.nodeValue;
}
return element.getAttribute(name);
}
,getHeight:function(element){
return $(element).getDimensions().height;
}
,getWidth:function(element){
return $(element).getDimensions().width;
}
,classNames:function(element){
return new Element.ClassNames(element);
}
,hasClassName:function(element,className){
if (!(element = $(element))) return;
var elementClassName = element.className;
if (elementClassName.length == 0) return false;
if (elementClassName == className || elementClassName.match(new RegExp("(^|\\s)" + className + "(\\s|$)"))) return true;
return false;
}
,addClassName:function(element,className){
if (!(element = $(element))) return;
Element.classNames(element).add(className);
return element;
}
,removeClassName:function(element,className){
if (!(element = $(element))) return;
Element.classNames(element).remove(className);
return element;
}
,toggleClassName:function(element,className){
if (!(element = $(element))) return;
Element.classNames(element)[element.hasClassName(className) ? 'remove':'add'](className);
return element;
}
,observe:function(){
Event.observe.apply(Event,arguments);
return $A(arguments).first();
}
,stopObserving:function(){
Event.stopObserving.apply(Event,arguments);
return $A(arguments).first();
}
,// removes whitespace-only text node children cleanWhitespace:function(element){
element = $(element);
var node = element.firstChild;
while (node){
var nextNode = node.nextSibling;
if (node.nodeType == 3 && !/\S/.test(node.nodeValue)) element.removeChild(node);
node = nextNode;
}
return element;
}
,empty:function(element){
return $(element).innerHTML.match(/^\s*$/);
}
,descendantOf:function(element,ancestor){
element = $(element),ancestor = $(ancestor);
while (element = element.parentNode) if (element == ancestor) return true;
return false;
}
,scrollTo:function(element){
element = $(element);
var pos = Position.cumulativeOffset(element);
window.scrollTo(pos[0],pos[1]);
return element;
}
,getStyle:function(element,style){
element = $(element);
if (['float','cssFloat'].include(style)) style = (typeof element.style.styleFloat != 'undefined' ? 'styleFloat':'cssFloat');
style = style.camelize();
var value = element.style[style];
if (!value){
if (document.defaultView && document.defaultView.getComputedStyle){
var css = document.defaultView.getComputedStyle(element,null);
value = css ? css[style]:null;
}
else if (element.currentStyle){
value = element.currentStyle[style];
}
}
if((value == 'auto') && ['width','height'].include(style) && (element.getStyle('display') != 'none')) value = element['offset'+style.capitalize()] + 'px';
if (window.opera && ['left','top','right','bottom'].include(style)) if (Element.getStyle(element,'position') == 'static') value = 'auto';
if(style == 'opacity'){
if(value) return parseFloat(value);
if(value = (element.getStyle('filter') || '').match(/alpha\(opacity=(.*)\)/)) if(value[1]) return parseFloat(value[1]) / 100;
return 1.0;
}
return value == 'auto' ? null:value;
}
,setStyle:function(element,style){
element = $(element);
for (var name in style){
var value = style[name];
if(name == 'opacity'){
if (value == 1){
value = (/Gecko/.test(navigator.userAgent) && !/Konqueror|Safari|KHTML/.test(navigator.userAgent)) ? 0.999999:1.0;
if(/MSIE/.test(navigator.userAgent) && !window.opera) element.style.filter = element.getStyle('filter').replace(/alpha\([^\)]*\)/gi,'');
}
else if(value === ''){
if(/MSIE/.test(navigator.userAgent) && !window.opera) element.style.filter = element.getStyle('filter').replace(/alpha\([^\)]*\)/gi,'');
}
else{
if(value < 0.00001) value = 0;
if(/MSIE/.test(navigator.userAgent) && !window.opera) element.style.filter = element.getStyle('filter').replace(/alpha\([^\)]*\)/gi,'') + 'alpha(opacity='+value*100+')';
}
}
else if(['float','cssFloat'].include(name)) name = (typeof element.style.styleFloat != 'undefined') ? 'styleFloat':'cssFloat';
element.style[name.camelize()] = value;
}
return element;
}
,getDimensions:function(element){
element = $(element);
var display = $(element).getStyle('display');
if (display != 'none' && display != null) // Safari bug return{
width:element.offsetWidth,height:element.offsetHeight}
;
// All *Width and *Height properties give 0 on elements with display none,// so enable the element temporarily var els = element.style;
var originalVisibility = els.visibility;
var originalPosition = els.position;
var originalDisplay = els.display;
els.visibility = 'hidden';
els.position = 'absolute';
els.display = 'block';
var originalWidth = element.clientWidth;
var originalHeight = element.clientHeight;
els.display = originalDisplay;
els.position = originalPosition;
els.visibility = originalVisibility;
return{
width:originalWidth,height:originalHeight}
;
}
,makePositioned:function(element){
element = $(element);
var pos = Element.getStyle(element,'position');
if (pos == 'static' || !pos){
element._madePositioned = true;
element.style.position = 'relative';
// Opera returns the offset relative to the positioning context,when an // element is position relative but top and left have not been defined if (window.opera){
element.style.top = 0;
element.style.left = 0;
}
}
return element;
}
,undoPositioned:function(element){
element = $(element);
if (element._madePositioned){
element._madePositioned = undefined;
element.style.position = element.style.top = element.style.left = element.style.bottom = element.style.right = '';
}
return element;
}
,makeClipping:function(element){
element = $(element);
if (element._overflow) return element;
element._overflow = element.style.overflow || 'auto';
if ((Element.getStyle(element,'overflow') || 'visible') != 'hidden') element.style.overflow = 'hidden';
return element;
}
,undoClipping:function(element){
element = $(element);
if (!element._overflow) return element;
element.style.overflow = element._overflow == 'auto' ? '':element._overflow;
element._overflow = null;
return element;
}
}
;
Object.extend(Element.Methods,{
childOf:Element.Methods.descendantOf}
);
Element._attributeTranslations ={
}
;
Element._attributeTranslations.names ={
colspan:"colSpan",rowspan:"rowSpan",valign:"vAlign",datetime:"dateTime",accesskey:"accessKey",tabindex:"tabIndex",enctype:"encType",maxlength:"maxLength",readonly:"readOnly",longdesc:"longDesc"}
;
Element._attributeTranslations.values ={
_getAttr:function(element,attribute){
return element.getAttribute(attribute,2);
}
,_flag:function(element,attribute){
return $(element).hasAttribute(attribute) ? attribute:null;
}
,style:function(element){
return element.style.cssText.toLowerCase();
}
,title:function(element){
var node = element.getAttributeNode('title');
return node.specified ? node.nodeValue:null;
}
}
;
Object.extend(Element._attributeTranslations.values,{
href:Element._attributeTranslations.values._getAttr,src:Element._attributeTranslations.values._getAttr,disabled:Element._attributeTranslations.values._flag,checked:Element._attributeTranslations.values._flag,readonly:Element._attributeTranslations.values._flag,multiple:Element._attributeTranslations.values._flag}
);
Element.Methods.Simulated ={
hasAttribute:function(element,attribute){
var t = Element._attributeTranslations;
attribute = t.names[attribute] || attribute;
return $(element).getAttributeNode(attribute).specified;
}
}
;
// IE is missing .innerHTML support for TABLE-related elementsif (document.all && !window.opera){
Element.Methods.update = function(element,html){
element = $(element);
html = typeof html == 'undefined' ? '':html.toString();
var tagName = element.tagName.toUpperCase();
if (['THEAD','TBODY','TR','TD'].include(tagName)){
var div = document.createElement('div');
switch (tagName){
case 'THEAD':case 'TBODY':div.innerHTML = '<table><tbody>' + html.stripScripts() + '</tbody></table>';
depth = 2;
break;
case 'TR':div.innerHTML = '<table><tbody><tr>' + html.stripScripts() + '</tr></tbody></table>';
depth = 3;
break;
case 'TD':div.innerHTML = '<table><tbody><tr><td>' + html.stripScripts() + '</td></tr></tbody></table>';
depth = 4;
}
$A(element.childNodes).each(function(node){
element.removeChild(node)}
);
depth.times(function(){
div = div.firstChild}
);
$A(div.childNodes).each( function(node){
element.appendChild(node)}
);
}
else{
element.innerHTML = html.stripScripts();
}
setTimeout(function(){
html.evalScripts()}
,10);
return element;
}
}
;
Object.extend(Element,Element.Methods);
var _nativeExtensions = false;
if(/Konqueror|Safari|KHTML/.test(navigator.userAgent)) ['','Form','Input','TextArea','Select'].each(function(tag){
var className = 'HTML' + tag + 'Element';
if(window[className]) return;
var klass = window[className] ={
}
;
klass.prototype = document.createElement(tag ? tag.toLowerCase():'div').__proto__;
}
);
Element.addMethods = function(methods){
Object.extend(Element.Methods,methods ||{
}
);
function copy(methods,destination,onlyIfAbsent){
onlyIfAbsent = onlyIfAbsent || false;
var cache = Element.extend.cache;
for (var property in methods){
var value = methods[property];
if (!onlyIfAbsent || !(property in destination)) destination[property] = cache.findOrStore(value);
}
}
if (typeof HTMLElement != 'undefined'){
copy(Element.Methods,HTMLElement.prototype);
copy(Element.Methods.Simulated,HTMLElement.prototype,true);
copy(Form.Methods,HTMLFormElement.prototype);
[HTMLInputElement,HTMLTextAreaElement,HTMLSelectElement].each(function(klass){
copy(Form.Element.Methods,klass.prototype);
}
);
_nativeExtensions = true;
}
}
var Toggle = new Object();
Toggle.display = Element.toggle;
/*--------------------------------------------------------------------------*/
Abstract.Insertion = function(adjacency){
this.adjacency = adjacency;
}
Abstract.Insertion.prototype ={
initialize:function(element,content){
this.element = $(element);
this.content = content.stripScripts();
if (this.adjacency && this.element.insertAdjacentHTML){
try{
this.element.insertAdjacentHTML(this.adjacency,this.content);
}
catch (e){
var tagName = this.element.tagName.toUpperCase();
if (['TBODY','TR'].include(tagName)){
this.insertContent(this.contentFromAnonymousTable());
}
else{
throw e;
}
}
}
else{
this.range = this.element.ownerDocument.createRange();
if (this.initializeRange) this.initializeRange();
this.insertContent([this.range.createContextualFragment(this.content)]);
}
setTimeout(function(){
content.evalScripts()}
,10);
}
,contentFromAnonymousTable:function(){
var div = document.createElement('div');
div.innerHTML = '<table><tbody>' + this.content + '</tbody></table>';
return $A(div.childNodes[0].childNodes[0].childNodes);
}
}
var Insertion = new Object();
Insertion.Before = Class.create();
Insertion.Before.prototype = Object.extend(new Abstract.Insertion('beforeBegin'),{
initializeRange:function(){
this.range.setStartBefore(this.element);
}
,insertContent:function(fragments){
fragments.each((function(fragment){
this.element.parentNode.insertBefore(fragment,this.element);
}
).bind(this));
}
}
);
Insertion.Top = Class.create();
Insertion.Top.prototype = Object.extend(new Abstract.Insertion('afterBegin'),{
initializeRange:function(){
this.range.selectNodeContents(this.element);
this.range.collapse(true);
}
,insertContent:function(fragments){
fragments.reverse(false).each((function(fragment){
this.element.insertBefore(fragment,this.element.firstChild);
}
).bind(this));
}
}
);
Insertion.Bottom = Class.create();
Insertion.Bottom.prototype = Object.extend(new Abstract.Insertion('beforeEnd'),{
initializeRange:function(){
this.range.selectNodeContents(this.element);
this.range.collapse(this.element);
}
,insertContent:function(fragments){
fragments.each((function(fragment){
this.element.appendChild(fragment);
}
).bind(this));
}
}
);
Insertion.After = Class.create();
Insertion.After.prototype = Object.extend(new Abstract.Insertion('afterEnd'),{
initializeRange:function(){
this.range.setStartAfter(this.element);
}
,insertContent:function(fragments){
fragments.each((function(fragment){
this.element.parentNode.insertBefore(fragment,this.element.nextSibling);
}
).bind(this));
}
}
);
/*--------------------------------------------------------------------------*/
Element.ClassNames = Class.create();
Element.ClassNames.prototype ={
initialize:function(element){
this.element = $(element);
}
,_each:function(iterator){
this.element.className.split(/\s+/).select(function(name){
return name.length > 0;
}
)._each(iterator);
}
,set:function(className){
this.element.className = className;
}
,add:function(classNameToAdd){
if (this.include(classNameToAdd)) return;
this.set($A(this).concat(classNameToAdd).join(' '));
}
,remove:function(classNameToRemove){
if (!this.include(classNameToRemove)) return;
this.set($A(this).without(classNameToRemove).join(' '));
}
,toString:function(){
return $A(this).join(' ');
}
}
;
Object.extend(Element.ClassNames.prototype,Enumerable);
var Selector = Class.create();
Selector.prototype ={
initialize:function(expression){
this.params ={
classNames:[]}
;
this.expression = expression.toString().strip();
this.parseExpression();
this.compileMatcher();
}
,parseExpression:function(){
function abort(message){
throw 'Parse error in selector:' + message;
}
if (this.expression == '') abort('empty expression');
var params = this.params,expr = this.expression,match,modifier,clause,rest;
while (match = expr.match(/^(.*)\[([a-z0-9_:-]+?)(?:([~\|!]?=)(?:"([^"]*)"|([^\]\s]*)))?\]$/i)){
params.attributes = params.attributes || [];
params.attributes.push({
name:match[2],operator:match[3],value:match[4] || match[5] || ''}
);
expr = match[1];
}
if (expr == '*') return this.params.wildcard = true;
while (match = expr.match(/^([^a-z0-9_-])?([a-z0-9_-]+)(.*)/i)){
modifier = match[1],clause = match[2],rest = match[3];
switch (modifier){
case '#':params.id = clause;
break;
case '.':params.classNames.push(clause);
break;
case '':case undefined:params.tagName = clause.toUpperCase();
break;
default:abort(expr.inspect());
}
expr = rest;
}
if (expr.length > 0) abort(expr.inspect());
}
,buildMatchExpression:function(){
var params = this.params,conditions = [],clause;
if (params.wildcard) conditions.push('true');
if (clause = params.id) conditions.push('element.readAttribute("id") == ' + clause.inspect());
if (clause = params.tagName) conditions.push('element.tagName.toUpperCase() == ' + clause.inspect());
if ((clause = params.classNames).length > 0) for (var i = 0,length = clause.length;
i < length;
i++) conditions.push('element.hasClassName(' + clause[i].inspect() + ')');
if (clause = params.attributes){
clause.each(function(attribute){
var value = 'element.readAttribute(' + attribute.name.inspect() + ')';
var splitValueBy = function(delimiter){
return value + ' && ' + value + '.split(' + delimiter.inspect() + ')';
}
switch (attribute.operator){
case '=':conditions.push(value + ' == ' + attribute.value.inspect());
break;
case '~=':conditions.push(splitValueBy(' ') + '.include(' + attribute.value.inspect() + ')');
break;
case '|=':conditions.push( splitValueBy('-') + '.first().toUpperCase() == ' + attribute.value.toUpperCase().inspect() );
break;
case '!=':conditions.push(value + ' != ' + attribute.value.inspect());
break;
case '':case undefined:conditions.push('element.hasAttribute(' + attribute.name.inspect() + ')');
break;
default:throw 'Unknown operator ' + attribute.operator + ' in selector';
}
}
);
}
return conditions.join(' && ');
}
,compileMatcher:function(){
this.match = new Function('element','if (!element.tagName) return false;
\ element = $(element);
\ return ' + this.buildMatchExpression());
}
,findElements:function(scope){
var element;
if (element = $(this.params.id)) if (this.match(element)) if (!scope || Element.childOf(element,scope)) return [element];
scope = (scope || document).getElementsByTagName(this.params.tagName || '*');
var results = [];
for (var i = 0,length = scope.length;
i < length;
i++) if (this.match(element = scope[i])) results.push(Element.extend(element));
return results;
}
,toString:function(){
return this.expression;
}
}
Object.extend(Selector,{
matchElements:function(elements,expression){
var selector = new Selector(expression);
return elements.select(selector.match.bind(selector)).map(Element.extend);
}
,findElement:function(elements,expression,index){
if (typeof expression == 'number') index = expression,expression = false;
return Selector.matchElements(elements,expression || '*')[index || 0];
}
,findChildElements:function(element,expressions){
return expressions.map(function(expression){
return expression.match(/[^\s"]+(?:"[^"]*"[^\s"]+)*/
g).inject([null],function(results,expr){
var selector = new Selector(expr);
return results.inject([],function(elements,result){
return elements.concat(selector.findElements(result || element));
}
);
}
);
}
).flatten();
}
}
);
function $$(){
return Selector.findChildElements(document,$A(arguments));
}
var Form ={
reset:function(form){
$(form).reset();
return form;
}
,serializeElements:function(elements,getHash){
var data = elements.inject({
}
,function(result,element){
if (!element.disabled && element.name){
var key = element.name,value = $(element).getValue();
if (value != undefined){
if (result[key]){
if (result[key].constructor != Array) result[key] = [result[key]];
result[key].push(value);
}
else result[key] = value;
}
}
return result;
}
);
return getHash ? data:Hash.toQueryString(data);
}
}
;
Form.Methods ={
serialize:function(form,getHash){
return Form.serializeElements(Form.getElements(form),getHash);
}
,getElements:function(form){
return $A($(form).getElementsByTagName('*')).inject([],function(elements,child){
if (Form.Element.Serializers[child.tagName.toLowerCase()]) elements.push(Element.extend(child));
return elements;
}
);
}
,getInputs:function(form,typeName,name){
form = $(form);
var inputs = form.getElementsByTagName('input');
if (!typeName && !name) return $A(inputs).map(Element.extend);
for (var i = 0,matchingInputs = [],length = inputs.length;
i < length;
i++){
var input = inputs[i];
if ((typeName && input.type != typeName) || (name && input.name != name)) continue;
matchingInputs.push(Element.extend(input));
}
return matchingInputs;
}
,disable:function(form){
form = $(form);
form.getElements().each(function(element){
element.blur();
element.disabled = 'true';
}
);
return form;
}
,enable:function(form){
form = $(form);
form.getElements().each(function(element){
element.disabled = '';
}
);
return form;
}
,findFirstElement:function(form){
return $(form).getElements().find(function(element){
return element.type != 'hidden' && !element.disabled && ['input','select','textarea'].include(element.tagName.toLowerCase());
}
);
}
,focusFirstElement:function(form){
form = $(form);
form.findFirstElement().activate();
return form;
}
}
Object.extend(Form,Form.Methods);
/*--------------------------------------------------------------------------*/
Form.Element ={
focus:function(element){
$(element).focus();
return element;
}
,select:function(element){
$(element).select();
return element;
}
}
Form.Element.Methods ={
serialize:function(element){
element = $(element);
if (!element.disabled && element.name){
var value = element.getValue();
if (value != undefined){
var pair ={
}
;
pair[element.name] = value;
return Hash.toQueryString(pair);
}
}
return '';
}
,getValue:function(element){
element = $(element);
var method = element.tagName.toLowerCase();
return Form.Element.Serializers[method](element);
}
,clear:function(element){
$(element).value = '';
return element;
}
,present:function(element){
return $(element).value != '';
}
,activate:function(element){
element = $(element);
element.focus();
if (element.select && ( element.tagName.toLowerCase() != 'input' || !['button','reset','submit'].include(element.type) ) ) element.select();
return element;
}
,disable:function(element){
element = $(element);
element.disabled = true;
return element;
}
,enable:function(element){
element = $(element);
element.blur();
element.disabled = false;
return element;
}
}
Object.extend(Form.Element,Form.Element.Methods);
var Field = Form.Element;
var $F = Form.Element.getValue;
/*--------------------------------------------------------------------------*/
Form.Element.Serializers ={
input:function(element){
switch (element.type.toLowerCase()){
case 'checkbox':case 'radio':return Form.Element.Serializers.inputSelector(element);
default:return Form.Element.Serializers.textarea(element);
}
}
,inputSelector:function(element){
return element.checked ? element.value:null;
}
,textarea:function(element){
return element.value;
}
,select:function(element){
return this[element.type == 'select-one' ? 'selectOne':'selectMany'](element);
}
,selectOne:function(element){
var index = element.selectedIndex;
return index >= 0 ? this.optionValue(element.options[index]):null;
}
,selectMany:function(element){
var values,length = element.length;
if (!length) return null;
for (var i = 0,values = [];
i < length;
i++){
var opt = element.options[i];
if (opt.selected) values.push(this.optionValue(opt));
}
return values;
}
,optionValue:function(opt){
// extend element because hasAttribute may not be native return Element.extend(opt).hasAttribute('value') ? opt.value:opt.text;
}
}
/*--------------------------------------------------------------------------*/
Abstract.TimedObserver = function(){
}
Abstract.TimedObserver.prototype ={
initialize:function(element,frequency,callback){
this.frequency = frequency;
this.element = $(element);
this.callback = callback;
this.lastValue = this.getValue();
this.registerCallback();
}
,registerCallback:function(){
setInterval(this.onTimerEvent.bind(this),this.frequency * 1000);
}
,onTimerEvent:function(){
var value = this.getValue();
var changed = ('string' == typeof this.lastValue && 'string' == typeof value ? this.lastValue != value:String(this.lastValue) != String(value));
if (changed){
this.callback(this.element,value);
this.lastValue = value;
}
}
}
Form.Element.Observer = Class.create();
Form.Element.Observer.prototype = Object.extend(new Abstract.TimedObserver(),{
getValue:function(){
return Form.Element.getValue(this.element);
}
}
);
Form.Observer = Class.create();
Form.Observer.prototype = Object.extend(new Abstract.TimedObserver(),{
getValue:function(){
return Form.serialize(this.element);
}
}
);
/*--------------------------------------------------------------------------*/
Abstract.EventObserver = function(){
}
Abstract.EventObserver.prototype ={
initialize:function(element,callback){
this.element = $(element);
this.callback = callback;
this.lastValue = this.getValue();
if (this.element.tagName.toLowerCase() == 'form') this.registerFormCallbacks();
else this.registerCallback(this.element);
}
,onElementEvent:function(){
var value = this.getValue();
if (this.lastValue != value){
this.callback(this.element,value);
this.lastValue = value;
}
}
,registerFormCallbacks:function(){
Form.getElements(this.element).each(this.registerCallback.bind(this));
}
,registerCallback:function(element){
if (element.type){
switch (element.type.toLowerCase()){
case 'checkbox':case 'radio':Event.observe(element,'click',this.onElementEvent.bind(this));
break;
default:Event.observe(element,'change',this.onElementEvent.bind(this));
break;
}
}
}
}
Form.Element.EventObserver = Class.create();
Form.Element.EventObserver.prototype = Object.extend(new Abstract.EventObserver(),{
getValue:function(){
return Form.Element.getValue(this.element);
}
}
);
Form.EventObserver = Class.create();
Form.EventObserver.prototype = Object.extend(new Abstract.EventObserver(),{
getValue:function(){
return Form.serialize(this.element);
}
}
);
if (!window.Event){
var Event = new Object();
}
Object.extend(Event,{
KEY_BACKSPACE:8,KEY_TAB:9,KEY_RETURN:13,KEY_ESC:27,KEY_LEFT:37,KEY_UP:38,KEY_RIGHT:39,KEY_DOWN:40,KEY_DELETE:46,KEY_HOME:36,KEY_END:35,KEY_PAGEUP:33,KEY_PAGEDOWN:34,element:function(event){
return event.target || event.srcElement;
}
,isLeftClick:function(event){
return (((event.which) && (event.which == 1)) || ((event.button) && (event.button == 1)));
}
,pointerX:function(event){
return event.pageX || (event.clientX + (document.documentElement.scrollLeft || document.body.scrollLeft));
}
,pointerY:function(event){
return event.pageY || (event.clientY + (document.documentElement.scrollTop || document.body.scrollTop));
}
,stop:function(event){
if (event.preventDefault){
event.preventDefault();
event.stopPropagation();
}
else{
event.returnValue = false;
event.cancelBubble = true;
}
}
,// find the first node with the given tagName,starting from the // node the event was triggered on;
traverses the DOM upwards findElement:function(event,tagName){
var element = Event.element(event);
while (element.parentNode && (!element.tagName || (element.tagName.toUpperCase() != tagName.toUpperCase()))) element = element.parentNode;
return element;
}
,observers:false,_observeAndCache:function(element,name,observer,useCapture){
if (!this.observers) this.observers = [];
if (element.addEventListener){
this.observers.push([element,name,observer,useCapture]);
element.addEventListener(name,observer,useCapture);
}
else if (element.attachEvent){
this.observers.push([element,name,observer,useCapture]);
element.attachEvent('on' + name,observer);
}
}
,unloadCache:function(){
if (!Event.observers) return;
for (var i = 0,length = Event.observers.length;
i < length;
i++){
Event.stopObserving.apply(this,Event.observers[i]);
Event.observers[i][0] = null;
}
Event.observers = false;
}
,observe:function(element,name,observer,useCapture){
element = $(element);
useCapture = useCapture || false;
if (name == 'keypress' && (navigator.appVersion.match(/Konqueror|Safari|KHTML/) || element.attachEvent)) name = 'keydown';
Event._observeAndCache(element,name,observer,useCapture);
}
,stopObserving:function(element,name,observer,useCapture){
element = $(element);
useCapture = useCapture || false;
if (name == 'keypress' && (navigator.appVersion.match(/Konqueror|Safari|KHTML/) || element.detachEvent)) name = 'keydown';
if (element.removeEventListener){
element.removeEventListener(name,observer,useCapture);
}
else if (element.detachEvent){
try{
element.detachEvent('on' + name,observer);
}
catch (e){
}
}
}
}
);
/* prevent memory leaks in IE */
if (navigator.appVersion.match(/\bMSIE\b/)) Event.observe(window,'unload',Event.unloadCache,false);
var Position ={
// set to true if needed,warning:firefox performance problems // NOT neeeded for page scrolling,only if draggable contained in // scrollable elements includeScrollOffsets:false,// must be called before calling withinIncludingScrolloffset,every time the // page is scrolled prepare:function(){
this.deltaX = window.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft || 0;
this.deltaY = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop || 0;
}
,realOffset:function(element){
var valueT = 0,valueL = 0;
do{
valueT += element.scrollTop || 0;
valueL += element.scrollLeft || 0;
element = element.parentNode;
}
while (element);
return [valueL,valueT];
}
,cumulativeOffset:function(element){
var valueT = 0,valueL = 0;
do{
valueT += element.offsetTop || 0;
valueL += element.offsetLeft || 0;
element = element.offsetParent;
}
while (element);
return [valueL,valueT];
}
,positionedOffset:function(element){
var valueT = 0,valueL = 0;
do{
valueT += element.offsetTop || 0;
valueL += element.offsetLeft || 0;
element = element.offsetParent;
if (element){
if(element.tagName=='BODY') break;
var p = Element.getStyle(element,'position');
if (p == 'relative' || p == 'absolute') break;
}
}
while (element);
return [valueL,valueT];
}
,offsetParent:function(element){
if (element.offsetParent) return element.offsetParent;
if (element == document.body) return element;
while ((element = element.parentNode) && element != document.body) if (Element.getStyle(element,'position') != 'static') return element;
return document.body;
}
,// caches x/y coordinate pair to use with overlap within:function(element,x,y){
if (this.includeScrollOffsets) return this.withinIncludingScrolloffsets(element,x,y);
this.xcomp = x;
this.ycomp = y;
this.offset = this.cumulativeOffset(element);
return (y >= this.offset[1] && y < this.offset[1] + element.offsetHeight && x >= this.offset[0] && x < this.offset[0] + element.offsetWidth);
}
,withinIncludingScrolloffsets:function(element,x,y){
var offsetcache = this.realOffset(element);
this.xcomp = x + offsetcache[0] - this.deltaX;
this.ycomp = y + offsetcache[1] - this.deltaY;
this.offset = this.cumulativeOffset(element);
return (this.ycomp >= this.offset[1] && this.ycomp < this.offset[1] + element.offsetHeight && this.xcomp >= this.offset[0] && this.xcomp < this.offset[0] + element.offsetWidth);
}
,// within must be called directly before overlap:function(mode,element){
if (!mode) return 0;
if (mode == 'vertical') return ((this.offset[1] + element.offsetHeight) - this.ycomp) / element.offsetHeight;
if (mode == 'horizontal') return ((this.offset[0] + element.offsetWidth) - this.xcomp) / element.offsetWidth;
}
,page:function(forElement){
var valueT = 0,valueL = 0;
var element = forElement;
do{
valueT += element.offsetTop || 0;
valueL += element.offsetLeft || 0;
// Safari fix if (element.offsetParent==document.body) if (Element.getStyle(element,'position')=='absolute') break;
}
while (element = element.offsetParent);
element = forElement;
do{
if (!window.opera || element.tagName=='BODY'){
valueT -= element.scrollTop || 0;
valueL -= element.scrollLeft || 0;
}
}
while (element = element.parentNode);
return [valueL,valueT];
}
,clone:function(source,target){
var options = Object.extend({
setLeft:true,setTop:true,setWidth:true,setHeight:true,offsetTop:0,offsetLeft:0}
,arguments[2] ||{
}
) // find page position of source source = $(source);
var p = Position.page(source);
// find coordinate system to use target = $(target);
var delta = [0,0];
var parent = null;
// delta [0,0] will do fine with position:fixed elements,// position:absolute needs offsetParent deltas if (Element.getStyle(target,'position') == 'absolute'){
parent = Position.offsetParent(target);
delta = Position.page(parent);
}
// correct by body offsets (fixes Safari) if (parent == document.body){
delta[0] -= document.body.offsetLeft;
delta[1] -= document.body.offsetTop;
}
// set position if(options.setLeft) target.style.left = (p[0] - delta[0] + options.offsetLeft) + 'px';
if(options.setTop) target.style.top = (p[1] - delta[1] + options.offsetTop) + 'px';
if(options.setWidth) target.style.width = source.offsetWidth + 'px';
if(options.setHeight) target.style.height = source.offsetHeight + 'px';
}
,absolutize:function(element){
element = $(element);
if (element.style.position == 'absolute') return;
Position.prepare();
var offsets = Position.positionedOffset(element);
var top = offsets[1];
var left = offsets[0];
var width = element.clientWidth;
var height = element.clientHeight;
element._originalLeft = left - parseFloat(element.style.left || 0);
element._originalTop = top - parseFloat(element.style.top || 0);
element._originalWidth = element.style.width;
element._originalHeight = element.style.height;
element.style.position = 'absolute';
element.style.top = top + 'px';
element.style.left = left + 'px';
element.style.width = width + 'px';
element.style.height = height + 'px';
}
,relativize:function(element){
element = $(element);
if (element.style.position == 'relative') return;
Position.prepare();
element.style.position = 'relative';
var top = parseFloat(element.style.top || 0) - (element._originalTop || 0);
var left = parseFloat(element.style.left || 0) - (element._originalLeft || 0);
element.style.top = top + 'px';
element.style.left = left + 'px';
element.style.height = element._originalHeight;
element.style.width = element._originalWidth;
}
}
// Safari returns margins on body which is incorrect if the child is absolutely// positioned. For performance reasons,redefine Position.cumulativeOffset for// KHTML/WebKit only.if (/Konqueror|Safari|KHTML/.test(navigator.userAgent)){
Position.cumulativeOffset = function(element){
var valueT = 0,valueL = 0;
do{
valueT += element.offsetTop || 0;
valueL += element.offsetLeft || 0;
if (element.offsetParent == document.body) if (Element.getStyle(element,'position') == 'absolute') break;
element = element.offsetParent;
}
while (element);
return [valueL,valueT];
}
}
Element.addMethods();
JS代码(side-bar.js):
var isExtended = 0;
function slideSideBar(){
new Effect.toggle('sideBarContents','blind',{
scaleX:'true',scaleY:'true;
',scaleContent:false}
);
if(isExtended==0){
$('sideBarTab').childNodes[0].src = $('sideBarTab').childNodes[0].src.replace(/(\.[^.]+)$/,'-active$1');
new Effect.Fade('sideBarContents',{
duration:1.0,from:0.0,to:1.0}
);
isExtended++;
}
else{
$('sideBarTab').childNodes[0].src = $('sideBarTab').childNodes[0].src.replace(/-active(\.[^.]+)$/,'$1');
new Effect.Fade('sideBarContents',{
duration:1.0,from:1.0,to:0.0}
);
isExtended=0;
}
}
function init(){
Event.observe('sideBarTab','click',slideSideBar,true);
}
Event.observe(window,'load',init,true);