// -------------------------------------------------------------------- // Author : mashimonator // Create : 2009/02/26 // Update : 2009/02/26 // : 2009/10/19 JQueryを使用しない形式に修正 // : 2009/10/20 アコーディオンの表示形式(uniqueOpen)を切り替え可能に修正 // : 2010/10/11 IE6,7での不具合を修正 // : 2010/10/11 ロールオーバー時の画像名やクラス名の制御を削除(他jsとの競合の可能性があるため) // : 2010/10/11 アコーディオンの表示形式(uniqueOpen)を切り替え不可に修正(後で対応) // Description : アコーディオンメニューを実装する // -------------------------------------------------------------------- /*@cc_on var doc = document; eval('var document = doc'); @*/ var accordion = { //----------------------------------------- // 設定値 //----------------------------------------- config : { targetClass : 'accordion', // 対象とするクラス名 defaultOpen : 'accordionOpen', // 初期オープン状態に指定するクラス名 speed : 10, // スクロールの速度 slickness : 8, // スクロールの滑らかさ activePrefix : '_a', // アクティブ時に画像に付加されるprefix activeClass : 'accordionActive' // アクティブ時にdtに付加されるクラス名 }, //----------------------------------------- // 初期処理 //----------------------------------------- initialize : function() { var elements = accordion.getElementsByClassName(accordion.config.targetClass); for (var i = 0, len = elements.length; i < len; i++) { var dt = elements[i].getElementsByTagName('dt'); for (var x = 0, len2 = dt.length; x < len2; x++) { dt[x].id = 'accordionheader-' + i + '-' + x; dt[x].style.cursor = 'pointer'; var child = accordion.getChild(dt[x]); child.accordionId = i + '-' + x; if ( child.nodeName == 'IMG' ) { var src_a = child.src.replace(/(\.gif|\.jpg|\.png)$/, accordion.config.activePrefix + "$1"); accordion.preLoadImage(src_a); child.neutralmage = child.src; child.activeImage = src_a; } var dd = accordion.nextSibling(dt[x]); if ( dd.className && dd.className.match(accordion.config.defaultOpen) ) { child.accordionState = true; accordion.active(dt[x]); dd.style.height = 'auto'; dd.style.display = 'block'; dd.style.overflow = 'hidden'; } else { child.accordionState = false; dd.style.height = '0px'; dd.style.display = 'block'; dd.style.overflow = 'hidden'; } accordion.addEvent( child, 'click', accordion.click ); } } }, //----------------------------------------- // click //----------------------------------------- click : function() { if ( this.accordionState ) { if ( this.nodeName == 'IMG' ) { this.src = this.nonactiveImage; } accordion.slideUp(this.accordionId); this.accordionState = false; } else { if ( this.nodeName == 'IMG' ) { this.src = this.activeImage; } accordion.slideDown(this.accordionId); this.accordionState = true; } }, //----------------------------------------- // slideDown //----------------------------------------- slideDown : function( id ) { var h = document.getElementById('accordionheader-' + id); var c = accordion.nextSibling(h); clearInterval(c.timer); if ( !c.maxh ) { c.style.height = 'auto'; c.maxh = c.offsetHeight; c.style.height = '0px'; } accordion.active(h); c.timer = setInterval( function(){accordion.slide(c,1)}, accordion.config.speed ); }, //----------------------------------------- // slideUp //----------------------------------------- slideUp : function( id ) { var h = document.getElementById('accordionheader-' + id); var c = accordion.nextSibling(h); clearInterval(c.timer); accordion.neutral(h); c.timer = setInterval( function(){accordion.slide(c,-1)}, accordion.config.speed ); }, //----------------------------------------- // slide //----------------------------------------- slide : function( c, d ) { var currh = c.offsetHeight; var dist; if ( d == 1 ) { dist = (Math.round((c.maxh - currh) / accordion.config.slickness)); } else { dist = (Math.round(currh / accordion.config.slickness)); } if ( dist <= 1 && d == 1 ) { dist = 1; } c.style.height = currh + dist * d + 'px'; if ( d == -1 && ((currh + dist * d) >= currh) ) { c.style.height = '0px'; } if ( (currh < 2 && d != 1) || (currh > (c.maxh - 2) && d == 1) ) { clearInterval(c.timer); } }, //----------------------------------------- // active //----------------------------------------- active : function( dt ) { var child = accordion.getChild(dt); if ( child.nodeName == 'IMG' ) { child.src = child.activeImage; } dt.className += ' ' + accordion.config.activeClass; }, //----------------------------------------- // neutral //----------------------------------------- neutral : function( dt ) { var child = accordion.getChild(dt); if ( child.nodeName == 'IMG' ) { child.src = child.neutralmage; } dt.className = dt.className.replace(accordion.config.activeClass, ''); }, //----------------------------------------- // 対象要素の子要素を返す //----------------------------------------- getChild : function( element ) { if ( element ) { var img = element.getElementsByTagName('IMG'); if ( img[0] ) { return img[0]; } else { var elements = element.childNodes; var result = false; for (var i = 0, len = elements.length; i < len; i++) { if ( elements[i].nodeType == '1' ) { result = elements[i]; break; } } if ( result == false ) { return element; } else { return result; } } } }, //----------------------------------------- // 画像の先読み //----------------------------------------- preLoadImage : function( src ) { var d = document; d.preLoad = new Image(); d.preLoad.src = src; }, //----------------------------------------- // nextSiblingをエミュレートする //----------------------------------------- nextSibling : function( element ) { for ( var node = element.nextSibling; node; node = node.nextSibling ) { if ( node.nodeType == '1' ) { return node; } } }, //----------------------------------------- // getElementsByClassNameをエミュレートする //----------------------------------------- getElementsByClassName : function( cls ) { var elements = new Array(); if ( document.evaluate ) { var xpathExpression = '/descendant::*[contains(@class,"'+ cls + '")]'; var iterator = document.evaluate(xpathExpression, document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null); for (var i = 0, len = iterator.snapshotLength; i < len; i++) { var elm = iterator.snapshotItem(i); elements[elements.length] = elm; } } else { var nodes = document.all ? document.all : document.getElementsByTagName('*'); for (var i = 0, len = nodes.length; i < len; i++) { var elm = nodes.item(i); if ( elm.className.match(cls) ) { elements[elements.length] = elm; } } } return elements; }, //----------------------------------------- // イベントに関数を付加する //----------------------------------------- addEvent : function( target, event, func ) { try { target.addEventListener(event, func, false); } catch (e) { target.attachEvent('on' + event, (function(el){return function(){func.call(el);};})(target)); } } } // Loadが終わるまで非表示にする // ---------------------------------------- document.write(''); // ---------------------------------------- // 実行 accordion.addEvent( window, 'load', accordion.initialize );