Tag Archives: Javascript

[CSS, jQuery]クリックされたボタンの色を変更したり文字を書き換えたりする

Share on Facebook
Bookmark this on Delicious
LINEで送る
Pocket

ボタンをクリックした際にクリック済みを表すクラスを付ける場合は jQuery の addClass() や toggleClass() を使用すれば簡単です。
toggleClass() はクリックするごとにつけたり外したり出来ます。

<script>
$(function(){
    $('.btn').on('click', function(){
        $(this).toggleClass('active');
    });
});
</script>

これでクラス名「btn」を持つ要素をクリックした際、その要素に「active」というクラスが追加されます。
クリック済みの要素の色を変えるだけなら「.btn.active」に対して CSS を書くだけで終わりです。
しかし、クリックしたらボタンの文字を書き換えたい場合、更に一工夫必要です。

click-done

javascript を使って書き換えてしまうなら jQuery の html() で変更できます。
data属性を使ってデフォルトの文字「data-text-default」、クリック後の文字「data-text-clicked」を持たせて、ボタンの状態に応じてテキストを書き換えます。
hasClass() を使うとクラス active を持っているかどうかを簡単に確認できます。

<a class="btn" data-text-default="Click" data-text-clicked="Done" href="#">Click</a>
$(function(){
    $('.btn').on('click', function(){
        $(this).toggleClass('active');

        if($(this).hasClass('active')){
            var text = $(this).data('text-clicked');
        } else {
            var text = $(this).data('text-default');
        }
    });
});

変更後の文字が単純な場合や、javascript を自由に書き換えられる状態ならこれでも良いのですが、そうでない場合は CSS で切り替えを表現します。

Demo

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>CSS</title>
        <script src="https://code.jquery.com/jquery-1.12.4.min.js"
            integrity="sha256-ZosEbRLbNQzLpnKIkEdrPv7lOy9C27hHQ+Xp8a4MxAQ="
            crossorigin="anonymous"></script>

        <style>
        .btn
        {
            display: block;
            width: 96px;
            height: 32px;
            line-height: 32px;
            background-color: #3692ff;
            color: #fff;
            text-align: center;
        }

        .btn.active {
            background-color: #ccc;
        }

        .btn > span:last-of-type,
        .btn.active > span:first-of-type
        {
            display: none;
        }

        .btn.active > span:last-of-type {
            display: inline;
        }
        </style>

        <script>
        $(function(){
            $('.btn').on('click', function(){
                $(this).toggleClass('active');
            });
        });
        </script>
    </head>
    <body>
        <a class="btn" href="javascript:void(0)">
            <span>Click</span>
            <span>Done</span>
        </a>
    </body>
</html>

ボタン要素 <a> 内にある2つの span のうち、最初のものがデフォルトに表示され、2番めがクリック後に表示されます。
必要に応じて <span> 内で <img> などを使っても構いません。
クラス active がつけられると、最初の span が非表示にされ、2番めの span が表示されます。
CSS はやや複雑ですが、Javascript 部分はクラスをつける処理だけあればいいので簡潔に出来ます。

Posted in JavaScript, HTML, CSS | Tagged , , | Leave a comment

[JS]TinyMCEでレスポンシブな独自のダイアログを使う(Bootstrap)

Share on Facebook
Bookmark this on Delicious
LINEで送る
Pocket

TinyMCE(4.x)ではリンク挿入ボタンや画像選択ボタンを押すとダイアログがポップアップ表示されますが、レスポンシブに非対応なため、iPhone や Android などのスマートフォンでは見切れてしまい全体を表示できません。

そこで、TinyMCE に用意されたポップアップウィンドウを利用せず、Bootstrap(v3) などで作った独自のモーダルダイアログを表示するプラグインを作ってみます。

プラグイン名は「myplugin」で、ボタンを押すとダイアログが表示され、決定ボタンで「Hello, World!」という文字が挿入されます。

DEMO

スクリーンショット 2015-09-04 17.59.39

まずは tinymce/plugins/myplugin/plugin.min.js となるようにプラグインフォルダと JS ファイルを作成します。
plugin.min.js の内容は下記のとおりです。

tinymce.PluginManager.add('myplugin', function( editor ) {
	editor.addCommand('MyCommand', function() {
		window.myObj.open(editor);
	});

	editor.addButton('myplugin', {
		text: 'My Plugin',
		icon: false,
		tooltip: 'This is my plugin.',
		cmd: 'MyCommand',
	});

	editor.addMenuItem('myplugin', {
		text: 'My Plugin',
		cmd: 'MyCommand',
		context: 'insert',
		prependToContext: true
	});
});

editor.addCommand() でボタンやメニューを押した時の動作を登録します。コマンド名は「MyCommand」としましたが自由に一意な名前をつけて下さい。editor.addButton() でボタンが追加され、editor.addMenuItem() でメニューが追加されます。cmd には先ほどのコマンド名を指定します。

addCommand() を使わずにメニューやボタンに直接 onclick を持たせる書き方もあります。この場合コマンドは登録されないので execCommand() では呼び出せなくなります。

tinymce.PluginManager.add('myplugin', function( editor ) {

	editor.addButton('myplugin', {
		text: 'My Plugin',
		icon: false,
		tooltip: 'This is my plugin.',
		onclick: function(){ window.myObj.open(editor); }
	});

	editor.addMenuItem('myplugin', {
		text: 'My Plugin',
		onclick: function(){ window.myObj.open(editor); },
		context: 'insert',
		prependToContext: true
	});
});

TinyMCE を表示するフォームは次のようになっています。

<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>title</title>
<script src="https://code.jquery.com/jquery-1.11.3.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
<script src="js/tinymce/tinymce.min.js"></script>
<script>
var myObj;

$(function(){
    var editor;
    myObj = {
        init: function(){
            $('#mySubmit').on('click', myObj.insert);
        },
        open: function(ed){
            editor = ed;
            $('#myModal').modal('show');
        },
        insert: function(){
            editor.execCommand('mceInsertContent', false, "Hello, World!");
            $('#myModal').modal('hide');
        }
    };
    $(document).ready(function(){
        myObj.init();
    });
});
</script>

<script>
tinymce.init({
    selector: '#wysiwyg',
    plugins: ["myplugin"],
    toolbar: "myplugin"
});
</script>
</head>
<body>
<div class="container">
<h1>TinyMCE Demo</h1>

<textarea id="wysiwyg"></textarea>
</div>

<!-- Modal -->
<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
  <div class="modal-dialog" role="document">
    <div class="modal-content">
      <div class="modal-header">
        <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
        <h4 class="modal-title" id="myModalLabel">Modal title</h4>
      </div>
      <div class="modal-body">
        <p>Hello, World!</p>
      </div>
      <div class="modal-footer">
        <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
        <button type="button" class="btn btn-primary" id="mySubmit">Submit</button>
      </div>
    </div>
  </div>
</div>
</body>
</html>

下記は TinyMCE の初期設定部分です。
selector にエディタを表示する textarea の ID を指定し、plugins に今回使用するプラグイン名「myplugin」を指定します。ツールバーにも表示する場合は toolbar にも指定します。

tinymce.init({
    selector: '#wysiwyg',
    plugins: [ "myplugin"],
    toolbar: "myplugin"
});
</script>

myObj.open() ではダイアログの表示処理を、myObj.insert() ではテキストエリアに文字を挿入する処理が行われます。open() 時にプラグインから渡された editor を受け取って保管しておき、insert() でそれを使います。editor.execCommand() は TinyMCE の各種コマンドを実行できます。今回はテキストの挿入なので mceInsertContent を使いました。その他のコマンドはこちらに掲載されています。(ver.3.x用)

Posted in JavaScript | Tagged , , | Leave a comment

[JS]HTML5 Canvasを使ったライフゲーム

Share on Facebook
Bookmark this on Delicious
LINEで送る
Pocket

HTML5 で導入された要素 Canvas には自由に図形を描画でき、JavaScript と組み合わせることでリアルタイムに書き換えることができます。
そこで練習も兼ねて HTML5 + JavaScript でシンプルなライフゲームを作ってみました。

lifegame

Demo

・html 部分

<!DOCTYPE html>
<html>
<head>
<title>Game of Life</title>
<meta charset="utf-8">
<script src="lifegame.js"></script>
</head>
<body>

<div style="margin: 1em 0;">
<form>
<input type="button" value="Random" id="buttonRandom">
<input type="button" value="Start" id="buttonStart">
<input type="button" value="Reset" id="buttonReset">
</form>
</div>

<canvas id="lifegame" width="320" height="320"></canvas>
</body>
</html>

・スクリプト部分(lifegame.js)

var canvas;
var ctx;
var cellSize = 8;	// セル1マスのサイズ
var cols;
var rows;
var cells = new Array();
var buttonStart;
var buttonRandom;
var buttonReset;
var timer1;
var running = false;

window.onload = function()
{
	canvas = document.getElementById('lifegame');
	ctx = canvas.getContext('2d');
	cols = Math.floor(canvas.width / cellSize);
	rows = Math.floor(canvas.height / cellSize);
	initCells();
	buttonStart = document.getElementById('buttonStart');
	buttonRandom = document.getElementById('buttonRandom');
	buttonReset = document.getElementById('buttonReset');
	buttonStart.addEventListener('click', onStart, false);
	buttonRandom.addEventListener('click', randomCells, false);
	buttonReset.addEventListener('click', initCells, false);
	canvas.addEventListener('click', canvasClick, false);
};

// 開始
function onStart(){
	if(running){
		clearInterval(timer1);
		buttonStart.value = "Start";
		running = false;
	} else {
		nextGeneration();
		timer1 = setInterval("nextGeneration()", 100);
		buttonStart.value = "Stop";
		running = true;
	}
}

// 初期化
function initCells(){
	ctx.fillStyle = 'rgb(60, 60, 60)';
	ctx.fillRect(0,0, canvas.width, canvas.height);
	for(col=0;col<cols;col++){
		cells[col] = new Array();
		for(row=0;row<rows;row++){
			cells[col][row] = 0;
		}
	}
	redraw();
}

// ランダムに埋める
function randomCells(){
	for(col=0;col<cols;col++){
		cells[col] = new Array();
		for(row=0;row<rows;row++){
			cells[col][row] = Math.round( Math.random());
		}
	}
	redraw();
}

// 全体を再描画
function redraw(){
	for(col=0;col<cols;col++){
		for(row=0;row<rows;row++){
			drawCell(col, row);
		}
	}
}

// セルを描画
function drawCell(x, y){
	var value = cells[x][y];
	var style = value ? "rgb(156, 255,0)" : "rgb(40,40,40)"; 
    ctx.fillStyle = style;
	ctx.fillRect(x * cellSize, y * cellSize,
		cellSize - 1, cellSize - 1);
}

// 世代を進行させる
function nextGeneration(){
	var tmpCells = new Array();
	for(col=0;col<cols;col++){
		tmpCells[col] = new Array();
		for(row=0;row<rows;row++){
			var count = countAround(col, row);
			if(cells[col][row]){
				if(count == 2 || count == 3){
					tmpCells[col][row] = 1;
				} else {
					tmpCells[col][row] = 0;
				}
			} else {
				if(count == 3){
					tmpCells[col][row] = 1;
				} else {
					tmpCells[col][row] = 0;
				}
			}
		}
	}
	cells = tmpCells;
	redraw();
}

// 周囲の生存セルを数える
function countAround(x, y){
	var count = 0;
	for(i=-1;i<=1;i++){
		for(j=-1;j<=1;j++){
			if(
				(i != 0 || j != 0) &&
				x + i >= 0 && x + i < cols &&
				y + j >= 0 && y + j < rows
			) {
				count += cells[x + i][y + j];
			}
		}
	}
	return count;
}

// Canvasクリック
function canvasClick(e){
    var x = e.clientX - canvas.offsetLeft;
    var y = e.clientY - canvas.offsetTop;
	var col = Math.floor(x / cellSize);
	var row = Math.floor(y / cellSize);
	cells[col][row] = !cells[col][row];
	drawCell(col, row);
}

ランダムボタンでランダムにセルを埋めるかマウスクリックでセルの ON/OFF を設定してスタートボタンで開始します。
セルの周囲に2~3の生存セルが隣接している場合生き残り、過疎(1以下)や過密(4以上)の場合消滅します。
死んでいるセルの周囲にちょうど3つの生存セルが隣接している場合生きているセルが発生します。

Posted in JavaScript, HTML | Tagged , | Leave a comment