20200218のHTMLに関する記事は11件です。

【HTML&CSS】フッター下部の余白を無くす方法

概要

Webページの画面の高さいっぱいに対して、中身の要素が足りていない場合にはフッターの下に余白ができてしまいます。
この余白を無くしてフッターを最下部にする方法に意外と手こずったことはないでしょうか。
ということで、CSSがどのように反映されるかをしっかり理解してフッター下部の余白を無くす方法を書いていきたいと思います。

フッター下部の余白をなくす方法

早速ですが、解決方法の1つの例が以下になります。

<html>
 <body>
  <div class="wrapper">
   <header>ヘッダー</header>
    <div class="inner">中身</div>
   <footer>フッター</footer>
  </div>
 </body>
</html>
html,body{
     height:100%;
}

.wrapper{
     width: 100%;
     position: relative;
     min-height: 100%;
}

.inner{
     padding-bottom:200px; /*フッターの高さと同じにする*/
}

footer{
     height:200px;
     position:absolute;
     bottom:0;
}

まず、height:100%;の%設定は設定したクラスの親要素に対して適用するものになります。
そのため、htmlから設定していかなければなりません。
htmlをheight:100%;にしているので、bodyをheight:100%;にすればhtmlとbodyの高さが100%になります。

そして、コンテンツを囲んでいるwrapperにmin-heightを設定してあるのが肝です。
私はここをheight:100%;にしていたため、上手く反映されずに時間がかかってしまいました。

もしwrapperをheightで設定した場合は、中身の要素分までしか高さが伸びないので、中身の要素の高さが画面いっぱい分までなければ、footerを最下部にすることができません。
height:100%;にしたとしても中身がなければ、高さは0になります。

しかし、min-heightの場合は最小の高さを指定するので、中身の要素がなくても最小100%の高さが反映されます。
例えば100pxにした場合は要素の中身が高さ50pxでも100pxまで伸びて、要素の中身が高さ150pxであれば、150pxまで伸びます。

そして、wrapperとfooterにpositionを設定し、footerをbottom:0;にすることで、wrapperの中に含まれているfooterはwrapperの最下部に位置します。
このままだとwrapperの中にfooterが被っているのでpadding-bottomをfooterの高さ分設定して、wrapperからfooterを押し出して最下部に配置します。

以上でフッターの下部に余白は無くなると思います。

こういった簡単に思えることで、時間が取られてイライラしてしまっている方の助けになることを祈ります。

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

Flexboxを使ってレイアウトを作りたい

https://qiita.com/takepon_it/items/694636fc139d9ac1109a
↑の記事の続き的な物を書いていきます。

今回はFlexBoxを使って簡単なレイアウトを作っていきます!

1.プロパティについて

FlexBoxってプロパティめちゃくちゃあって結局何使えばいいんだってなりません?
まぁ多分大半の物は"覚えなくても"大丈夫なんじゃないかなぁって思います。
そこで今回の記事でFlexBoxってこうやって使うんだなぁくらいのイメージが出来たらいいです!

2.完成品のイメージ

image.png

こんな感じでブログの記事一覧みたいな物を作っていきます!

3.早速コーティングしていこう!

index.html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset=UTF-8">
<title>FlexBox</title>
<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body>
<div class="group">
    <div class="box">
        <img src="ここに画像">
        <h1>好きなタイトル</h1>
        <p>好きな文</p>
    </div>

    <div class="box">
        <img src="ここに画像">
        <h1>好きなタイトル</h1>
        <p>好きな文</p>
    </div>

    <div class="box">
        <img src="ここに画像">
        <h1>好きなタイトル</h1>
        <p>好きな文</p>
    </div>
</div>
</body>

htmlの記述はこんな感じでいいです!
ここは特に説明する箇所もないので早速CSSの方に移ります!

4.CSSもかいていこう!

style.css
.group {
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;
}

.box {
/*ここは自分の好きなようにしてください!*/
}

CSSはこうです!
これを解説していくと

image.png

まず.groupっていう箱を作りたいので
display;flex
で.groupを箱にします(親要素という)

①の説明をしますね
これは
flex-wrap: wrap;
というプロパティを使っていて、何故これを使うのかと説明すると
親要素にしたばかりで何もしないと、只々横一列に並ぶだけなんですよね。
しかしこのプロパティを指定して親要素にwidth等を指定すると、下にいくようになります!便利ですね!

そして②の説明ですが、これは図が汚すぎて申し訳ないんですが等間隔っていうことを伝えたい矢印です!
justify-content: space-between;
を使うことによって横並びになっているアイテムを等間隔に設置してくれるめちゃくちゃ便利なプロパティです!
一々margin等を使わなくても綺麗に揃えれるということですね!

この二つのプロパティを使うことによって、完成図みたいなブログの記事一覧っぽい画面を作れました!
.boxはご自身の好みで作ってみてください!

4.最後に

どうでしたでしょうか?
FlexBoxを使えば簡単に綺麗にレイアウトを作れることが分かったと思います。
今回紹介したプロパティは本当にごく一部なものですが、それだけでも十分にいい感じの物が作れます!

この記事が自分と同じような初学者の参考になったらうれしいです!

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

フォントサイズの定義の仕方について

フォントサイズをコードで書いている中で、emやrem、%が出てきたのでその関係について調べました。

定義方法

フォントサイズの定義方法は、絶対値と相対値の2つがあります。

  • 絶対値:他の要素に依存せずに定義される。px
  • 相対値:他の要素によって定義される。%、em、rem、vw、vh

それぞれのフォントサイズの定義について

px

絶対値での指定となるので、どのデバイスでも、同じピクセルサイズで表示されます。

%

考え方:「親要素の◯%」となります。
stylusで書くとこのような感じです。

html
  font-size 20px

p
  font-size 50% /* これは10pxになる */

em

考え方:「親要素の◯」となります。
基本的には%と同じ考え方で、小数点で考える点だけが違う点となります。
emは、アルファベットの大きさのベースとなる「M」に由来しているとのことです。

html
  font-size 20px

p
  font-size 0.5em /* これは10pxになる */

rem

考え方:「もととなっている要素の◯」となります。
emに「root」のrを足したのがこのremで、親要素が複雑でわかりにくくなった場合も基準点を同じにしておくことで簡単に対応できるのがメリットになります。
ルート要素とはhtml要素のフォントサイズのことです。

html
  font-size 100% /* 100%は16pxになる */

div
  font-size 2em /* これは32pxになる */

vw

考え方:「画面幅の◯」となります。
vwは「viewport width」の略で、ビューポートの幅に対してどれくらいの幅にするのかを定義しています。
画面幅によって細かく文字サイズを調整できるので、目立つ文字列に使用されたりします。

p
  font-size 0.05vw /* 画面幅が1000pxのとき、50pxのフォントサイズ。500pxの画面幅のとき、25pxのフォントサイズ */

どのように使うのが良いのか

ブラウザごとにフォントの大きさを変える必要がない場合は、remやemで書くのが良いでしょう。
remかemかはその状況にもよります。

基準となるフォントサイズを font-size = 62.5% とすると、そのフォントサイズを10pxにすることができます。

ですので

html
  font-size 62.5% /* これで基準が10pxになる */

h1
  font-size 3rem /* h1は基準の3倍、つまり30pxになる */

とすることができます。
これで、かなり使いやすく、かつ変更にも強いフォントサイズを作ることができます。

また一つ学びました。

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

ブックマークレット初心者がWEBサイト入力を自動化するためにやったこと

概要

自動化したいWEBサイトのHTMLを確認して、Bookmarkletを作ってみた。
検索窓に文字列を入れたり、POSTしたり、Amazonから本のタイトルコピーしたりできるようになった。デバッグツールの使い方も少し知ることができた。
今回、題材にしたサイト以外でも同じように対応できるはず。

はじめに

Bookmarkletを自分で作ってみた。今までは、検索して同じことしようとしてる人を見つけてコピペして登録してた。今回、やりたいことが見つからなかったので、自分で作ってみた。HTTPもHTMLもJavaScriptもなんとなく知ってるくらいだったけれど、なんとかなった。

やりたいこと

市の図書館のWEBサイトが微妙なので、もうすこし楽に(クリック少なめで)検索と予約したい。(一応書いておくと、WEBで予約できるの便利で活用してる。とても感謝してる。)

環境

ブラウザはChrome。
image.png

デバッグ環境

ここを参考にした。ちゃんとデバッグできる。すばらしい。
Chrome Dev Toolでブックマークレットを実行する - Qiita

ChromeのCtrl+Shift+Iで開くDeveloper Toolsを開く。
Consoleにコピペしてエンターキー。console.log()とか使える。エラーの行番号もでる。ブレークポイントも設定できる(らしい)。試してみると、すごく簡単。実際に使うときと同じChrome環境で動くので、安心感すごい。

image.png

自動化したいWEBサイトの中身を調べる

Developer Tools使ったり、Ctrl+uでHTMLのソースコード見たりして自動化したい部分のformとかinputを確認する。今回、対象にしたサイトが割と古いからか、HTMLにそのまま色々書かれてた。

ただ、自動化したかったサイトはauthenticity_tokenってのが毎回変わる。結構、やっかいやった。
検索がHTTP GETじゃなくてHTTP POSTなのも微妙やった。一度、このサイトを開いてauthenticity_tokenってのを確認してPOSTしないと検索できない。予約もおんなじようなシステム。Bookmarkletじゃ他のサイトから直接検索したり予約できなかった。残念。

サイトとHTMLは、こんな感じ↓
image.png

コードを短くする

GoogleのClosure Compilerってのを使うと短くしてくれる。デバッグもできる(らしい)。
image.png

Closure Compiler Service

登録

適当にブックマークとして登録。URL部分にコピペ
image.png

Bookmarklet

いくつか試したものを抜粋。

Amazonの本のタイトルを取得

HTMLを確認するとtitleに著者名とかが入ってて|で区切られてる。本のタイトルだけ取得して、コピーする(クリップボードに入れる)。
(ここで取得した本のタイトルを図書館のサイトの検索窓に入れたかったけど、あんまり自動化できなくて結局手動でやることにした。)

javascript:(
    function(){
      const title = document.title;
      var title1 = title.split('|');
      console.log('ページタイトル=%s\n', title1[0]);
      alert('ページタイトル:'+title1[0]);

      var tmp = document.createElement('p');
      var pre = document.createElement('p');
      pre.style.userSelect = 'auto';
      tmp.appendChild(pre).textContent = title1[0];
      document.body.appendChild(tmp);
      document.getSelection().selectAllChildren(tmp);
      document.execCommand('copy');
    }
)();

image.png

検索窓に文字列を挿入

formの名前を確認して、とりあえず適当にテキストを入力してみた。普通に動いた。
(結局使わなかった。クリップボードからペーストもできそうやったけど、あんまり自動化できてないしやめた。)

javascript:(
    function(){  
      document.forms['search_form'].elements['keywords'].value = 'test';
    }
)();

まじめにformとinputを設定してsubmit

formに紐づくinputを全部、自分で設定してPOSTするパターン。結構めんどい。
var request部分をコメントアウトしたら、最後にappendしたものしか送られていなかった。変数を再利用できてなさそう。JavaScriptってそういうもんなんかな?

javascript: (
    function postForm() {
        var form = document.createElement('form');
        form.method = 'POST';
        //    form.accept-charset = 'UTF-8';                                                                                          
        form.action = 'https://xxx';

        var request = document.createElement('input');
        request.name = 'y';
        request.value = 'z';
        form.appendChild(request);

        var request = document.createElement('input');
        request.name = 'a';
        request.value = 'b';
        form.appendChild(request);
        form.submit();
    }
)();

formを取得して、inputを追加してsubmit

HTMLにかかれているformを再利用する。一部ユーザ入力によって変わる部分があったので、そこだけ追加。formに名前とかIDがついていなかったので、何番目のformかを指定した。x[2]の部分。3番目。

javascript: (
    function postForm() {
        var x = document.getElementsByTagName("form");
        var request = document.createElement('input');
        request.name = 'commit';
        request.value = '予約';
        x[2].appendChild(request);
        x[2].submit();// Form submission                                                                                              
    }
)();

ページ遷移後のスクリプト

一度、POSTして新しいページに行ってから、別のスクリプトを実行したかったけれど、Bookmarkletじゃできなさそうやった。残念。Chrome拡張でなんとかしようかなぁ。

おわりに

作りたいもの駆動で勉強できてよかった。
デバッグツールがあったので、試しながら作れたのが良かった。
HTTPとかHTMLとかJavaScriptの知識がもうすこしあれば、もっとスムーズに作れるかもしれない。
でも、ちょっと自動化したいだけだったので、ちょうど良い感じで学べた気がする。
複数ページにまたがって自動化したかったけれど、調べた限りできないみたいやった。残念。
次は、Chrome拡張でも作ってみよっかな。

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

textareaの右下のスタイルを1行で消す

目的

textareaのこのチョンチョンを消すcssを毎回忘れるのでメモをソッと残しておきます

スクリーンショット 2020-02-18 19.43.56.png

解決法

textarea {
  resize: none;
}

結果

スクリーンショット 2020-02-18 19.46.21.png
無事に消えましたっ

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

【CSS】フォームのセレクトボックスに角丸などのスタイルを適用する

概要

フォーム要素の<select>のスタイルを変更するため、元のスタイルを非表示にしてからスタイルを適用した。元のスタイルを表示しない場合矢印も消えるため、独自の矢印を表示する方法もあわせて調べた。

デフォルトの<select>は以下のようになる。

HTML
<select name="sample" id="select" class="select">
  <option value="" default></option>
  <option value="1">option1</option>
  <option value="2">option2</option>
  <option value="3">option3</option>
</select>

スクリーンショット 2020-02-18 11.24.22.pngスクリーンショット 2020-02-18 11.24.29.png

そのままスタイルを変更してみる

デフォルトのスタイルから、

  • 幅・高さ
  • 枠線の色や太さ・角丸
  • 背景色
  • 文字の色や大きさ

を変更してみる。

SCSS
.select {
  width: 150px;
  height: 50px;
  border: 3px solid #FF0000;
  border-radius: 20px;
  background-color: #FFFF00;
  color: #0000FF;
  font-size: 20px;
}

     ←Chrome Firefox→
スクリーンショット 2020-02-18 11.31.30.pngスクリーンショット 2020-02-18 11.31.37.png

Chromeの場合は角がborder-radiusで指定した値になっていない(他の値を指定しても変わらず)。
Firefoxでは、矢印部分が違和感のあるスタイルになってしまう。

<select>のスタイルを消す

そこで、元々の<select>のスタイルが表示されないようにして、その上から好きなスタイルを適用することにする。
appearance: none;を指定することで元々のスタイルを無効にできる(ベンダープレフィックスが必要)。

SCSS
.select {
  &::-ms-expand {
    display: none; // IE
  }

  -webkit-appearance: none; // Chrome, Safari (Firefoxでも効いた)
  -moz-appearance: none; // Firefox
  appearance: none;

  border: 3px solid #FF0000;
  border-radius: 20px;
  width: 150px;
  height: 50px;
  background-color: #FFFF00;
  color: #0000FF;
  font-size: 20px;
}

     ←Chrome Firefox→
スクリーンショット 2020-02-18 12.16.24.pngスクリーンショット 2020-02-18 12.17.27.png

これで、意図したスタイルを適用できるようになった。

再び矢印を表示する

元々のスタイルを打ち消したことで、矢印が表示されなくなり、セレクトボックスかどうか少し分かりづらくなった。そこで、改めてそれっぽい矢印を表示することにする。
::before::afterで作成するのが簡単だが、<select>には追加できない。そのため、<div>等で<select>を囲み、その<div>に擬似要素を追加する。

SCSS
.select-container { // div要素
  overflow: hidden;
  position: relative; // ::before要素をabsoluteで表示するため

  &::before {
    position: absolute;
    top: 50%;
    right: 15px;
    transform: translateY(-50%);
    content: "▼"; // これだけでもそれっぽい下三角矢印にできる
  }

  border: 3px solid #FF0000;
  border-radius: 20px;
  width: 150px;
  height: 50px;

  .select {
    width: 100%;
    height: 100%;

    &::-ms-expand {
      display: none;
    }

    -webkit-appearance: none;
    -moz-appearance: none;
    appearance: none;

    background: #FF0000;
    border: none; // noneにしないと見えてしまう
    padding: 0 20px;
    color: #0000FF;
    font-size: 20px;
  }
}

スクリーンショット 2020-02-18 13.02.57.png

<select>widthheightを指定しない場合、以下のようになってしまう。
スクリーンショット 2020-02-18 13.07.17.png

borderで三角を作る

::before::afterborderを利用して、矢印を表示してみる。
要素のwidthheightを0にしてborderを表示すると、以下のように三角ができる。

SCSS
  &::before {
    position: absolute;
    top: 50%;
    right: 15px;
    transform: translateY(-50%);
    content: "";
    width: 0;
    height: 0;
    border-top: 15px solid #555555;
    border-left: 15px solid #FF00FF;
    border-right: 15px solid #ABCDEF;
    border-bottom: 15px solid #000000;
  }

スクリーンショット 2020-02-18 13.23.53.png

これを利用して、下三角矢印を表示する。

SCSS
.select-container {
  &::before {
    position: absolute;
    top: 50%;
    right: 15px;
    transform: translateY(-50%);
    content: "";
    width: 0;
    height: 0;
    border-top: 15px solid #555555;
    border-left: 10px solid transparent;
    border-right: 10px solid transparent;
  }
}

スクリーンショット 2020-02-18 13.15.06.png

2つ組み合わせて上下矢印を作成することもできる。

SCSS
.select-container {
  &::before {
    position: absolute;
    top: 27%;
    right: 15px;
    content: "";
    width: 0;
    height: 0;
    border-bottom: 10px solid #00FF00;
    border-left: 7px solid transparent;
    border-right: 7px solid transparent;
  }

  &::after {
    position: absolute;
    top: 54%;
    right: 15px;
    content: "";
    width: 0;
    height: 0;
    border-top: 10px solid #00FFFF;
    border-left: 7px solid transparent;
    border-right: 7px solid transparent;
  }
}

スクリーンショット 2020-02-18 13.12.55.png

矢印部分をクリックできるようにする

現状では、矢印部分をクリックしても<select>が反応しない。
select-pointer.gif
そこで、pointer-events: none;を指定して擬似要素のクリックを無効にする。

SCSS
.select-container {
  &::before {
    position: absolute;
    top: 50%;
    right: 15px;
    transform: translateY(-50%);
    content: "▼";
    pointer-events: none;
  }
}

select-pointer-ok.gif
矢印部分もクリックできるようになった。

まとめ

  • appearance: none;で元の<select>のスタイルを表示しないようにして、新たにスタイルを適用した。
  • 擬似要素で矢印を表示した。

最終形態


See the Pen
select
by mmmmk (@mmmmmmk)
on CodePen.


参考

https://copypet.jp/797/

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

タッチイベント(マルチ対応)JavaScript サンプルコード

タッチイベント(マルチ対応)JavaScript サンプルコード

簡潔で理解しやすいタッチイベント(マルチ)のコードが見当たらなかったので、
以下のページを参考にリファクタリングしてみた。

https://developer.mozilla.org/ja/docs/Web/API/Touch_events

https://mdn.mozillademos.org/ja/docs/Web/API/Touch_events$samples/Example

タッチイベントで渡ってくる情報って、ev.pageX, _ev.pageY なのね、、、使いにくいなぁ。
具体的には「そのまま canvas に描くとマージンの分描画位置がズレる」という問題がある(元のコードから)。どうしたものか、、、。
(以下のコードはそのズレの対策はしていないです。なぜ、
ev.offsetX, _ev.offsetY をくれないのか、、、)

リファクタリングした結果

リファクタリングした結果がこちら。

ご注意:
・スマホのブラウザで確認しないとタッチイベントは発生しないことにご注意ください
・PCのブラウザで起動した場合でも動作が確認できるように mousemove イベントのみ拾っていますが、あくまで確認用(メインのコードではない)なのでこちらもご注意ください

https://codepen.io/yamazaki3104/pen/QWbbBOK

See the Pen Javascript-touch-event-test by yamazaki.3104 (@yamazaki3104) on CodePen.

コードはこちら、参考まで

参考にしたコードの原型をとどめていないのは、、、、あえて触れないでおこう。いや、すでに「同じ機能」ではなくなっているから「リファクタリング」とは言えないのではないか??

<!DOCTYPE html>
<html><body>
<canvas id="canvas" width="600" height="600" style="border:solid black 1px;">
Your browser does not support canvas element.
</canvas>
<script>

class PointTable // 描画用の色と座標を覚えるためのクラス
{
    constructor( _table_max = 10 ) {
        this.color = []
        this.x = []
        this.y = []
        this.table_max = _table_max
        for ( let i=0 ; i<_table_max ; i++ ) {
            this.color.push( `hsla( ${ i / this.table_max * 360 }, 100%, 33%, 0.8 )` )
            this.x.push( 0 )
            this.y.push( 0 )
        }
    }

    get_idx( _i ) {
        const i = ( _i < 0 ? -_i : _i ) // abs
        return i % this.table_max
    }

    get_color( _tc ) {
        const r = this.get_idx( _tc.identifier )
        return this.color[r]
    }

    get_xy( _tc ) {
        const r = this.get_idx( _tc.identifier )
        return { x: this.x[r], y: this.y[r] }
    }

    set_xy( _tc ){
        const r = this.get_idx( _tc.identifier )
        this.x[r] = _tc.pageX
        this.y[r] = _tc.pageY
    }
}

const xy_tbl = new PointTable()
const elm = document.querySelector( 'canvas#canvas' )
const ctx = elm.getContext( '2d' )

// changedTouches を回す。 Array ではなく Object なんですよ。 Why?
const for_touches = ( _evt, _fnc ) => {
    for ( let i=0 ; i<_evt.changedTouches.length ; i++ )
        _fnc( _evt.changedTouches[i] )
}

const ctx_draw_line = ( _t ) => {   // ctxに線を描く
    const p = xy_tbl.get_xy( _t )
    ctx.beginPath()
    ctx.moveTo( p.x, p.y )
    ctx.lineTo( _t.pageX, _t.pageY )
    ctx.lineWidth = 4
    ctx.strokeStyle = xy_tbl.get_color( _t )
    ctx.stroke()
    xy_tbl.set_xy( _t )
}

elm.addEventListener( "touchstart", ( _evt ) => {
    _evt.preventDefault()
    for_touches( _evt, ( _t ) => xy_tbl.set_xy( _t ) )
}, false )

elm.addEventListener( "touchmove", ( _evt ) => {
    _evt.preventDefault()
    for_touches( _evt, ( _t ) => ctx_draw_line( _t ) )
}, false )

elm.addEventListener( "touchend", ( _evt ) => {
    _evt.preventDefault()
    for_touches( _evt, ( _t ) => {
        ctx_draw_line( _t )
        ctx.fillStyle = xy_tbl.get_color( _t )
        ctx.fillRect( _t.pageX - 4, _t.pageY - 4, 8, 8 )
    })
}, false )

//----------------
// PC用 mousemove イベントでの動作確認コード

elm.addEventListener( "mousemove", ( _evt ) => {
    _evt.preventDefault()
    ctx_draw_line( { identifier: 0, pageX: _evt.pageX, pageY: _evt.pageY } )
}, false )

</script>
</body>
</html>

canvas でできること

このサンプルコードでは、タッチイベントの結果をシンプルに表現するために、canvas に描画している。
canvas でできることは、このあたりにまとまっています。参考まで。

https://developer.mozilla.org/ja/docs/Web/API/CanvasRenderingContext2D

まとめ

コードを見ていただければ、かなり短いし、特に解説するほどではないいけど、

・changedTouches とかに複数の情報がまとまって渡っていくるところがタッチイベントのポイント
・で、changedTouches は Array ではなく Object なところもポイント(Arrayにしてほしいなぁ もっと簡潔に書きたいから)
・あとは、offsetX, offsetY が「無い」ところもポイントかな(いつかサポートされるのでしょうか、、、遠い目)

・情報保存用のクラス、PointTable の _table_max は 10 にしてるけど、もっと少なくてもいいかもしれない。3点以上来てもどう処理していいかわからないしね。

このコードが、みなさまのプログラミングライフの一助になれば幸いです。

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

Javascriptで動的にファイルを読み込む

はじめに

ウェブサイトで外部ライブラリを読み込むというのはよくやる行為だが、それが多くなってきたり、外部ライブラリを踏み台に自作ライブラリを作る(&同じサイト内で使い回す)となると読み込みの管理も大変になってくる。
ので、その辺を自動化する関数を作ってみた。

headに読み込みリンクを生成する

二重読み込みの防止装置もつけてある。

javascript
function insert_link(tagname, obj, raw_url){

    // 差し込む要素の生成
    var target_tag = document.createElement(tagname);
    var keylist = Object.keys(obj);
    var currentkey;
    for(let int = 0; int < keylist.length; int++){
        currentkey = keylist[int];
        target_tag[currentkey] = obj[currentkey];
    }

    // その要素がhead内にすでに存在するかどうかチェックし、存在しない場合のみ読み込みを行う
    var head = document.querySelector('head');
    var headtext = head.innerHTML;
    var processed_url = raw_url.replace(/\//g, '\\/');
    processed_url = processed_url.replace(/\./g, '\\.');
    var regexstr = new RegExp( '=["\']' + processed_url + '["\']', 'g');
    if(!regexstr.test(headtext)){
        head.appendChild(target_tag);
    }
    return target_tag;
}

使用例

html
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="utf-8">
    <title>無題</title>
</head>
<body>

<script type="text/javascript">
(function(){

function insert_link(tagname, obj, raw_url){

    // 差し込む要素の生成
    var target_tag = document.createElement(tagname);
    var keylist = Object.keys(obj);
    var currentkey;
    for(let int = 0; int < keylist.length; int++){
        currentkey = keylist[int];
        target_tag[currentkey] = obj[currentkey];
    }

    // その要素がhead内にすでに存在するかどうかチェックし、存在しない場合のみ読み込みを行う
    var head = document.querySelector('head');
    var headtext = head.innerHTML;
    var processed_url = raw_url.replace(/\//g, '\\/');
    processed_url = processed_url.replace(/\./g, '\\.');
    var regexstr = new RegExp( '=["\']' + processed_url + '["\']', 'g');
    if(!regexstr.test(headtext)){
        head.appendChild(target_tag);
    }
    return target_tag;
}

// 使うときは、キーを属性名、値を属性値としたオブジェクト(下のやつ)に設定を書き込みます
// CSSファイルの場合
var list01 = {
    rel: "stylesheet",
    href: "https://example.com/css/style.css",
}

// Jsファイルの場合
var list02 = {
    type: "text/javascript",
    charset: "UTF-8",
    src: "https://example.com/js/testscript.js",
}


// 引数は左から順にタグ名、設定オブジェクト名、読込先です。
insert_link('link', list01, list01.href);

// 上で挙げた通り、既に読み込まれているときは自動で処理中止してくれます。
insert_link('link', list01, list01.href);


// Jsの場合
insert_link('script', list02, list02.src);

// 上で挙げた通り、既に読み込まれているときは自動で処理中止してくれます。
insert_link('script', list02, list02.src);


})();
</script>
</body>
</html>

実行例

1581988906989.jpg

読み込みが完了したのを確認してから処理を実行

実は、上のコードだけだとある問題が発生する。
ライブラリの読み込みが、本命のjavascriptよりも後になってしまうのだ。
これでは、せっかく読み込んだライブラリを利用したコードを書いてもエラーになってしまう。

これを防ぐため、実際のコードでは以下の文を付け足して使う。

javascript
// insert_linkが実行された時点で、ライブラリの読み込み処理は終わっています。
var madedom = insert_link('script', list02, list02.src);

madedom.onload = function(){

    /* ~~ライブラリの読み込み完了後に行いたい処理をここに書く~~ */

}

onloadを使うことで、読込みの完了を待つことができるのだ。
多少速度は落ちるが、エラーが出るよりかはマシだろう。

全体のコード

html
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="utf-8">
    <title>無題</title>
</head>
<body>

<script type="text/javascript">
(function(){

function insert_link(tagname, obj, raw_url){

    // 差し込む要素の生成
    var target_tag = document.createElement(tagname);
    var keylist = Object.keys(obj);
    var currentkey;
    for(let int = 0; int < keylist.length; int++){
        currentkey = keylist[int];
        target_tag[currentkey] = obj[currentkey];
    }

    // その要素がhead内にすでに存在するかどうかチェックし、存在しない場合のみ読み込みを行う
    var head = document.querySelector('head');
    var headtext = head.innerHTML;
    var processed_url = raw_url.replace(/\//g, '\\/');
    processed_url = processed_url.replace(/\./g, '\\.');
    var regexstr = new RegExp( '=["\']' + processed_url + '["\']', 'g');
    if(!regexstr.test(headtext)){
        head.appendChild(target_tag);
    }
    return target_tag;
}

// Jsファイルの場合
var list02 = {
    type: "text/javascript",
    charset: "UTF-8",
    src: "https://example.com/js/testscript.js",
}

// Js
var madedom = insert_link('script', list02, list02.src);

madedom.onload = function(){

    /* ~~ライブラリの読み込み完了後に行いたい処理をここに書く~~ */

}

})();
</script>
</body>
</html>

おわりに

間違いなどありましたら編集リクエストおねがいします。

参考文献

https://qiita.com/ykob/items/6e4d0b07bed57881a2bd

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

初心者によるプログラミング学習ログ 242日目

100日チャレンジの241日目

twitterの100日チャレンジ#タグ、#100DaysOfCode実施中です。

すでに100日超えましたが、継続。

100日チャレンジは、ぱぺまぺの中ではプログラミングに限らず継続学習のために使っています。

242日目は、

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

flexboxを使用してグリッドレイアウトを実装することになった僕

今日の内容について

これは、2ヶ月前くらいの話です。
IE対応でflexboxを使用してグリッドレイアウトを実装することになった僕がいました。

自分で考えてやってもできるが
「考えるの面倒くさいし調べてコピペしよー」と思い、
「flexbox grid layout」「display:flex grid layout」と検索していたがflexboxとcss gridの使い分けの記事ばかりでした。

なので、
「自分と同じ、めんどくさがり屋の人にこの記事を残そう」ってことです。
(つまり、「flexbox grid layout」「display:flex grid layout」で検索したら見つかるといいね)

書いてみた。

See the Pen grid-layout by pokocy (@pokocy) on CodePen.

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

初心者のうちに知っときゃよかったCSSセレクター

今回の話って誰向き?

この記事の内容は、CSSセレクターを初めて使う人、初心者にはぜひ見てほしい...
(初心者じゃなくても復習がてら見ていただきたいです。)

今になって、初めてCSSセレクターを使用したときに、
知っていればよかった
知っていたがこんなに使用するものだと思っていなかった
と感じたものを紹介していきます。

CSSセレクター3つ紹介

今回、紹介するものは3点!
1..A.B
2..A:nth-child()
3..A + .B

では、さっそく...

1..A.B

こいつ、すごい出てきたんですけど、そんなに重要なものだと思っていなかった。
君の存在は知っていたんだよ....

何がめちゃめちゃ使えるポイントかって?
とりあえず使用例を見てみようー.........

.button {
  width: 200px;
  background-color: red;
  border-radius: 4px;
}

.button.is-small {
  width: 100px;
}

.button.is-large {
  width: 300px;
}

.button.is-blue {
  background-color: blue;
}

.buttonにクラスを一つ追加するだけで大きさや背景色を変更することができる。
また、.button.is-smallとクラス名が2つ続いていたら、.button.is-smallwidth: 100px;が適用される。(.buttonwidth: 200px;は上書きされてるよ。ディベロッパーツールで見たらwidth: 200px;ってなってる。)

2..A:nth-child()

<div class="box">
  <p>サンプルテキスト<p>
  <p>サンプルテキスト<p>
  <p>サンプルテキスト<p>
</div>


<style>
.box:nth-child(2) {
  font-size: 20px;
}
</style>

上記の例では.boxの2番目の子要素のみにスタイルを適用することができる。

:nth-child() ←( )内に記載する値によって、該当箇所のスタイルを変更することができる。

詳しくはこちら

3..A + .B

こいつを知ったときはマジですごいと思った。
使用例は

<ul class="box-list">
  <li class="box-list-item">
    <div class="box"></div>
  </li>
  <li class="box-list-item">
    <div class="box"></div>
  </li>
</ul>

<style>
.box-list-item + .box-list-item {
 margin-top: 30px;
}
</style>

.box-list-itemの後に.box-list-itemが書かれてたら、margin-top: 30pxをとる。

CSSを勉強し始めの時に、覚えておけばもっと楽に実装できた箇所があったかもしれない。。。。

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