javascript(jQuery)でhtmlやcss、javascriptのソースをコピーさせる

WordPressのことやHTML・CSSやjavascript(jquery)のことを記事にしていると、ページ内で使用している html、css、javascript をそのままコピーさせたい場合があります。
今回javascriptを使用して実現してみましたので、処理の中身に関してご紹介します。

動作や使い方などはこちらをご覧ください。

コピーさせる仕組

「html」、「css」でコピーさせる仕組みは少し異なります。cssの方には後述しますが、直後に書くというルールもあります。
「html」と「css」のコピーを同じ仕組みにすることはできますが、コピーされる側に無駄なタグ等を記述させない方法を試行錯誤し、異なる仕組みにしました。

例で使用するソース

まず、本ページの説明で使用する「コピーさせたい要素(html)」と「css」になります。
以降の説明ではこちらをコピーさせたいものとして説明します。

html

<div class="ex-box">
    <span>テキストテキストテキストテキスト</span>
</div>

css

<style>
.ex-box {
    border: 1px solid #999;
    padding: 20px;
}
.ex-box span {
    color: #c00;
    font-size: 14px;
}
</style>

html、cssの並び

実際に「css」をコピーさせたい場合は、下記のように並べる必要がありますで、ご注意ください。

<div class="ex-box">
    <span>テキストテキストテキストテキスト</span>
</div>
<style>
.ex-box {
    border: 1px solid #999;
    padding: 20px;
}
.ex-box span {
    color: #c00;
    font-size: 14px;
}
</style>

メインとなるjavascript(jQueryを使用)

下記コードによって、コピーを実装しています。
大した処理はしていませんが、次項で少し詳しく見ていきます。

※jqueryの1.12.4を使用していますので、読込が必要です(特殊な処理はしていないので、おそらくその他のバージョンでも動作するかと思います)

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script>
jQuery(function($){
    $('.copy-inner').on('click', function() {
        var target = $(this).data('target');
        var text = $(target).html();
        $(this).copy(text);
        alert('コピーしました。');
    });
    $('.copy-outer').on('click', function() {
        var target = $(this).data('target');
        var text = $(target).prop('outerHTML');
        $(this).copy(text);
        alert('コピーしました。');
    });
    $('.copy-css-with-style').on('click', function() {
        var target = $(this).data('target');
        var text = $(target).next('style').prop('outerHTML');
        $(this).copy(text);
        alert('コピーしました。');
    });
    $('.copy-css').on('click', function() {
        var target = $(this).data('target');
        var text = $(target).next('style').text();
        $(this).copy(text);
        alert('コピーしました。');
    });
    $.fn.extend({
        copy: function(text) {
            $(this).after('<textarea>'+text+'</textarea>');
            $(this).next('textarea').select();
            document.execCommand('copy');
            $(this).next('textarea').remove();
        },
    });
});
</script>

それでは、個別に詳しく見ていきます。

メイン処理(コピー)

メインの「コピーをさせる」処理です。
jQueryエレメントに独自の新しいメソッドを追加する形で対応しました。

jQuery(function($){
    $.fn.extend({
        copy: function(text) {
            $(this).after('<textarea>'+text+'</textarea>');
            $(this).next('textarea').select();
            document.execCommand('copy');
            $(this).next('textarea').remove();
        },
    });
});

細かく見ていきます。

0.まずjQueryエレメントに独自の新しいメソッド(copy)を追加します。

$.fn.extend({
    copy: function(text) {
        ・・・
    },
});

1.クリックされた要素の後ろに「指定されたテキスト」を持った textareaタグを追加します。

$(this).after('<textarea>'+text+'</textarea>');

2.追加した textareaの中身(テキスト)を選択状態にします。

$(this).next('textarea').select();

3.選択箇所をコピーをします。

document.execCommand('copy');

4.追加した textareaを削除します。

$(this).next('textarea').remove();

これらが一連の流れになります。

簡単にまとめますと、
コピーさせるために選択状態を作りたい。そのため新しく「textarea」を追加し、「指定されたテキスト」を持たせます。
「textarea」であればjavascriptで簡単に選択状態にできます。
選択状態にした後はコピー処理をすればコピーができます。
最後に、不要になった「textarea」を削除してコピー処理完了です。

追加したjQueryエレメントに独自のメソッドの使い方

jQueryの標準メソッドと同じように「copy」メソッドが使用できるようになります。
下記のようなスクリプトを書けばOKです。

$('.btn').copy('コピーさせたいテキストをここに指定');

要素(html)の中身をコピーさせる

下の要素の中身だけをコピーさせます。

<div class="ex-box">
    <span>テキストテキストテキストテキスト</span>
</div>

つまり下の部分です。

    <span>テキストテキストテキストテキスト</span>

javascriptの該当箇所は下記です。

<script>
jQuery(function($){
    $('.copy-inner').on('click', function() {
        var target = $(this).data('target');
        var text = $(target).html();
        $(this).copy(text);
        alert('コピーしました。');
    });
});
</script>

ボタンの指定の仕方は下記の通りです。

<span class="copy-inner" data-target=".ex-box">ボタン(要素の中身)</span>

それでは、細かく見ていきます。

0.まず「copy-inner」がクリックされた時の処理を定義します。

$.fn.extend({
    $('.copy-inner').on('click', function() {
        ・・・
    });
});

1.ボタン要素(copy-inner)に指定されたカスタムデータ(data-target)の値を取得します。

var target = $(this).data('target');

2.カスタムデータ(data-target)で指定された要素の中身(タグも含む)を取得します。
※指定された要素自身は含みません

var text = $(target).html();

3.取得したテキスト(タグも含む)をコピーをします。
※メイン処理で追加した「copy」を使用します

$(this).copy(text);

4.コピー完了を知らせます。
※なくても問題ありません

alert('コピーしました。');

要素(html)をコピーさせる

下の要素自身をコピーさせます。

<div class="ex-box">
    <span>テキストテキストテキストテキスト</span>
</div>

javascriptの該当箇所は下記です。

<script>
jQuery(function($){
    $('.copy-outer').on('click', function() {
        var target = $(this).data('target');
        var text = $(target).prop('outerHTML');
        $(this).copy(text);
        alert('コピーしました。');
    });
});
</script>

ボタンの指定の仕方は下記の通りです。

<span class="copy-outer" data-target=".ex-box">ボタン(要素自身)</span>

それでは、細かく見ていきます。

0.まず「copy-outer」がクリックされた時の処理を定義します。

$.fn.extend({
    $('.copy-outer').on('click', function() {
        ・・・
    });
});

1.ボタン要素(copy-outer)に指定されたカスタムデータ(data-target)の値を取得します。

var target = $(this).data('target');

2.カスタムデータ(data-target)で指定された要素自身(中身を含む)を取得します。

var text = $(target).prop('outerHTML');

3.取得したテキスト(タグも含む)をコピーをします。
※メイン処理で追加した「copy」を使用します

$(this).copy(text);

4.コピー完了を知らせます。
※なくても問題ありません

alert('コピーしました。');

css(styleタグ含む)をコピーさせる

下の<style>~</style>をコピーさせます。

<style>
.ex-box {
    border: 1px solid #999;
    padding: 20px;
}
.ex-box span {
    color: #c00;
    font-size: 14px;
}
</style>

javascriptの該当箇所は下記です。

<script>
jQuery(function($){
    $('.copy-css-with-style').on('click', function() {
        var target = $(this).data('target');
        var text = $(target).next('style').prop('outerHTML');
        $(this).copy(text);
        alert('コピーしました。');
    });
});
</script>

ボタンの指定の仕方は下記の通りです。

<span class="copy-css-with-style" data-target=".ex-box">ボタン(css※styleタグ含む)</span>

それでは、細かく見ていきます。

0.まず「copy-css-with-style」がクリックされた時の処理を定義します。

$.fn.extend({
    $('.copy-css-with-style').on('click', function() {
        ・・・
    });
});

1.ボタン要素(copy-css-with-style)に指定されたカスタムデータ(data-target)の値を取得します。

var target = $(this).data('target');

2.カスタムデータ(data-target)で指定された要素の直後にあるスタイル(<style>~</style>)を取得します。

var text = $(target).next('style').prop('outerHTML');

3.取得したスタイルをコピーをします。
※メイン処理で追加した「copy」を使用します

$(this).copy(text);

4.コピー完了を知らせます。
※なくても問題ありません

alert('コピーしました。');

css(styleタグ含まない)をコピーさせる

下のように<style>~</style>の中身だけをコピーさせます。

.ex-box {
    border: 1px solid #999;
    padding: 20px;
}
.ex-box span {
    color: #c00;
    font-size: 14px;
}

javascriptの該当箇所は下記です。

<script>
jQuery(function($){
    $('.copy-css').on('click', function() {
        var target = $(this).data('target');
        var text = $(target).next('style').text();
        $(this).copy(text);
        alert('コピーしました。');
    });
});
</script>

ボタンの指定の仕方は下記の通りです。

<span class="copy-css" data-target=".ex-box">ボタン(css※styleタグ含まない)</span>

それでは、細かく見ていきます。

0.まず「copy-css」がクリックされた時の処理を定義します。

$.fn.extend({
    $('.copy-css').on('click', function() {
        ・・・
    });
});

1.ボタン要素(copy-css)に指定されたカスタムデータ(data-target)の値を取得します。

var target = $(this).data('target');

2.カスタムデータ(data-target)で指定された要素の直後にあるスタイル(<style>~</style>)の中身だけを取得します。

var text = $(target).next('style').text();

3.取得したスタイルをコピーをします。
※メイン処理で追加した「copy」を使用します

$(this).copy(text);

4.コピー完了を知らせます。
※なくても問題ありません

alert('コピーしました。');

まとめ・経緯

色々と分けて説明しましたが、基本的な部分はどれも似たような処理です。
コピーしたい要素を渡して、自分を含むものをコピーするか / 自分の中身だけをコピーするかという処理になります。

本ページのスタイルのコピーで行ったようにhtmlの要素を基準に決め打ちの場所のstyleタグをコピーするという形をとれば、独自でコピー対応ができるかと思います。

経緯

今回、このコピーの処理を作成した経緯についてです。

本サイトとECサイトをセットで作成する案件がありました。その際に、基本的なレイアウトが同じなので、ヘッダーやフッター、サイドなどは同じhtml(javascript)・cssソースを利用できました。
ただ、本サイトは本サイトに、ECサイトはECサイトにソースを設定しなければなりませんでした。

本サイト⇒ECサイトへの反映の際に、書いているhtmlをそのままコピーしたいと思ったのがこの処理を作成するきっかけでした。
また、本サイトのサイドバナー等はクライアント自身で更新できるようWPで構築していました。
ただ、更新を行うと、それをECサイトにも反映させる必要があります。

その際にボタン1つでコピーした状態にし、ECサイトの管理画面のここに貼りつけてくださいというマニュアルを用意し、対応しました。
クライアントは、ソースの中身は気にせずに指定箇所に貼り付けるだけなので、問題なく対応していただけています。
コピーする部分が煩わしいですが、構造上仕方ない部分かと思います。

それで出来上がった処理です。
本ページでは少しだけ拡張し、cssもコピーできるよう対応しました。

あまり活躍する場はないかもしれませんが、参考になれば幸いです。