タブ切り替えUIの実装 Tab

タブの切り替えを実装する方法をご紹介します。
あくまでここでご紹介するコードは一例です。

デモ

ボックス1

ボックス2

ボックス3

functionの定義とHTMLの準備

JavaScript

var tabNavigation = function() {
	this.init.apply(this, arguments);
};

tabNavigation.prototype = {

	settings : {},
	elements : {},

	init : function(settings) {
		var self = this;

		/**
		 * @property {string} boxElementIdName  : ナビゲーションとして実装する要素の親要素のID名
		 * @property {string} anchorElementName : ナビゲーションとして実装する要素の要素名
		 * @property {string} linkAttrName      : ナビゲーションとして実装する要素の属性名(切り替える要素のID名が格納されている属性名)
		 * @property {string} openClassName     : 表示時のCSSクラス名
		 * @property {number} defaultTargetId   : 初期時に表示するタブのインデックス番号
		 */
		settings = this.arrayMerge({
			boxElementIdName  : '',
			anchorElementName : 'a',
			linkAttrName      : 'href',
			openClassName     : 'open',
			defaultShowIndex  : 0
		}, settings);

		this.settings = settings;

		this.elements = {
			tabNaviBoxElement    : null,
			tabNaviAnchorElement : null
		};

		this.elements.tabNaviBoxElement = document.getElementById(settings.boxElementIdName);

		var tabNaviBoxElement     = this.elements.tabNaviBoxElement,
		    tabNaviAnchorElements = null,
		    attr                  = '';

		if (!tabNaviBoxElement) return this;

		this.elements.tabNaviAnchorElements = tabNaviBoxElement.getElementsByTagName(settings.anchorElementName);

		tabNaviAnchorElements = this.elements.tabNaviAnchorElements;

		if (this.elements.tabNaviAnchorElements) {
			var clickEvent = function(event) {
				self.changeElement(this.getAttribute(settings.linkAttrName));

				if (event.preventDefault) {
					event.preventDefault();
				} else {
					event.returnValue = false;
				}

				if (event.stopPropagation) {
					event.stopPropagation();
				} else {
					event.cancelBubble = true;
				}
			};

			var tabNaviAnchorElements = tabNaviBoxElement.getElementsByTagName(settings.anchorElementName);

			for (var i = 0, len = tabNaviAnchorElements.length; i < len; i++) {
				tabNaviAnchorElements[i].onclick = clickEvent;

				if (i !== settings.defaultShowIndex) continue;

				attr = tabNaviAnchorElements[i].getAttribute(settings.linkAttrName);
				this.changeElement(attr, true);
			}
		}

		return this;
	},

	changeElement : function(targetId, startFlag) {
		var attrHref      = '',
		    elements      = this.elements.tabNaviAnchorElements,
		    targetElement = null,
		    ii            = 0,
		    len2          = 0,
		    classNames    = '';

		if (typeof targetId !== 'string' || !targetId.match(/^#[A-Za-z]/)) return this;
		if (!elements) return this;

		for (var i = 0, len = elements.length; i < len; i++) {
			attrHref = elements[i].getAttribute(this.settings.linkAttrName);

			if (attrHref && attrHref !== '' && attrHref.match(/^#[A-Za-z]/)) {
				targetElement = document.getElementById(attrHref.replace('#', ''));

				if (attrHref === targetId) {
					if (elements[i].parentNode.className.indexOf(this.settings.openClassName) === -1) {
						targetElement.style.display    = 'block';
						targetElement.style.visibility = 'visible';

						this.addClass(elements[i].parentNode);
					}
				} else {
					if (startFlag || elements[i].parentNode.className.indexOf(this.settings.openClassName) !== -1) {
						targetElement.style.display    = 'none';
						targetElement.style.visibility = 'hidden';

						this.removeClass(elements[i].parentNode);
					}
				}
			}
		}

		return this;
	},

	addClass : function(obj) {
		if (!obj) return this;

		if (obj.className.indexOf(this.settings.openClassName) === -1) {
			if (obj.className !== '') {
				var classNames = obj.className.split(' ');
				var hasClassName = false;
				classNames.push(this.settings.openClassName);
				obj.className = classNames.join(' ');
			} else {
				obj.className = this.settings.openClassName;
			}
		}

		return this;
	},

	removeClass : function(obj) {
		if (!obj) return this;

		if (obj.className.indexOf(this.settings.openClassName) !== -1) {
			if (obj.className !== '') {
				var classNames = obj.className.split(' ');
				for (var i = 0, len = classNames.length; i < len; i++) {
					if (classNames[i] === this.settings.openClassName) {
						classNames.splice(i, 1);
					}
				}
				obj.className = classNames.join(' ');
				obj.className = obj.className.replace(this.settings.openClassName, '');
			}
			if (obj.className === '') {
				obj.removeAttribute('class');
			}
		}

		return this;
	},

	arrayMerge : function() {
		if (!arguments.length) return false;

		var key, result = {};

		for (var i = 0, len = arguments.length;i < len; i++) {
			if (arguments[i] && typeof arguments[i] === 'object') {
				for (key in arguments[i]) {
					if (isFinite(key)) {
						result.push(arguments[i][key]);
					} else {
						result[key] = arguments[i][key];
					}
				}
			}
		}

		return result;
	}
};

HTML

<ul id="tabs">
	<li><a href="#box1">tab1</a></li>
	<li><a href="#box2">tab2</a></li>
	<li><a href="#box3">tab3</a></li>
</ul>

<div id="box1">
	ボックス1
</div>

<div id="box2">
	ボックス2
</div>

<div id="box3">
	ボックス3
</div>

使い方

構文

var instance = new tabNavigation(options);

引数

引数名 説明
第一引数
必須
options object 各種オプション
オプションを参照

オプション

プロパティ 初期値 説明
boxElementIdName '' ナビゲーションとして実装する要素の親要素のID名(必須)
anchorElementName 'a' ナビゲーションとして実装する要素の要素名
linkAttrName 'href' ナビゲーションとして実装する要素の属性名(切り替える要素のID名が格納されている属性名)
openClassName 'open' 表示時のCSSクラス名
defaultShowIndex 0 初期時に表示するタブのインデックス番号

JavaScript

new tabNavigation({
	boxElementIdName : 'tabs'
});

JavaScript逆引きリファレンス一覧へ戻る