Gruntを使ってファイル変更後ブラウザで自動リロード

HTMLやJS、CSSを編集したらいちいちブラウザをリロードするのは面倒ですよね。いろんな人が書いているので何番煎じだって感じですが、動く例として。2014-11-05の時点でMacとDebianで確認しました。

npmなどは事前にインストールしておいてください。

# gruntをインストール
$ sudo npm install grunt-cli -g

# ディレクトリを作成して移動
$ mkdir grunt-livereload-example
$ cd grunt-livereload-example/

# 必要なパッケージをインストール
$ sudo npm install grunt-contrib-watch grunt-contrib-connect connect-livereload

# index.htmlを作成 (ソースは後ろに付加)
$ vi index.html

# Gruntfile.jsを作成 (ソースを後ろに付加)
$ vi Gruntfile.js

# gruntを実行
$ grunt

# ブラウザで、127.0.0.1:9000 にアクセス!

index.html
<script src="http://127.0.0.1:35729/livereload.js"></script>

<div>
ここにいろいろと書いてみて、保存すると、ブラウザが再読み込みしてくれます。
</div>

Gruntfile.js
var LIVE_RELOAD_PORT = 35729;
var LIVE_RELOAD_SNIPPET = require('connect-livereload')({port: LIVE_RELOAD_PORT});
var LIVE_RELOAD_MOUNT_FOLDER = function (connect, dir) {
	return connect.static(require('path').resolve(dir));
};

module.exports = function(grunt) {

  grunt.loadNpmTasks('grunt-contrib-watch');
  grunt.loadNpmTasks('grunt-contrib-connect');

  grunt.initConfig({
    watch: {
      files: 'index.html', // 監視対象のファイル
      options: {
        livereload: true //livereloadを有効
      }
    },
    connect: {
      options: {
        port: 9000,
        hostname: '0.0.0.0'
      },
      livereload: {
        options: {
          middleware: function (connect) {
            return [LIVE_RELOAD_SNIPPET, LIVE_RELOAD_MOUNT_FOLDER(connect, './')];
          }
        }
      }
    }
  });

  grunt.registerTask('default', ['connect', 'watch']);
};

蛇足
– HTMLにスニペットを入れてありますので、Chromeのアドオンなどは必要ありません
– livereloadのポートの変更は、Gruntfile.jsのLIVE_RELOAD_PORTの値を書き換えて、HTMLにスニペットを反映し、gruntを再起動すればOKです
– HTMLのスニペットのIPアドレスを書きければ、ローカルではなくリモートのブラウザでも動きます。

ローカルでRTCDataChannelを使ってみる

スクリーンショット:
スクリーンショット 2014-09-17 18.21.47

動作例: http://jsfiddle.net/su5o99oa/
Chromeで開いて(Firefoxだと動きません!)、デベロパーツールを出して、右上の「Run」を押して、HTMLが表示されるので、その中のinput領域に何かを書いてsubmitボタンを押します。すると、下の方に入力した文字が出ます。デベロパーツールのコンソールでも確認が出来ます。ボタンをクリックすると、RTCDataChannelのsendメソッドにより文字列が送信されて、もう片方のRTCDataChannelがメッセージを受け取り、それをHTMLの領域に書き出します。

ソース:
ソースは↑こんな感じです。

input領域にファイル名、textarea領域に内容を入力して、ファイルをブラウザでダウンロード

表題のようなことをやりたかったのであれこれやりました。ChromeとFirefoxでは動作確認しました。

スクリーンショット:
スクリーンショット 2014-09-17 15.23.43

操作方法:
– ファイル名を入力
– テキストエリアに入力
– 「Click to download」をクリック

HTMLとJavascript:

参考URL:
http://hebikuzure.wordpress.com/2012/12/16/file-api-%E3%81%A7%E4%BD%9C%E6%88%90%E3%81%97%E3%81%9F-blob-%E3%82%92%E3%83%80%E3%82%A6%E3%83%B3%E3%83%AD%E3%83%BC%E3%83%89%E3%81%99%E3%82%8B/

はまりどころ:
– onclick要素で、downloadという名前のメソッドにすると、エラーが出るようです。ですので今回はdownloadFileという名前にしました。

reveal.jsでページ番号とfooterを加える

reveal.jsというイケてるHTMLスライドソフト(ソースデモ)があります。諸事情により、ページ番号とfooterを入れる必要がありました。

ページ番号は、

added page number feature


↑のmohikanerさんのソースを利用させてもらい、footerは自力でcssで頑張りました。

こんな感じになります↓

reveal.js.slide-number_footer

以下、ソースのHTMLです。実際に実行する際は、公式からreveal.jsを落としてきて、index.htmlと同じ階層のディレクトリにindex2.htmlとでもして、↓をコピペするといいと思います。ちなみに私はHTMLもCSSもJavaScriptもjQueryもぜんぜん分からないので、いろいろと間違った記法をしている可能性があります。

<!doctype html>
<html lang="en">
    <head>
	<meta charset="utf-8">
	<title>Page Number and Footer in reveal.js</title>
	<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
	<link rel="stylesheet" href="css/reveal.min.css">
	<link rel="stylesheet" href="css/theme/default.css" id="theme">

	<!-- css for footer and page number -->
	<style type="text/css">
	    footer{
		clear:both;
		font-size:20px;
		color: red;
		height:75px;
		display:block;
		position:absolute;
		bottom:0;
		width: 100%;
	    }

	    footer div{
		margin:0 auto;
		text-align: center;
	    }

	    aside.slide-number{
		position:absolute;
		bottom: 25px;
		left: 25px;
		width: 100%;
	    }
	</style>
    </head>
    <body>
	<div class="reveal">
	    <div class="slides">
		<section>
		    <h2>Page Number and Footer in reveal.js</h2>
		    <p>Press right arrow key</p>
		</section>
	    </div>

	    <div class="slides">
		<section>
		    <h2>You can see the page number and footer. Yey!</h2>
		</section>
	    </div>

	    <div class="slides">
		<section>
		    <h2>This must be #2</h2>
		</section>
	    </div>
	</div>

	<footer>
	    <div>I am a footer!</div>
	</footer>

	<script src="lib/js/head.min.js"></script>
	<script src="js/reveal.js"></script>
	<script>
	    Reveal.initialize({
		controls: true,
		progress: true,
		history: true,
		center: true,
		theme: 'default',
		transition: Reveal.getQueryHash().transition || 'default',
		transitionSpeed: 'default'
	    });
	</script>

	<!-- Page number -->
	<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
	<script>
	    function currentPageFormatter(event) {
		var formattedStr;
		if (event.indexh === 0) {
		    return "";
		}

		formattedStr = event.indexh;

		if (event.indexv) {
		    formattedStr += "/" + event.indexv;
		}

		return formattedStr;
	    }

	    Reveal.addEventListener('ready', function(event) {
		$('<aside class="slide-number"></aside>')
			.text(currentPageFormatter(event))
			.appendTo('.reveal.center');
	    });

	    Reveal.addEventListener('slidechanged', function(event) {
		$(".slide-number").text(currentPageFormatter(event));
	    });
	</script>
    </body>
</html>

JavaScript の変数を PHP に送信する

index.html の中の JavaScript のある変数 counter の値を send.php に送信したい場合がある。そんなのを書いてみた。

具体例 ← クリック!

やり方としては、form に onsubmit で関数Fを書いておいて、form 内ボタンが押された時に関数Fが呼び出されて、その関数内でhidden属性のvalueに値をセットする感じである。

index.html↓

<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title></title>
		<script>
			var counter = 0;

			function get_javascript_variable(){
				document.forms['input_form'].elements['hidden_input'].value = counter;
			}
			
			function add()
			{
				counter += 1;
			}
		</script>
	</head>
	<body>
		<form name ="input_form" action="send.php" method="post" onsubmit="get_javascript_variable()">
			<p>
				<input type="submit" value="SHOW COUNTER!" />
				<br><br>
				<input type="button" value="ADD COUNTER" onclick="add()" />
				<input type="hidden" name="hidden_input" value="" />
			</p>
		</form>
	</body>
</html>

send.php↓
<?php
$num = isset($_POST['hidden_input']) ? $_POST['hidden_input'] : null;

print "num: " . $num;
?>

実行結果↓
num: 4