LoginSignup
29
24

More than 5 years have passed since last update.

【Javascript】リアルタイムプレビュー付き簡易htmlエディタ

Last updated at Posted at 2016-10-17

今回はJavascriptを使ってhtml作成をある程度楽にする簡易エディタをつくりたいと思います。
似たようなhtmlファイルを大量につくりたいならいいかも

内容をゴリゴリ書くなら然程労力は変わらないと思う…

プレビュー

qiita_js003.gif
必要最低限の機能しか実装してないけどちょっと工夫すれば
そこそこ実用的なものが作れるかと思います。そして楽!

クリックでデモページのzipファイルダウンロード
Win,MacのChromeでのみ動作確認済みです
10/17 リンク間違ってました…ごめんなさい

ソースコード

qiita_js003.html
<html>
    <head>
        <title>qiita_js003</title>

        <meta charset="utf-8">
        <meta name="viewport" content="width=320, minimum-scale=1.0, maximum-scale=2.0">

        <style type="text/css">

            *{
                font-family: Meiryo;
                text-align: center;
                margin: 0;
                padding: 0;
            }

            #liveeditor{
                margin: 10px;
            }

            .bottomspace{
                margin-bottom: 20px;
            }

            .editorwrapper{

            }

            .editor{
                float: left;
                width: 50%;
                height: 70%;

            }

            .preview{
                float: right;
                width: 50%;
                height: 70%;
                background-color: DDDDDD;

            }

            .procedure{
                background-color: white;
                min-height: 100%;
                clear: both;
            }

            .button{
                border: 1px solid plum;
                color: black;
                line-height: 50px;
                width: 200px;
                margin: 20px;
                background-color: aliceblue;
                padding: 5px 10px 5px 10px;
                transition: 0.3s;
            }

            .button:hover{
                border: 1px solid mediumpurple;
                color: white;
                transition: 0.3s;
                background-color: mediumpurple;
            }

            .footer{
                font-size:6px;
                font-weight: 100;
                position: fixed;
                color: white;
                background-color: #444444;
                width: 100%;
                padding: 5px 10px 5px 10px;
                bottom: 0;
            }
        </style>

        <script src="http://ajax.googleapis.com/ajax/libs/jquery/3.0.0/jquery.slim.min.js"></script>
        <script>
            $(function() {
                $('body').keyup(function() {
                    $('#livepreview').html($('#liveeditor').val());
                });
            });
        </script>

    </head>

    <body>
        <div style="editorwrapper">
            <div class="editor">
                <p style="background-color:Black; color:white;">Editor</p>
                <form name="js">
                    <p>ページタイトル(ファイル名にも適用されます)</p>
                    <input class="bottomspace" type="text" name="title" value="index"><br>

                    <p>ページの内容(htmlタグが使えます)</p>
                    <textarea id="liveeditor" name="htmlbody" rows="10" cols="80"></textarea>
                </form>
            </div>

            <div class="preview">
                <p style="background-color:Black; color:white;">Preview</p>
                <div id="livepreview"></div>
            </div>

            <div class="procedure">
                <p style="background-color:Black; color:white;">Procedure</p>
                <button class="button" onclick="openmanual()">How to Use</button>
                <button class="button" onclick="downloadfile()">Download</button>
            </div>
        </div>

        <div class="footer">
                Copyright &#169; 2016 Trouble_SUM All Rights Reserved.
        </div>

        <script type="text/javascript">
            function downloadfile(){
                //BOM
                var bom = new Uint8Array([0xEF, 0xBB, 0xBF]);

                //各フォームの値を取得
                var title = document.js.title.value;
                var htmlbody = document.js.htmlbody.value;

                //htmlの内容を変数に格納
                var html ="<html><head><title>" + title + "</title></head><body>" + htmlbody + "</body></html>"

                //blobとしてhtmlファイルを生成
                var blob = new Blob([bom, html],{type: "text/html;"})

                //a要素を作成してクリックイベント実行
                var a = document.createElement("a");
                a.href = URL.createObjectURL(blob);
                a.target = '_blank';
                a.download = title + '.html';
                a.click();
            }

            function openmanual(){
                window.open('manual.html','_blank','top=50,left=50,width=500,height=500,scrollbars=1,location=0,menubar=0,toolbar=0,status=1,directories=0,resizable=1');
                return false;
                }
        </script>
    </body>
</html>

一見長いがCSS部分(ちょっと凝ってしまった)を取り除けばかなり単純な構造
大事っぽいところを順に解説していきます。

解説

<script>
    $(function() {
        $('body').keyup(function() {
            $('#livepreview').html($('#liveeditor').val());
        });
    });
</script>

jQueryをちょびっと使ってキー入力が終わった瞬間にliveeditorの値をlivepreview側に反映してるだけ

<div style="editorwrapper">
    <div class="editor">
        <p style="background-color:Black; color:white;">Editor</p>
        <form name="js">
            <p>ページタイトル(ファイル名にも適用されます)</p>
            <input class="bottomspace" type="text" name="title" value="index"><br>

            <p>ページの内容(htmlタグが使えます)</p>
            <textarea id="liveeditor" name="htmlbody" rows="10" cols="80"></textarea>
        </form>
    </div>

    <div class="preview">
        <p style="background-color:Black; color:white;">Preview</p>
        <div id="livepreview"></div>
    </div>

    <div class="procedure">
        <p style="background-color:Black; color:white;">Procedure</p>
        <button class="button" onclick="openmanual()">How to Use</button>
        <button class="button" onclick="downloadfile()">Download</button>
    </div>
</div>

フォーム。特別変わったことはしていないと思う

function downloadfile(){
    //BOM
    var bom = new Uint8Array([0xEF, 0xBB, 0xBF]);

    //各フォームの値を取得
    var title = document.js.title.value;
    var htmlbody = document.js.htmlbody.value;

    //htmlの内容を変数に格納
    var html ="<html><head><title>" + title + "</title></head><body>" + htmlbody + "</body></html>"

    //blobとしてhtmlファイルを生成
    var blob = new Blob([bom, html],{type: "text/html;"})

    //a要素を作成してクリックイベントを発火させる
    var a = document.createElement("a");
    a.href = URL.createObjectURL(blob);
    a.target = '_blank';
    a.download = title + '.html';
    a.click();
}

これが今回のメイン処理。
htmlファイルをそのまま生成したら文字化けしてしまったのでBOMをつけたら直った。
MacでもWinでも一応文字化けせずにファイル生成できたから大丈夫だと思うけど、
もしもうまくいかないようなら文字コードをUTF-16あたりにすると治るかも?(試してないけど)

あとはフォームからタイトルと本文をぶっこ抜いてタグと結合して変数に格納。
blobとしてhtmlファイルをつくる

そのあとにa要素を生成、クリックイベントを発火させてhtmlファイルを直でダウンロードするようにしてます。

問題点

言わずともわかると思うけどこれをそのまま使ったらXSSの餌食です。
よくわからない人は試しにテキストエリアに

<script>alert('uoaaaa!!!!!');</script>

とかコピペしてみよう。

ローカルで使うならまだしも自分のサーバ上で公開するならタグとか特殊文字のエスケープ処理を加える必要があると思う。
これをこのまま使う人はいないと思うので参考程度に見てネ

参考にさせていただいた記事

JavaScriptでファイルダウンロード処理を実現する
http://qiita.com/wadahiro/items/eb50ac6bbe2e18cf8813

BOMを変数に格納するところそのままもらいました

29
24
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
29
24