Category Archives: JavaScript

[JS]画像ファイルアップロード前にプレビューを表示する

Facebook にシェア
Delicious にシェア
LINEで送る
Pocket

HTML 5 で追加された FileReader を利用すると JavaScript からローカルファイルの一部にアクセスすることができるようになります。一般的にはアップロードするファイルを事前にプレビューするなどの用途でよく使われます。
下記サンプルはファイル選択時に画像プレビューを表示するプログラムです。
古いブラウザでは FileReader が利用できないためその場合は何もしない点に注意して下さい。

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Preview Demo</title>
    <script>
    document.addEventListener('DOMContentLoaded', function(){
        // アップロードボタン
        var fileSelector = '.image-upload';
        
        // プレビュー画像のクラス名
        var previewSelector = '.preview';

        // プレビューするファイルタイプ
        var fileTypes = [
            'image/jpeg', 'image/jpg', 'image/png',
            'image/gif', 'image/bmp'
        ];

        if( typeof FileReader == 'undefined' ){
            return;
        }

        var reader = new FileReader();

        reader.addEventListener('load', function(event) {
            preview.setAttribute('src', event.target.result);
        });

        var fileInputs = document.querySelectorAll(fileSelector);

        for(var i = 0; i < fileInputs.length; i++){
            var fileInput = fileInputs[i];
            var input = fileInput.querySelector('input');
            var preview = fileInput.querySelector(previewSelector);

            if(!preview) return;
            preview.setAttribute('data-fallback-src', preview.getAttribute('src'));

            input.addEventListener('change', function(){
                if(input.files && input.files[0] && fileTypes.indexOf(input.files[0].type) >= 0) {
                    reader.readAsDataURL(input.files[0]);
                } else {
                    preview.setAttribute('src', preview.getAttribute('data-fallback-src'));
                }
            });
        }
    });
    </script>
    <style>
    .image-upload .preview {
        display: block;
        width: 100%;
        max-width: 100px;
        height: auto;
    }
    </style>
</head>
<body>
    <div class="image-upload">
        <img class="preview" src="noimage.jpg" alt="Preview">
        <input name="image" type="file">
    </div>
</body>
</html>

Posted in JavaScript | Tagged | Leave a comment

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

Facebook にシェア
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, jQuery]ページ内に他のページをiframeのように埋め込む

Facebook にシェア
Delicious にシェア
LINEで送る
Pocket

一昔前まではサイトそのものをフレーム構造にしたり iframe を使って新着情報などを埋め込むサイトを良く見かけましたが、HTML5 と Ajax が定着してからはあまり見なくなりました。frameset や frame タグ自体廃止され、唯一残った iframe も iPhone や android の登場により使いにくいものとなってしまったことが理由の一つかと思います。
今回は jQuery の load() を使って他のページを GET, POST の二つの方式を用いて読み込むサンプルを作ってみようと思います。


GET

GET

index.html

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>Ajax Load</title>
		<script src="//code.jquery.com/jquery-1.12.0.min.js"></script>
		<script>
		function loadPage(page){
			$("#content-frame").load("pages.php?page=" + page);
		}
		</script>
	</head>
	<body>
		<ul>
			<li><a href="javascript:loadPage(0);">Page 1</a></li>
			<li><a href="javascript:loadPage(1);">Page 2</a></li>
			<li><a href="javascript:loadPage(2);">Page 3</a></li>
		</ul>
		<div id="content-frame" style="width: 300px;height:200px;overflow:scroll;border:1px solid #DDD;">
			Sample
		</div>
	</body>
</html>

pages.php

<?php
$content1 = <<<EOD
<h1>Hello, World!</h1>
<p>page 1</p>
EOD;

$content2 = <<<EOD
<h1>Foo Bar</h1>
<p>page 2</p>
EOD;

$content3 = <<<EOD
<h1>Lorem Ipsum</h1>
<p>page 3</p>

<p>
Lorem ipsum dolor sit amet,
consectetur adipiscing elit,
sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris
nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor
in reprehenderit in voluptate velit esse cillum dolore eu fugiat
nulla pariatur. Excepteur sint occaecat cupidatat non proident,
sunt in culpa qui officia deserunt mollit anim id est laborum.
</p>
EOD;

$pages = array($content1, $content2, $content3);

$page = filter_input(INPUT_GET, 'page', FILTER_VALIDATE_INT);
$page = ($page !== false) ? (int)$page : 0;

if(isset($pages[$page])){
	echo $pages[$page];
} else {
	echo 'Not Found.';
}

GET パラメータ「page」を pages.php を渡し、そのページ番号に応じて HTML を返すという単純なものです。
$("#表示先ID").load(読み込むページのURL); という形で指定します。 iframe と違い要素内に直接読み込まれるので <html> や<body> などのタグは使いません。
また、CSS などは読み込み元のページのスタイルが適用されます。


POST

POST

index.html

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>Ajax Load</title>
		<script src="//code.jquery.com/jquery-1.12.0.min.js"></script>
		<script>
		function submitMessage(page){
			var params = {message: $('#message').val()};
			$("#content-frame").load("hello.php", params);
		}
		</script>
	</head>
	<body>
		<p>
			<input id="message" type="text">
			<input type="button" onclick="submitMessage()" value="Submit">
		</p>

		<div id="content-frame" style="width: 300px;height:200px;overflow:scroll;border:1px solid #DDD;">
			Sample
		</div>
	</body>
</html>

hello.php

<?php
$message = (string)filter_input(INPUT_POST, 'message');
echo '<p>Hello, ' . htmlspecialchars($message, ENT_QUOTES, 'UTF-8') . '!</p>';

load() の第二引数にオブジェクトを指定した場合 POST メソッドが使用されます。
サンプルではテキストボックスの文字列を post.php に送信し、post.php は送られてきた文字に「Hello, 」をつけて返します。

POST の際にCSRF(クロスサイトリクエストフォージェリ)対策としてトークンを送信する必要がある場合、ajaxSetup() を使って拡張ヘッダに埋め込んでしまうのが良いと思います。

<meta name="csrf-token" content="<?php echo $token;?>">

<script>
$.ajaxSetup({
    headers: {
        'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
    }
});
</script>

送信されたヘッダのトークンは PHP では $_SERVER["HTTP_X_CSRF_TOKEN"]; として受け取ることができます。

また、より複雑な通信を行う必要がある場合は load() の代わりに ajax() を使うことになります。
以下は同じ動作を ajax() を使う形に変更したものです。

function submitMessage(page){
    var params = {message: $('#message').val()};
    $("#content-frame").load('hello.php', params);

    $.ajax({
        url: "hello.php",
        data: params,
        type: "POST",
        success: function(html) { $("#content-frame").html(html); }
    });
}

Posted in JavaScript | Leave a comment