【JQuery】エクスプローラーのようなフォルダーツリーを作ってみる(その1)

Javascript,開発

おはようございます。

今日は実家に行って、庭に設置する柵を作る予定です。

最近私もDIY(たいしたものじゃないですが)にハマっているのですが、
とうとう、ホームセンターで木材まで購入して、本格的な感じでやるので楽しみです。

うまくできるだろうか。

さて本題。

約1ヶ月ぶりの JQuery ネタです。

今回は、JQuery(スタイルはBootstrap、Fontawesome を使いました)で、エクスプローラーのようなツリーを作成してみました。

なんだかんだみんな Windows 好きですよね。

スポンサーリンク

画面

基本的に、div要素をリスト(ul,li)に入れて表現しました。

css

style.css

@charset "UTF-8";

body
{
	font-family:Helvetica, 'Helvetica Neue', 'Mplus 1p', 'Hiragino Kaku Gothic Pro', 'ヒラギノ角ゴ Pro W3', Meiryo, メイリオ, Osaka, 'MS PGothic' !important;
	font-size:12px;
}

h1,h2,h3,h4,h5,h6,.h1,.h2,.h3,.h4,.h5,.h6
{
	font-family:Helvetica, 'Helvetica Neue', 'Mplus 1p', 'Hiragino Kaku Gothic Pro', 'ヒラギノ角ゴ Pro W3', Meiryo, メイリオ, Osaka, 'MS PGothic' !important;
}

/**
 * アイコン
 */
.tree i.fas,
.tree i.far,
.tree i.fa
{
	font-size: 16px;
	margin-right: 5px;
}

.tree i.fa-none
{
	margin-right: 20px;
}

.tree i.fa-angle-down 
{
	margin-right: 7px;
}

.tree i.fa-angle-right 
{
	margin-right: 9px;
}
.tree i.fa-folder-open 
{
	margin-right: 2px;
}

/**
 * ツリー
 */

.tree {
	margin: 0;
	padding: 5px 0px 0px 0px;
	list-style-type: none;
	cursor: pointer;
} 

.tree div {
	padding: 5px 0px;
}

.tree div span {
	-webkit-user-select: none;
	-moz-user-select: none;
	-ms-user-select: none;
	user-select: none;
}
.tree li ul {
	list-style-type: none;
	margin: 0;
	padding: 0;
}

.tree div:hover,
.tree div:focus 
{
	background : #edf7fe;
}

.tree div.selected 
{
	background : #d0e8ff;
}

html

sampleTree.html

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ja" lang="ja">
<head>
	<meta charset="utf-8">
	<meta http-equiv="X-UA-Compatible" content="IE=edge">
	<meta http-equiv="content-type" content="text/html; charset=UTF-8">
	<title>サンプルツリー</title>
	<meta content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" name="viewport">
	<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" />
	<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.6.1/css/all.css">
	<link rel="stylesheet" href="css/style.css">
</head>
<body class="hold-transition fixed skin-blue-light sidebar-mini ">
<div class="wrapper" >
<div style="margin: 20px;">
<pre>
ツリーのサンプル

矢印をシングルクリックでフォルダの開閉、その他の部分はダブルクリックで開閉します。
</pre>
</div>
	<div>
		<ul class="tree" data-widget="tree">
			<li>
				<div>
					<span><i class="fa-none"></i></span>
					<span class="tree-icon-arrow"><i class="fas fa-angle-right"></i></span>
					<span class="tree-icon-folder"><i class="far fa-folder"></i></span>
					<span class="tree-title">フォルダー1</span>
				</div>
				<ul style="display:none;">
					<li>
						<div class="selected">
							<span><i class="fa-none"></i></span>
							<span><i class="fa-none"></i></span>
							<span class="tree-icon-arrow"><i class="fa-none"></i></span>
							<span class="tree-icon-folder"><i class="far fa-folder"></i></span>
							<span class="tree-title">サブフォルダー1-1</span>
						</div>
					</li>
					<li>
						<div>
							<span><i class="fa-none"></i></span>
							<span><i class="fa-none"></i></span>
							<span class="tree-icon-arrow"><i class="fas fa-angle-right"></i></span>
							<span class="tree-icon-folder"><i class="far fa-folder"></i></span>
							<span class="tree-title">サブフォルダー1-2</span>
						</div>
						<ul style="display:none;">
							<li>
								<div class="selected">
									<span><i class="fa-none"></i></span>
									<span><i class="fa-none"></i></span>
									<span><i class="fa-none"></i></span>
									<span class="tree-icon-arrow"><i class="fa-none"></i></span>
									<span class="tree-icon-folder"><i class="far fa-folder"></i></span>
									<span class="tree-title">サブフォルダー1-2-1</span>
								</div>
							</li>
							<li>
								<div>
									<span><i class="fa-none"></i></span>
									<span><i class="fa-none"></i></span>
									<span><i class="fa-none"></i></span>
									<span class="tree-icon-arrow"><i class="fa-none"></i></span>
									<span class="tree-icon-folder"><i class="far fa-folder"></i></span>
									<span class="tree-title">サブフォルダー1-2-2</span>
								</div>
							</li>
						</ul>
					</li>
				</ul>
			</li>
			<li>
				<div>
					<span><i class="fa-none"></i></span>
					<span class="tree-icon-arrow"><i class="fas fa-angle-right"></i></span>
					<span class="tree-icon-folder"><i class="far fa-folder"></i></span>
					<span class="tree-title">フォルダー2</span>
				</div>
				<ul style="display:none;">
					<li>
						<div class="selected">
							<span><i class="fa-none"></i></span>
							<span><i class="fa-none"></i></span>
							<span class="tree-icon-arrow"><i class="fa-none"></i></span>
							<span class="tree-icon-folder"><i class="far fa-folder"></i></span>
							<span class="tree-title">サブフォルダー2-1</span>
						</div>
					</li>
					<li>
						<div>
							<span><i class="fa-none"></i></span>
							<span><i class="fa-none"></i></span>
							<span class="tree-icon-arrow"><i class="fa-none"></i></span>
							<span class="tree-icon-folder"><i class="far fa-folder"></i></span>
							<span class="tree-title">サブフォルダー2-2</span>
						</div>
					</li>
					<li>
						<div>
							<span><i class="fa-none"></i></span>
							<span><i class="fa-none"></i></span>
							<span class="tree-icon-arrow"><i class="fa-none"></i></span>
							<span class="tree-icon-folder"><i class="far fa-folder"></i></span>
							<span class="tree-title">サブフォルダー2-3</span>
						</div>
					</li>
					<li>
						<div>
							<span><i class="fa-none"></i></span>
							<span><i class="fa-none"></i></span>
							<span class="tree-icon-arrow"><i class="fa-none"></i></span>
							<span class="tree-icon-folder"><i class="far fa-folder"></i></span>
							<span class="tree-title">サブフォルダー2-4</span>
						</div>
					</li>
				</ul>
			</li>
			<li>
				<div>
					<span><i class="fa-none"></i></span>
					<span class="tree-icon-arrow"><i class="fa-none"></i></span>
					<span class="tree-icon-folder"><i class="far fa-folder"></i></span>
					<span class="tree-title">フォルダー3</span>
				</div>
			</li>
			<li>
				<div>
					<span><i class="fa-none"></i></span>
					<span class="tree-icon-arrow"><i class="fa-none"></i></span>
					<span class="tree-icon-folder"><i class="far fa-folder"></i></span>
					<span class="tree-title">フォルダー4</span>
				</div>
			</li>
		</ul>
	
	</div>
</div>
<script src="https://code.jquery.com/jquery-3.4.1.min.js" integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo=" crossorigin="anonymous"></script>
<script src="js/sampleTree.js"></script>
</body>
</html>

スクリプト

javascript

sampleTree.js

/**
 * ページ読み込み時の処理
 */
$(function(){

	// シングルクリックで選択状態の切替
	$(".tree div").on("click", function(event) {
		$(".tree div").removeClass("selected");
		$(this).addClass("selected");
	});
	$(".tree .tree-icon-folder, .tree .tree-title").on("click", function(event) {
		var parent = $(this).parent("div");
		$(".tree div").removeClass("selected");
		$(parent).addClass("selected");
		event.stopPropagation();
	});
	
	// ダブルクリックでツリーを展開
	$(".tree div").on("dblclick", function(event) {
		treeClick($(this));
	});
	$(".tree .tree-icon-folder, .tree .tree-title").on("dblclick", function(event) {
		var parent = $(this).parent("div");
		treeClick($(parent));
		event.stopPropagation();
	});
	
	// 矢印はシングルクリックでツリーを展開
	$(".tree .tree-icon-arrow").on("click", function(event) {
		var parent = $(this).parent("div");
		treeClick($(parent));
		event.stopPropagation();
	})
});


/**
 * ツリークリックイベント
 */
function treeClick(div) {

	// サブフォルダがあれば開閉の処理をおこなう。
	if (($(div).next().length > 0)) {
		// 矢印アイコンの入れ替え
		var arrow = $(div).children(".tree-icon-arrow").children("i");
		$(arrow).toggleClass("fa-angle-right");
		$(arrow).toggleClass("fa-angle-down");
		
		// フォルダアイコンの入れ替え
		var folder = $(div).children(".tree-icon-folder").children("i");
		$(folder).toggleClass("fa-folder");
		$(folder).toggleClass("fa-folder-open");
	
		// ツリーの開閉
		$(div).next().slideToggle();
	}

	// 選択状態の変更
	$(".tree div").removeClass("selected");
	$(div).addClass("selected");
}

サンプルイメージ

初期表示

初期表示。矢印アイコンをシングルクリックか、アイコンやフォルダ名をダブルクリックで開閉します。

ツリーを展開

開閉したところ。

入れ子

全部展開しました。基本的に入れ子にすれば階層はどんどん増やしていけます。

また、アイコンも Fontawesome ではなく自前の icon に変更することもできますね。

まとめ

便利なJQueryプラグインもありますが、プラグインを使えない場合や、最小限のものだけ欲しいといった場合には自分で実装しますよね。

何だか面白くなってきたので、もうちょっと機能を追加していきたいと思います。

何かのお役に立てれば。

ではでは。

 

スポンサーリンク


関連するコンテンツ