20201114のHTMLに関する記事は13件です。

【javaScript / jQuery】Googleドライブに保存した画像をHTMLで表示させる

はじめに

初めての投稿です。自分の復習も兼ねて、Qiitaに記事投稿していこうと思います。
至らない点があったらスミマセン。
今回JavaScriptでご紹介していますが、変数にGoogleドライブのURLを格納できる言語でしたらどの言語でも問題ありません。
というより、imgタグに直接記述するだけならHTMLのみで完結します。

内容

javaScript,jQueryを利用してGoogleドライブの画像をHTMLに引っ張ってくるという趣旨の記事になります。

趣味でよくiPadを使ってイラストを描くのですが、描いた絵を自分の開設しているWebページへ表示させる時にPCに送ってサーバに送って・・・という作業が面倒だったので、iPadから直接Googleドライブに画像を置いて、そこからプログラムで引っ張ってくればいいじゃないかと思ったのが始まりです。

Googleドライブに画像を保存している前提で執筆していきます。

Googleドライブに保存した画像の設定を変更する

コンテンツを右クリックし、「リンクを取得」を選択します。
スクリーンショット 2020-11-13 6.20.36.png

権限を「制限付き」から、「リンクを知っている全員」に変更します。

スクリーンショット 2020-11-13 6.25.51.png

この時、リンクのURLは下記のようになっています。
https://drive.google.com/file/d/画像ごとに異なるID/view?usp=sharing

この[画像ごとに異なるID]をjavaScriptに記述し、HTMLで表示させようという流れになります。

またこちらのリンクへ実際に移動してみると分かるのですが、閲覧者側では違うURLとして表示されます。
このように、ファイルを確認するページ別にURLが異なるのですが、HTMLの<img>を利用して画像を表示させる場合は下記のURLを利用します。

http://drive.google.com/uc?export=view&id=画像ごとに異なるID

画像のIDを変数に格納する

変数に画像のIDを格納していきます。ファイルIDは「XXXX」と表記しています。
今回はjQueryのbefore要素も利用しています。

index.html
<!-- <head>等、一部省略 -->
<body>
    <div class="container">
      <h4>画像を表示</h4>
      <div id="driveImg"></div>
    </div>
 <!-- jQueryでbefore要素を利用。今回の場合、containerとdriveImgの間に画像が挿入される -->
</body>
script.js
const URL = "http://drive.google.com/uc?export=view&id=";
const item = "XXXX";
//XXXX : Googleドライブの共有リンクのURLから確認したファイルのID

const driveURL = URL + item;
//driveURL = "http://drive.google.com/uc?export=view&id=XXXX"; となった

$('#driveImg').before('<img src="' + driveURL + '">');
/*
<div id="driveImg"></div>の後ろに、
<img src="http://drive.google.com/uc?export=view&id=XXXX">が挿入される。
*/

結果

スクリーンショット 2020-11-14 22.46.27.png

画像が表示されました。
なお2020年11月現在、ファイルのIDの文字数は33文字で統一されています。

内容は以上となります。
自分はいろんな画像のIDを配列に格納したので、その名残でJavaScriptとしてのファイルもご紹介したのですが、imgタグのみでも実装できるので初学者の方でも比較的簡単に実現できる内容だと思います。

実際やってみると分かるのですが、重いファイルをこれで表示させるとなかなか時間がかかります。
趣味で描いているイラストのサイズは2500*3000px程度であることが多いのですが、このくらい大きな画像になってしまうと読み込みに失敗してしまうことがたまにあります。

軽いファイルにならこの方法は十分使えるかもしれませんね。
良ければ応用してみてください。

閲覧ありがとうございました!

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【JavaScript / jQuery】Googleドライブに保存した画像をHTMLで表示させる

はじめに

初めての投稿です。自分の復習も兼ねて、Qiitaに記事投稿していこうと思います。
至らない点があったらスミマセン。
今回JavaScriptでご紹介していますが、変数にGoogleドライブのURLを格納できる言語でしたらどの言語でも問題ありません。
というより、imgタグに直接記述するだけならHTMLのみで完結します。

内容

JavaScript,jQueryを利用してGoogleドライブの画像をHTMLに引っ張ってくるという趣旨の記事になります。

趣味でよくiPadを使ってイラストを描くのですが、描いた絵を自分の開設しているWebページへ表示させる時にPCに送ってサーバに送って・・・という作業が面倒だったので、iPadから直接Googleドライブに画像を置いて、そこからプログラムで引っ張ってくればいいじゃないかと思ったのが始まりです。

Googleドライブに画像を保存している前提で執筆していきます。

Googleドライブに保存した画像の設定を変更する

コンテンツを右クリックし、「リンクを取得」を選択します。
スクリーンショット 2020-11-13 6.20.36.png

権限を「制限付き」から、「リンクを知っている全員」に変更します。

スクリーンショット 2020-11-13 6.25.51.png

この時、リンクのURLは下記のようになっています。
https://drive.google.com/file/d/画像ごとに異なるID/view?usp=sharing

この[画像ごとに異なるID]をJavaScriptに記述し、HTMLで表示させようという流れになります。

またこちらのリンクへ実際に移動してみると分かるのですが、閲覧者側では違うURLとして表示されます。
このように、ファイルを確認するページ別にURLが異なるのですが、HTMLの<img>を利用して画像を表示させる場合は下記のURLを利用します。

http://drive.google.com/uc?export=view&id=画像ごとに異なるID

画像のIDを変数に格納する

変数に画像のIDを格納していきます。ファイルIDは「XXXX」と表記しています。
今回はjQueryのbefore要素も利用しています。

index.html
<!-- <head>等、一部省略 -->
<body>
    <div class="container">
      <h4>画像を表示</h4>
      <div id="driveImg"></div>
    </div>
 <!-- jQueryでbefore要素を利用。今回の場合、containerとdriveImgの間に画像が挿入される -->
</body>
script.js
const URL = "http://drive.google.com/uc?export=view&id=";
const item = "XXXX";
//XXXX : Googleドライブの共有リンクのURLから確認したファイルのID

const driveURL = URL + item;
//driveURL = "http://drive.google.com/uc?export=view&id=XXXX"; となった

$('#driveImg').before('<img src="' + driveURL + '">');
/*
<div id="driveImg"></div>の後ろに、
<img src="http://drive.google.com/uc?export=view&id=XXXX">が挿入される。
*/

結果

スクリーンショット 2020-11-14 22.46.27.png

画像が表示されました。
なお2020年11月現在、ファイルのIDの文字数は33文字で統一されています。

内容は以上となります。
自分はいろんな画像のIDを配列に格納したので、その名残でJavaScriptとしてのファイルもご紹介したのですが、imgタグのみでも実装できるので初学者の方でも比較的簡単に実現できる内容だと思います。

実際やってみると分かるのですが、重いファイルをこれで表示させるとなかなか時間がかかります。
趣味で描いているイラストのサイズは2500*3000px程度であることが多いのですが、このくらい大きな画像になってしまうと読み込みに失敗してしまうことがたまにあります。

軽いファイルにならこの方法は十分使えるかもしれませんね。
良ければ応用してみてください。

閲覧ありがとうございました!

追記

編集リクエストを頂いたので一部修正しました。
こんな機能もあるんですね・・・ありがとうございます。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【初心者向け】画像のボタンホバー時、背景が透けてしまう問題の解決法2つ

どうも7noteです。透過時に背景が見えてしまう対策方法

背景色が入っている箇所の上に画像のボタンを配置した時、ボタンがhoverで透過した際に背景色がうっすら見えてしまう対策方法について。

画像で作成したボタンの場合、2つの方法で対応することができます。

※ボタンをCSSのみ(背景色)で作成した場合はこちら

通常時
normal.png

ただ透明にしたら後ろが透ける
miss.png

対策すると・・・
ok.png

①画像の背景に白を入れておく

index.html
<div class="box">
  <div class="btn"><a href="#"><img src="sample.png" alt=""></a></div>
</div>
style.css
.box {
  padding: 50px;         /* 適当な余白を確保 */
  background-size: auto auto;  /* 分かりやすいよう赤のストライプを指定 */
  background-color: rgba(255, 255, 255, 1);
  background-image: repeating-linear-gradient(45deg, transparent, transparent 10px, rgba(255, 1, 1, 1) 10px, rgba(255, 1, 1, 1) 20px );
}

.btn {
  width: 150px;         /* 横幅を適当なサイズに指定 */
  margin: 10px;         /* ボタン同士が見やすいよう適度な余白 */
  background: #fff;     /* 背景に白を挿入 */
}

.btn a:hover {
  opacity: .8;          /* 透過させる */
}

解説

透過させるのはaタグだけ透過させ、親要素のdivは背景色として白がはいっているのでその後ろのストライプは透けずに済むという方法です。
親子構造になって、子要素だけが透過しているのがポイント

ただし、CSSで再現可能な形(四角や楕円系)でなければ白い枠がはみ出たり、透過を綺麗に防ぐことができないので万能というわけではありません。

②背景画像に指定して、hover時だけ画像を変更する

index.html
<div class="box">
  <div class="btn"><a href="#"></a></div>
</div>
style.css
.box {
  padding: 50px;         /* 適当な余白を確保 */
  background: #f36 25%,  /* 分かりやすいよう赤のストライプを指定 */
    #fff 25%,
    #fff 50%,
    #f36 50%,
    #f36 75%,
    #fff 75%,
    #fff
  );
  background-size: 40px 40px;  /* 適度な大きさに指定 */
}

.btn {
  width: 150px;         /* 横幅を適当なサイズに指定 */
  height: 50px;         /* 縦幅を適当なサイズに指定 */
  margin: 10px;         /* ボタン同士が見やすいよう適度な余白 */
  background: #fff;     /* 背景に白を挿入 */
}

.btn a {
  display: block;
  background-image: url("sample.png");
  background-repeat: no-repeat;
  background-size: 100% auto;
}

.btn a:hover {
  background-image: url("sample-hover.png");
}

解説

imgタグではなく、aタグの背景画像としてボタンを設置しておき、hover時に背景画像を変更する方法です。
2種類の画像を用意する必要がありますが、CSSでは再現が難しい形のボタンでもこの方法なら対応することができます

※imgタグでやる場合はjavascriptでの制御することができます。

まとめ

★や◆など変な形のボタンでなければ①の方法が修正などの手間が少なく済むのでオススメ。
少し変った形などにしなければいけない時は②の方法で画像を2種類用意しましょう!

おそまつ!

~ Qiitaで毎日投稿中!! ~
【初心者向け】HTML・CSSのちょいテク詰め合わせ

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

「画像でゴミ分類!」アプリ作成日誌day7~サイドバーのスライドメニュー化~

はじめに

「画像でゴミ分類!」アプリ作成日誌7日目の今日はサイドバーのスマホ対応ということでHTML,CSS,JavaScriptをガッツリ書いて、横から出てくるスライドメニューを実装していく回です。

<記事一覧>

前回までのあらすじ

前回までの記事では画像認識アプリを実装してDjangoに載せたうえで、Bootstrapを使ってフロントエンドを整えるところまでやりました。サイドバーに関してはスマホの際は非表示にするような設定にしていましたが、それでは味気ないのでボタンをタップしたら表示されるようにしたいと思います。

garbage/templates/garbage/base.html
# トグル用のボタンの設置
        <button class="toggler d-md-none display-toggler-inline" type="button" id="toggler" onclick="Sidebar()">
            <i class="fas fa-bars fa-2x"></i>
        </button>

Font Awesomeを利用してアイコンを設置していきます。d-md-noneというクラスを設定することで、画面が小さい時しか表示しないというのをBootstrapで制御しています。なお、Sidebar()は何もしない関数にしてあります。

次にボタンクリック時に表示されるサイドバーを作っていきます。

garbage/templates/garbage/base.html
<body>
    <div id="side-bar" class="display-sidebar-none d-md-none">
        <div type=button id="close-button" class="mr-1" onclick="Sidebar()">
            ×
        </div>
        <p role="button" class="mb-2 btn border-dark rounded-0 btn-secondary">外部リンク集</p>
        <a href="https://manage.delight-system.com/threeR/web/bunbetsu?menu=bunbetsu&jichitaiId=kashiwashi&areaId=22125&areaName=%2F&lang=ja&benriCateId=7&bunbetsuCateId=7&faqCateId=%2F&howToCateId=&search=%E3%83%9A%E3%83%83%E3%83%88%E3%83%9C%E3%83%88%E3%83%AB&dummy=" class="btn btn-default border-dark mb-1 rounded-0" role="button" target="_blank" rel="noopener noreferrer">分別検索</a>
        <a href="https://manage.delight-system.com/threeR/web/benri?menu=benri&jichitaiId=kashiwashi&areaId=22125&benriCateId=7&bunbetsuCateId=7&faqCateId=%2f&lang=ja" class="btn btn-default border-dark mb-1 rounded-0" role="button" target="_blank" rel="noopener noreferrer">ごみの分け方・出し方</a>
    </div>

これは、ほかの要素にかぶせて使うので、body直下に置いています。3~5行目で閉じるボタンを文字で直接実装しています。それ以降は中身なので、PC版の記述をそのまま利用しています。

そして、CSSは以下のようにすると、ほかの要素の上にかぶせて表示することができます。

garbage/static/garbage/css/style.css
#side-bar{
    position: fixed;
    z-index: 1;
    height: 100vh;
    width: 250px;
    opacity: 0.9;
    background-color: white;
}

#close-button{
    float: right;
    font-size: 400%;
    font-weight: bold;
    height: 90px;
}

positionで固定位置に表示できるようにし、height,widthで大きさを指定します。また、z-indexで前面に表示するようにしています。
閉じるボタンについてもいい感じになるようにしています。

JavaScriptの実装

ここまでで基本的な形はできたので、JSで動きを実装していきます。
まず、JavaScriptで追加・削除するためのクラスを書いていきます。

garbage/static/garbage/css/style.css
.display-sidebar-none{
    transition: all 0.5s;
    left: -250px;
}

.display-sidebar-inline{
    transition: all 0.5s;
    left: 0;
}

.display-toggler-none{
    transition: all 0.3s;
    opacity: 0;
}

.display-toggler-inline{
    transition: all 1.5s;
    opacity: 1.0;
}

やっていることとしては、上二つでsidebarの位置を動かします。こうすることであたかも左から出てきたかのような効果を演出できます。
また、下二つでtoggleボタンの表示非表示を切り替えています。fadeのようなことをしたかったので、透明度を変化させます。
それぞれ、transitionを設定することで、クラスを付与した際に起こる変化をゆっくりにすることができ、視覚的になじみやすく表現することができます。

それではいよいよJavaScriptの実装です。

garbage/templates/garbage/base.html
    <script>
        function Sidebar(){
            document.getElementById("side-bar").classList.toggle("display-sidebar-none");
            document.getElementById("side-bar").classList.toggle("display-sidebar-inline");
            document.getElementById("toggler").classList.toggle("display-toggler-none");
            document.getElementById("toggler").classList.toggle("display-toggler-inline");
        }
    </script>

classList.toggleでクラスがあれば削除し、なければ追加ということを一括で処理しています。

実際に実装できたものは以下のような挙動になります。めっちゃちゃんと動いてる!!!
サイドバー.gif

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【HTML】tableタグのメリットとデメリット

プログラミング勉強日記

2020年11月14日
いつもはtableタグを何気なく使ってたけど、デメリットもあることを知り改めてtableタグの使い方をまとめる。

tableタグとは

 tableタグは名前の通りテーブル(表)を作成するタグ。表の基本的な構造は、<table></table>内に<tr></tr>で表の1行を定義して、さらにその中に<td></td>でセルを定義する。
 テーブルの各セルには見出しを定義するヘッダセルと、データを定義するデータセルがあり、ヘッダセル内のテキストは一般的なブラウザでは太文字でセンタリングされて表示される。

HTML
<table border=1>
    <tr>
        <th>スポーツ</th>
        <th>種類</th>
        <th>考案者</th>
    </tr>
    <tr>
        <td>バスケ</td>
        <td>球技</td>
        <td>ネイスミスによって考案されたスポーツ</td>
    </tr>
</table>

実行結果
image.png

メリット

 テキストなどの一塊になっている要素を段組レイアウトにする場合にはいくつか方法があり、tableタグを用いる方法は以前のWebサイトでよく使われていた。
 そのメリットは、CSSに記述することなく横並びの段組にできることである。細かい記述方法を気にすることなくHTMLファイルに記述するだけで段組を実現できる。また、CSSを使用してvertical-alignプロパティを使用したい場合にはtableタグを用いて実現する。vertical-alignプロパティはインライン要素とテーブルセルのみに使用することで、フォント調整ができるようになる。

デメリット

 修正がしにくいことである。複数人でメンテナンスをする場合に日にちが経過してからコードを見直したときに、マークアップとしてのHTMLの記述と視覚的なスタイル調整としてのCSSが混在した書き方なので、見にくくなってしまう。
 また、新しく段組として追加のカラムを記述したい場合にtableの中に余計な要素などを加えたり、table全てを書き直したり必要が出る場合があり複雑になってしまう。

参考文献

テーブル(表)を作成する
HTMLでtableタグを使わないで段組レイアウトする方法を現役エンジニアが解説【初心者向け】

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

rails6 form_with(ヘルパー)のラジオボタンにCSSを装飾する方法

目的:rails6にてform_withでラジオボタンを実装、それに対してCSSで装飾を行います。

苦戦したこと:ヘルパーを使っていることにより、ラジオボタンの内部構造が見えなくなってしまった。

①他のオプションと違いラジオボタンはclassをセレクタにしてもCSSを反映する事ができない。
②label forが設定されていない事により、選択作業が反映できないバグが発生。

以下、内容を記載。

①ラジオボタンはclassセレクタではCSSが反映されない。

HTML
スクリーンショット 2020-11-14 19.30.25.png

CSS
.second{
font-size: 14px;
font-weight: bold;
display: block; /* ブロックレベル要素化する /
float: left; /
要素の左寄せ・回り込を指定する */
.
.
}

このような記述では全くCSSが反映されません。検証ツールで見てみると、

スクリーンショット 2020-11-14 18.28.39.png

一見OKな気もします。ちなみに、検証ツールで見えるのはヘルパーの記述がHTMLに変換されたものなので、ツール上で修正を加えて正しく動作すればその修正したコードを丸々コピーしてHTML型に変えてしまうのも一つの手です(データの送信自体はHTML形式でも問題なし)。

結論を言ってしまうとラジオボタンにCSSを設定する場合はclassではなくlabel属性に記述をしなくてはいけません。その際、合わせてtype="radio"属性で設定されている標準のラジオボタンの表示を見えなくする必要もあります。

というわけで、

CSS
.fields-label label{
font-size: 14px;
font-weight: bold;
display: block; /* ブロックレベル要素化する /
float: left; /
要素の左寄せ・回り込を指定する */
.
.
}

とし、

input[type=radio] {
display: none; /* ラジオボタンを非表示にする */
}

の記述を加えます。これで外見上は装飾されたラジオボタンのでき上がりです。

スクリーンショット 2020-11-14 18.35.42.png

しかし、実際に入力作業をしてみると問題発生。
ボタンをクリックしたら変色する仕様を以下のように記述したはずが全く動作しません。

input[type="radio"]:checked + label{
background:blue;/* マウス選択時の背景色を指定する /
color: #ffffff; /
マウス選択時のフォント色を指定する */
}

これはtype="radio"属性(labelの要素まで含めて)がクリックされたら指定の動きをする記述です。
再び検証ツールで確認。

スクリーンショット 2020-11-14 18.43.06.png

一見問題が無いように見えます。ちゃんと選択肢事にid、valueも違う値が登録されています。

②label for属性の指定がないことによるlabel要素の読み込みエラー

この原因を特定するのにかなり苦労しましたが、ヘルパーを使わない場合のlabel設定の仕方を確認し、わかりました。

idに対して、label forが設定されていない事で、それぞれの選択肢がうまくVIEWに反映されていなかった。意味わかんないですね、とりあえずidとlabel forが一致して初めてラジオボタンのCSS設定が反映されるという事です。なので、label forにidと同じ値を設定します。
//
スクリーンショット 2020-11-14 19.35.12.png

これが完成形です。
label for="id" 選択肢 /label
の書き方はこの指定となりますので、順番も変えました。

スクリーンショット 2020-11-14 19.05.09.png

このように動作しました。ちなみに検証ツールで確認すると、

スクリーンショット 2020-11-14 19.07.24.png

このようにlabel forが定義されており、idと紐づいている状態です。

※ちなみに、別箇所でcollection_selectでラジオボタンを作っていた箇所は選択肢事の全てのlabel forが同じ値になっており、どれを選択しても最初の選択肢が選択されてしまうというエラーも発生。
railsのフォームヘルパーでラジオボタンを作成する場合はlabel forの設定が必須になると思われますので、注意が必要です。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

HTMLページがHerokuにデプロイできない時の対処法

目次

エラー内容
解決方法

エラー内容

以前『Heroku』にデプロイした際におきたエラー内容です。

!    NO default language could be detected for this app.
HINT: This occurs when Heroku cannot detect the buildpack to use for this application automatically.
See https://devcenter.heroku.com/articles/buildpacks  
!     Push failed 

HTML,CSS,JSファイルだけのアプリケーションはHerokuではアプリケーションとして認識してもらえないみたいです。

解決方法

HTML,CSS,JSファイルのアプリケーションをPHPとして読み込ませる方法です。

追加するファイルは2つです。

index.php と composer.json です。

下記の様に『index.html』のメインページと同じところにファイルを追加しましょう。

111.png

追加しましたら下記の様にコードを追加しましょう。

<!-- index.php -->

<?php include_once("index.html"); ?>
<!-- composer.json -->

{}

再度 commit、push してデプロイできれば成功です。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【初投稿】売れた商品に対して、SoldOutの文字を出力する

条件式でexists?メソッドを使用し、指定したテーブル内のカラム名(item_id)と売れた商品(item.id)が一致したら商品にSoldOutの文字を出力するコードを書きました。

qiita.rb
<% if Order.exists?(item_id: [item.id]) %> 
  <div class='sold-out'>
    <span>Sold Out!!</span>
  </div> 
<% end %>

私のコードの書き方で当たり前なことかもしれませんが、こういう動作をさせたいといいう目的がある場合、今回の動作であれば売れた商品にSoldOutを表示させたいという目的がありました。

その目的に対して、exists?メソッドはいきなり見つけたわけではなく、まず商品を購入してitem_idを商品情報と一緒にorderテーブル保存しているのでitem_idがorderテーブルにあることに気が付きます。

商品のid、item_idを見境なしに判別してしまうのは違うので、orderテーブルにitem_idが存在した場合トップページに存在するitem_idとorderテーブルの中のitem_idを判別してくれればうまくいきそうだなと考え、トップページ商品id、item_idとorderテーブルのitem_idと見比べたいなと思いexists?メソッドにたどり着きました。

文章で書くときはなんとなく順番通り書きましたが、考えている時は初めにorderテーブルのitem_idと見比べるのではないかと思い付きまずさかのぼって考え、答えに至りました。

プログラミングで目的の動作を考える時は、抽象化された目的に対し細かくプロセスを考えることが大切だと分かりました。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

DOM操作とは?【JavaScript】初心者の疑問

どうも、三町哲平です!

以前作成した【JavaScript】分からない部分まとめてみたら最強だった件 - Qiitaの記事は、現在(2020/11/14 時点)なんと25,000PVを超えました!

本当に読んでくれた皆様には、感謝、感謝なのですが、実際私は、確かにJavaScriptの分からない部分はまとめたのですが、JavaScriptに関しては依然素人も素人...

もう超ド素人な訳なんです。

そんな私のJavaScriptの謎の中にDOM操作というものがあります。

JavaScriptの特徴の一つにDOM操作がありますよ!なんて言われても超ド素人からすれば、そのDOMが分からんよ...てな話

では、そのDOMについてのお話。

まずは、ググってみる

Google先生に頼ってみますか。

「ドム とは」

スクリーンショット 2020-11-12 2.17.59.png

え〜っと...

ドム (DOM) は、「ガンダムシリーズ」に登場する架空の兵器。有人操縦式の人型ロボット兵器「モビルスーツ」 (MS) の一種。初出は、1979年放送のテレビアニメ『機動戦士ガンダム』。
引用元:ドム - Wikipedia

なるほど...DOMは、ガンダムに関係あるんですね...。

ドムとは、テレビアニメ『機動戦士ガンダム』に登場するモビルスーツである。
引用元:ドム (どむ)とは【ピクシブ百科事典】

ピクシブ百科事典に答えが載っていましたね。

DOM操作っていうのは、モビルスーツの操作の事だったんですね。

いや〜勉強になりましたね。

では、また!

............

......

...て、おいおい

おふざけは、ここまで

本題です。

ここで終わってたら、流石に怒られますからね...(汗)

「DOM とは」
スクリーンショット 2020-11-12 2.44.03.png

求めていた記事が沢山出てきましたね。

DOMとは?

  • Document 文書、資料
  • Object 物体、対象
  • Model 模型、原型

Google 翻訳では、上記のような日本語訳になります。

文書オブジェクトモデル(DOM)とは、HTML文書およびXML文書のためのアプリケーション=プログラミング=インターフェイス(API)である。これは、文書の論理的構造や、文書へのアクセスや操作の方法を定義するものである。
引用元:DOMとは何か

なるほど...分からん

そんなあなたに↓

オブジェクトのような感じで、HTMLのタグなどにアクセスして、CSSを追加したり、あるいはタグを追加したり・削除したりすることが出来る形のこと
引用元:JavaScriptでDOMを操作する方法【初心者向け】 | TechAcademyマガジン

初心者なりに噛み砕いてみた

JavaScriptの特徴からDOM操作

ここでDOM操作を考えていく上で必要になるのが、JavaScriptって何ができるのかという事です。
JavaScriptと言えば、Node.jsによるバックエンド開発も有名ですが、やっぱりメインはフロントエンドに動きをつけてUI/UXの向上であり、
その時のJavaScriptを使って、HTML表示を変える処理こそが、DOM操作

では、実践で確認していきましょう!

HTMLを書いてみる

index.html
<!DOCTYPE html>
<html lang="ja">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <h1 id="title">アムロ・レイ</h1>
</body>

</html>

スクリーンショット 2020-11-12 16.35.22.png

このHTMLのアムロ・レイ表示をJavaScriptを用いて変更してみましょう!

index.html
<!DOCTYPE html>
<html lang="ja">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <h1 id="title">アムロ・レイ</h1>
</body>

<!-- 追加 -->
<script>
    const h1 = document.getElementById("title");
    console.log(h1);
    h1.textContent = "シャア・アズナブル";
</script>

</html>

スクリーンショット 2020-11-12 16.43.20.png

h1は、アムロ・レイのままですが、JavaScriptの追加によりシャア・アズナブルになりました。
これが、DOM操作です。

何となくイメージは摑んでいただけましたでしょうか?

参考記事:JavaScriptでDOMを操作する方法【初心者向け】 | TechAcademyマガジン

さいごに

この記事は、上記でも書いてある通りDOM操作の何となくのイメージしか掴めないと思います。
詳しい方からすると何でDOM操作を解説する記事なのにツリー構造の説明がないの?ノードのノの字もないぞ!などといった意見はあると思いますが、対象は、そこでは無いことをご了承下さい。

さらにDOMについて気になった方は、個々人で調べてみることをお勧めします。
例えばこの記事とか↓が分かりやすいかと
JavaScript初心者でもすぐわかる!DOMとは何か?

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

HTML・CSSとは

HTML・CSSの役割

HTMLとはウェブページの見た目を作る言語で、CSSはその見た目を整える言語です。
つまり、HTMLはウェブページについての情報を記載する言語であり、CSSは記載した情報をユーザーにとって見やすいものにするための言語です。

それでは実際にどういう感じにプログラムを書くのか見てみましょう。

HTMLの実際のコード

<h1>これは見出しです</h1>

このような感じでHTMlのコードを書いていきます。
重要なのは要素をタグで囲うことです。

タグとは<>このカッコのことで、ここに囲まれている部分が要素です
この例では「これは見出しです」が要素ということになります。
そして、この要素には様々な種類のものがあり、それぞれに役割があります。

例えば、このコードのh1要素は見出しを作る要素です。
h1要素の他にもh2~h6まであり、数が小さくなるほど見出しも小さくなります。
このようにHTMLではタグと要素の関係が基礎となってきます。

CSSの実際のコード

h1 {
 color: red;
}

CSSのコードはこのように書きます。
これは先程のHTMLのh1要素の色を変えるよう指示したものです。

CSSではセレクタ・プロパティ・値の3つのものでプログラムを構成していきます。
それぞれ順に見ていきましょう。

セレクタ・プロパティ・値とは

セレクタとは、CSSによる装飾をどの部分のHTMLに適用するかを選択するものです。
つまり、ここではh1要素に適用しています。

次にプロパティですが、これはセレクタで選択したHTMLの「何を変えるか」を選択するものです。
つまり、ここではh1要素の色を変えるという選択をしています。
この色を変えるプロパティをcolorプロパティといいます。

最後に値ですが、プロパティで何を変えるかを選択したら、どう変えるかといった値を決めないといけません。
ここでは、何:見出しの色 どう変えるか:赤色に変える ということになります。

このようにCSSでは、HTMLの「何をどう変えるか」を選択しており、これによってウェブページの装飾がなされていくのです。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

フォーム入力時に自動で名前やアドレスを補完してくれるアレ

あると便利なこの機能についてです。
スクリーンショット 2020-11-14 2.17.39.png
使う側としても、住所などの長いものが一発ではまると気持ち良いですよね。実装のほんのひと手間でユーザーのフォーム入力の負担を軽減できるのなら、わたしはそれができる大人になりたいと思いました。

autocomplete属性

ひと手間どころか、もはや知っているか知らないかなのですが、input要素にautocomplete属性を割り振るだけというお手軽さです。
下の例では、名前の場合はautocomplete="name"、 メールアドレスの場合はautocomplete="email"としています。

<div class="form">
  <label for="name">名前</label>
  <input id="name" type="text" autocomplete="name">
</div>
<div class="form">
  <label for="email">メール</label>
  <input id="email" type="text" autocomplete="email">
</div>

その他の項目も自動補完に対応させたいよ! という場合はHTML の autocomplete 属性などを参考にすると良さそうです。

おまけ: 自動補完される情報はどこと紐づいているのか

利用者視点のおまけです。
Chromeをお使いの方は、設定 > 自動入力 > 住所やその他の情報 から情報を追加・修正できます。
スクリーンショット 2020-11-14 2.27.57.png
自動補完しようとしてくれる気持ちはありがたいけど、住所とかぐちゃぐちゃなんだよなぁ、と思いながら使っている時が、わたしにもありました。今後はautocompleteの恩恵を、きちんと受けていこうと思います。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

「画像でゴミ分類!」アプリ作成日誌day6~ディレクトリ構成の修正~

はじめに

「画像でゴミ分類!」アプリ作成日誌6日目の今日はディレクトリ構成を修正します。今日は忙しかったこともあり軽めです。

<記事一覧>

前回までのあらすじ

前回までの記事では画像認識アプリを実装してDjangoに載せたうえで、Bootstrapを使ってフロントエンドを整えるところまでやりました。現時点での問題点の一つ目はindexとresultのtemplateファイルで重複した記述が存在していることであり、これはbaseファイルを作成して対応します。2つ目の問題は画像ファイルをHTMLから相対パスで参照してしまっているので、それをstaticフォルダから読めるようにしたいと思います。

base.htmlの作成

indexとresultで重複した記述をbaseに移行します。これは、今後デザインを変更した際にいちいち二つのファイルをいじるのが非効率だからです。

garbage/templates/garbage/base.html
{% load static %}
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>画像でゴミ分類!</title>
    <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.4.2/css/all.css" integrity="sha384-/rXc/GQVaYpyDdyxK+ecHPVYJSN9bmVFBvjA/9eOB+pb3F2w2N6fc5qB9Ew5yIns" crossorigin="anonymous">
    <link rel="stylesheet" type="text/css" href="{% static 'garbage/css/bootstrap.css' %}" />
    <link rel="stylesheet" type="text/css" href="{% static 'garbage/css/style.css' %}" />
</head>
<body>
    <div id="wrapper">
        <button class="toggler d-md-none" type="button" id="toggler" data-toggle="collapse-side" data-target=".side-collapse">
            <i class="fas fa-bars fa-2x"></i>
        </button>
        <img src="{% static 'garbage/media/images/title.png' %}" alt="画像でゴミ分類!" class="m-4 pb-3" id="title">

        <div class="container row">
            <div class="card col-md-4 py-4 px-0 d-none d-md-block h-100" id="sidebar">
                <p role="button" class="mb-2 btn border-dark rounded-0 btn-secondary">外部リンク集</p>
                <a href="https://manage.delight-system.com/threeR/web/bunbetsu?menu=bunbetsu&jichitaiId=kashiwashi&areaId=22125&areaName=%2F&lang=ja&benriCateId=7&bunbetsuCateId=7&faqCateId=%2F&howToCateId=&search=%E3%83%9A%E3%83%83%E3%83%88%E3%83%9C%E3%83%88%E3%83%AB&dummy=" class="btn btn-default border-dark mb-1 rounded-0" role="button" target="_blank" rel="noopener noreferrer">分別検索</a>
                <a href="https://manage.delight-system.com/threeR/web/benri?menu=benri&jichitaiId=kashiwashi&areaId=22125&benriCateId=7&bunbetsuCateId=7&faqCateId=%2f&lang=ja" class="btn btn-default border-dark mb-1 rounded-0" role="button" target="_blank" rel="noopener noreferrer">ごみの分け方・出し方</a>
            </div>

            {% block main %}{% endblock main %}

        </div>

        {% block second %}{% endblock second %}

        <footer>
            <p id="copyright" class="mb-0">Copyright &copy; 2020 eycjur All Rights Reserved.</p>
        </footer>
    </div>
</body>
</html>

冒頭の記述やサイドバーが共通しているもののため、baseにします。{% block main %}{% endblock main %}のところに各ファイルごとの記述が入ります。

では、各ファイルが実際にどうなるかを見てみると、

garbage/templates/garbage/index.html
{% extends "garbage/base.html" %}
{% load static %}

{% block main %}
<div class="col-md-8">
    <div class="container card p-4 h-100">
        <p>分類を調べたい画像を入力してください</p>
        <form action="{% url "garbage:result" %}" method="post" enctype="multipart/form-data">
            {% csrf_token %}
            {{ form }}
            <br>
            <button type="submit" class="mt-3 wait-disappear">調べる!</button>
        </form>
    </div>
</div>
{% endblock main %}

{% block second %}
<h4>既存の画像を利用する</h4>
<div class="container row">
    <div class="col-md-6 p-3">
        <a href='{% url "garbage:result_num" num=1 %}'>
            <img src="{% static 'garbage/media/images/temp1.jpg' %}" alt="画像1" class="sample-img">
        </a>
    </div>
    <div class="col-md-6 p-3">
        <a href='{% url "garbage:result_num" num=2 %}'>
            <img src="{% static 'garbage/media/images/temp2.jpg' %}" alt="画像2" class="sample-img">
        </a>
    </div>
</div>
{% endblock second %}

最低限の部分だけを書くことで、このようにだいぶすっきりしたのが伝わるかと思います。

画像ファイルの配置の修正

完成イメージ

まず、どのようなディレクトリ構成にするかを決めておきます。
今回は以下のような構成にします。

garbage_proj
├garbage_proj
│ └settings.pyなど
├garbage
│ └views.pyなど
└static
  └garbage
   ├css
   │ └style.css
   └media
    └images
    └image.pngなど

staticとmediaのパス

まず、staticとmediaのパスを設定しておきましょう。

garbage_proj/setting.py
STATIC_URL = '/static/'
STATICFILES_DIRS = (os.path.join(BASE_DIR, "static"),)

MEDIA_ROOT = os.path.join(BASE_DIR, 'static/garbage/media')
MEDIA_URL = '/media/'

いま、BASE_DIRは大元のgarbage_projフォルダなので、static,mediaフォルダをそれぞれ指定できていることがわかります。
こうすると、staticディレクトリを読み込むことで利用できるようになるので、templateファイルは<img src="{% static 'garbage/media/images/title.png' %}">のように画像を指定できます。

これをもとに記述してきます。

garbage/templates/garbage/result.html
{% extends "garbage/base.html" %}
{% load static %}

{% block main %}
<div class="col-md-8">
    <div class="container card p-4 px-5">
        <h2 class="m-3">分類結果</h2>
        <img src="{% static 'garbage/media/images/image.png' %}" alt="画像" id="result-img">
        <div class="container">
            <table class="table">
                <tr><th>分類</th><td>確率</td><td>収集曜日</td></tr>
                {% for key, value, day in pred %}
                <tr><th>{{ key }}</th><td>{{ value }}%</td><td>{{ day }}</td></tr>
                {% endfor %}
            </table>
            <a href="{% url "garbage:index" %}">Topへ戻る</a>
        </div>
    </div>
</div>
{% endblock main %}

このように書くと相対パスで記述する必要がなくなるので、ルーティングを統一できます。

garbage/templates/garbage/index.html
{% extends "garbage/base.html" %}
{% load static %}

{% block main %}
<div class="col-md-8">
    <div class="container card p-4 h-100">
        <p>分類を調べたい画像を入力してください</p>
        <form action="{% url "garbage:result" %}" method="post" enctype="multipart/form-data">
            {% csrf_token %}
            {{ form }}
            <br>
            <button type="submit" class="mt-3 wait-disappear">調べる!</button>
        </form>
    </div>
</div>
{% endblock main %}

{% block second %}
<h4>既存の画像を利用する</h4>
<div class="container row">
    <div class="col-md-6 p-3">
        <a href='{% url "garbage:result_num" num=1 %}'>
            <img src="{% static 'garbage/media/images/temp1.jpg' %}" alt="画像1" class="sample-img">
        </a>
    </div>
    <div class="col-md-6 p-3">
        <a href='{% url "garbage:result_num" num=2 %}'>
            <img src="{% static 'garbage/media/images/temp2.jpg' %}" alt="画像2" class="sample-img">
        </a>
    </div>
</div>
{% endblock second %}

garbageアプリのresult_numに対してパラメーターnumを指定して渡しています。また、これを処理するurls.pyは以下のようになっています。

garbage/urls.py
from django.urls import path
from django.conf import settings
from django.conf.urls.static import static
from . import views

app_name="garbage"
urlpatterns = [
    path("", views.index, name="index"),
    path("result", views.result, name="result"),
    path("result/<int:num>", views.result, name="result_num"),
]

result_numに対してはパラメーターを渡しつつ、"result"という同じ関数を割り当てています。

garbage/views.py(一部略)
def result(request, num=0):
    if num:
        img = "./static/garbage/media/images/" + ["temp1.jpg", "temp2.jpg"][num-1]

    else:
        form = UploadPictureForm(request.POST, request.FILES)
        if form.is_valid():
            img = form.cleaned_data["img"]
        else:
            params = {
                "form":UploadPictureForm()
            }
            return render(request, "garbage/index.html", params)

    pred = predict(img)

    params = {
        "img":img,
        "pred":pred
    }
    return render(request, "garbage/result.html", params)

サンプルが選択されたときは既存の画像を利用するようにすることができました。

さいごに

以上のことで、だいぶファイル構造がわかりやすくなったかと思います。今後の開発がだいぶ楽になりそうです!
ちなみに、今回記事を書いていてコードブロックにdjangoという言語の指定ができることを初めて知りました。HTMLのシンタックスハイライトを引き継いだうえでdjango templateも見やすくなっているので非常に便利ですね。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

htmlのaタグのtarget="_blank"だけだと良くない理由を調べてみた

目的

  • HTMLのaタグでrel=noopenerだけを使用するのは良くない理由を自分なりに調べてまとめてみた

そもそも<a href="" target="_blank"></a>って?

  • aタグでtarget="_blank"を指定するとリンク先をブラウザの別タブで開く事ができる。
  • target="_blank"だけだとセキュリティ面出の脆弱性とパフォーマンスに悪影響が有るらしい。

脆弱性

  • リンク先のページにwindow.openerというJavaScriptのオブジェクトが存在していたときに<a href="" target="_blank"></a>が書いてあるリンク元ウインドウの情報が取得されてしまう。またリンク先タブからリンク元タブを制御する事もできてしまう。
  • リンク元タブがリンク先タブによってフィッシングサイトにすり替えられたりしてしまう。

パフォーマンスの低下

  • 難しい言葉で説明すると一つのスレッドに両方のタブの処理が入るので処理が重くなる可能性がある。
  • 簡単に説明すると本来一つのタブ表示に使用している作業スペースでリンク元とリンク先2つのタブの処理を実行しているようなイメージ。リンク先のページに重い処理が合ったときリンク元のページも重くなる。

解決策

  • aタグにrel=”noopener”を追加して<a href="" target="_blank" rel=”noopener”></a>とする。
  • rel=”noopener”を追加することでリンク元タブとリンク先タブを別スレッドで処理してくれる。
  • 別スレッドで処理することでJavaScriptのwindow.openerでリンク元の情報を取得できなくなる。
  • 別スレッドで処理することでリンク先ページに影響されること無くリンク元ページの処理を行うことができる。
  • セキュリティ面で更に強固にしたいならaタグにrel=”noopener noreferrer”と記載する。
  • rel=”noreferrer”はリンク先にリンク元のリンクを渡さないようにする。非通知電話をかけているようなイメージらしい。

結論

  • aタグでリンク先を新しいタブで開かせたいときは<a href="" target="_blank" rel=”noopener noreferrer”></a>と記載しよう
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む