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

【IE10以降】テキストボックスの幅が81px以下だと「×」ボタンが表示されない

はじめに

IE10以降ではテキストボックス(<input type="text">)にフォーカス時、入力されている値をクリアする「×」ボタンが表示されるようになっています。しかし業務中に「×」ボタンが表示されないテキストボックスを見つけ、改修に手間取ったため備忘も兼ねてメモです。

事象

IE11にてテキストボックスに入力されている値をクリアする「×」ボタンが表示されません。

結論

IE10以降の仕様で、テキストボックスの幅が82px以上だと「×」ボタンが表示され、81px以下だと表示されません。

検証

環境

  • Windows7 64bit
  • Internet Explorer 11

※Windows10でも検証済みだが会社PCのためエビデンスなし

テキストボックスの幅(width)を81pxと82pxで比較

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Sample</title>
</head>
<body>
    81px <input type="text" style="width:81px"><br><br>
    82px <input type="text" style="width:82px"><br>
</body>
</html>

width : 81px

IE_input_type_width81px.png

width : 82px

IE_input_type_width82px.png

まとめ

IE10以降の仕様として、テキストボックス(<input type="text">)に「×」ボタンが表示されなくなる幅(width)の境界値は81pxです。

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

子要素のmarginが親要素に適用されて困惑;゚д゚) #marginのはみ出し

親要素のcssにoverflow: hidden;で解決

親要素と子要素を設置
スクリーンショット 2020-05-27 17.25.58.png

index.html
<body>
    <div class="box1">
        <div class="box2"></div>
    </div>
</body>
style.css
.box1 {
    width: 400px;
    height: 400px;
    background-color: #bae8e8;
}
.box2 {
    width: 200px;
    height: 200px;
    background-color: #ffd803;
}

親要素からの余白が欲しいので
子要素にmarginを追加

style.css
.box2 {
###
    margin: 50px;
###
}

すると
スクリーンショット 2020-05-27 17.25.49.png
オーマイガー;゚д゚)
親要素の淵からの余白が欲しかったものの、仕様なのか、縦の余白は親要素の外側に適用される。

親要素にoverflow: hidden;を指定

style.css
.box1 {
###
    overflow: hidden;
###
}

すると
スクリーンショット 2020-05-27 17.25.33.png
思い通りの結果に


プログラミング初心者です。
ログイン画面のレイアウト作成中、ログインフォームのボックスにmarginを指定したら、背景のスタイルが崩れてしまい、なかなか思い通りに余白が設定できなかったので、今回はその覚書きとしました。

参考
親要素からはみ出してmarginが適用される対策
CSSリファレンス overflow …… はみ出た要素の表示方法を指定する


サンプルコード

index.html
<!DOCTYPE html>
<html>
<head>
    <title>Overflow</title>
    <link rel="stylesheet" type="text/css" href="style.css">
</head>
    <body>
        <div class="box1">
            <div class="box2"></div>
        </div>
    </body>
</html>
style.css
* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}
body {
    background-color: #e3f6f5;
}
.box1 {
    width: 400px;
    height: 400px;
    background-color: #bae8e8;

    /*親要素に追加*/
    overflow: hidden;
}
.box2 {
    width: 200px;
    height: 200px;
    background-color: #ffd803;

    /*子要素に追加*/
    margin: 50px;
}

ちなみに、親要素にテキストが含まれていたりmarginやpaddingが指定されていると、overflow: hidden;を指定しなくても余白がはみ出ることはないみたいです。
スクリーンショット 2020-05-27 18.02.55.png

style.css
.box1 {
    width: 400px;
    height: 400px;
    background-color: #bae8e8;

    /*  overflowの指定なし*/
}
.box2 {
    width: 200px;
    height: 200px;
    background-color: #ffd803;

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

【HTML/CSS】子要素のmarginが親要素に適用される #marginのはみ出し

こんなお悩みに

marginを指定したら、背景もろとも余白が生まれて思い通りに設定できない
子要素にmargin指定したのに、親要素が子離れしないでついてくる

親要素のcssにoverflow: hidden;で解決

親要素と子要素を設置

スクリーンショット 2020-05-27 17.25.58.png

index.html
<body>
    <div class="box1">
        <div class="box2"></div>
    </div>
</body>
style.css
.box1 {
    width: 400px;
    height: 400px;
    background-color: #bae8e8;
}
.box2 {
    width: 200px;
    height: 200px;
    background-color: #ffd803;
}

子要素にmarginを追加

親要素からの余白が欲しいので、marginを設定します

style.css
.box2 {
###
    margin: 50px;
###
}

すると
スクリーンショット 2020-05-27 17.25.49.png
オーマイガー;゚д゚)
親要素の淵からの余白が欲しかったものの、仕様なのか、縦の余白は親要素の外側に適用される

親要素にoverflow: hidden;を指定

style.css
.box1 {
###
    overflow: hidden;
###
}

すると
スクリーンショット 2020-05-27 17.25.33.png
思い通りの結果に


プログラミング初心者です。
ログイン画面のレイアウト作成中、ログインフォームのボックスにmarginを指定したら、背景のスタイルが崩れてしまい、なかなか思い通りに余白が設定できなかったので、今回はその覚書きとしました。

参考
親要素からはみ出してmarginが適用される対策
CSSリファレンス overflow …… はみ出た要素の表示方法を指定する


サンプルコード

index.html
<!DOCTYPE html>
<html>
<head>
    <title>Overflow</title>
    <link rel="stylesheet" type="text/css" href="style.css">
</head>
    <body>
        <div class="box1">
            <div class="box2"></div>
        </div>
    </body>
</html>
style.css
* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}
body {
    background-color: #e3f6f5;
}
.box1 {
    width: 400px;
    height: 400px;
    background-color: #bae8e8;

    /*親要素に追加*/
    overflow: hidden;
}
.box2 {
    width: 200px;
    height: 200px;
    background-color: #ffd803;

    /*子要素に追加*/
    margin: 50px;
}

ちなみに、親要素にテキストが含まれていたりmarginやpaddingが指定されていると、overflow: hidden;を指定しなくても余白がはみ出ることはないみたいです。
スクリーンショット 2020-05-27 18.02.55.png

style.css
.box1 {
    width: 400px;
    height: 400px;
    background-color: #bae8e8;

    /*  overflowの指定なし*/
}
.box2 {
    width: 200px;
    height: 200px;
    background-color: #ffd803;

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

HTMLフォーム部品

①valueで初期値を設定
<input type="text" value="hello">

②password入力用の部品で文字が伏字になる
<input type="password">

③placeholderで入力例を記載する
<input type="test" placeholder="住所">

④labelを付けてあげると、何を書くべきかが分かりやすくなる。
そして、for文とidで紐づけをきちんと行うと、labelをクリックしたときに、
inputタグにfocusがあたる。
また、HPなどの読み上げ機能の際には、紐づけしてあると名前が読み上げられる。

<label for="name">名前</label>
<input type="text" id="name">

下記のように略すこともできる
<label>名前<input type="text"></label>

⑤ドロップダウンリスト
size="2"を選択すると、2行分表示される
multipleは複数選択可能
selected属性は最初から項目指定ができる

<select size="2" multiple>
<option>1</option>
<option selected>2</option>
</select>

⑥チェックボックス
<input type="checkbox">andorid
<input type="checkbox">ipad

ラベルと紐づけすると、文字をタップしてもチェックされる
<label><input type="checkbox">iphone</label>

最初からチェックする
<input type="checkbox" checked>andorid

グループ化する(複数選択)
<fieldset>
<legend>携帯端末</legend>
<input type="checkbox">andorid
<input type="checkbox">ipad
</fieldset>

⑥ラジオボタン
ラジオボタンは、name属性で同じ項目の質問だよと
してあげないと複数選択できるようになってしまう。

<fieldset>
<legend>携帯端末</legend>
<input type="radio" name="phone">andorid
<input type="radio" name="phone">ipad
</fieldset>

⑦ボタンを押せなくする
<input type="button" disabled>
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

iOS13.5 Safari でページがスクロールできないバグの解消

iOS13.5バグ発生

複雑なコードの一部のため、細かい発生条件の切り分けまでできていませんが…
高さを指定したdivoverflow:auto指定をして、画面内でスクロールするコンテンツが、OSアップデートしたとたん動かなくなりました。

解決法

いろいろ試し、結果として、以下が判明しました。
- CSSのoverflowの値を再定義してやればスクロールできるようになる。
- ただし、2度同じ再定義をしても、以後はスクロールできるようにならない。

divの中のHTMLを動的に書き換えるコンテンツだったため、スクロールが必要だったり必要なかったりします。

コード

結果として、すごくびみょうな方法ですが…値としてautoscrollを交互に入れ替える方法で解決しました。

//表示されてから実行するために、setTimeoutで遅延。
setTimeout(function(){

    if($(target).css('overflow')=='auto'){
        $(target).css('overflow','scroll');
    }else{
        $(target).css('overflow','auto');
    }
},100);
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

ググるは【力】!コーディングで困った時に役立つGoogleChromeのオススメ拡張機能

コーディングしていてわからないことはGoogle先生にお尋ねすることになりますよね

ただ、知りたい情報に早くいきつきたいものです

そんな時に使っているChromeの拡張機能まとめました

google検索

AdBlock — 最高峰の広告ブロッカー

その名の通り、広告をブロックしてくれる拡張機能

情報に集中できるのはありがたいのですが、デメリットも

「あれ?ページ真っ白!」

「表示されないぞ?」

「なんか文字だけが表示されてる、CSS効いてない?」

こんなときはオフにしてみよう!

ちゃんと表示されないときはこの子が原因のときがよくある

(わたしは結構時間をむだにしました(。-ω-)z)

SearchPreview

google検索結果に画像でプレビューを表示してくれます

雰囲気は画像がやはり把握しやすい

AutoPagerize

たまにあるページを分割しているサイト

1 2 3 次のページ

これめんどくさいので、自動で一枚のページのように表示してくれます

Google検索結果も読み込んでくれます

サイトの設定もできて便利

コーディングお助け拡張機能

Awesome Screenshot: キャプチャーと注釈

ブラウザに表示されているページをキャプチャできる

ページ全体もできるし、選択範囲を指定できたり編集機能もある

メモにも使えるし、サイトの素材としても使えるしgood

Image Downloader

もう一つ画像関係

ページに表示されている画像を一括でダウンロードできる

サイトを模写する時にお世話になります

注意:CSSでbackground-imageのように設定している画像はとれないみたい

HTMLのimgタグの画像のみ

ColorPick Eyedropper

ブラウザの色を16進数やRGBでとることができる
これも模写でお世話になります

CSSViewer

これいれてたのにつかってなかった!忘れていた

選択したHTMLタグにどんなCSSが当たっているのか表示してくれる

ディベロッパーツールでも確認できるけど、それよりも手軽にできる

この記事書く時に、「こんなのいれてたのか!」って。書いてよかった(˘︶˘)

Page Ruler Redux

選択ツールで要素の幅をはかれます
これも模写で活躍

WhatRuns

サイトで使用しているサービスやツールをみることができます

同じブラウザで見てるのに違う技術っていっぱいあるんだなと感心した記憶が

プロジェクト始める前の参考によいです  

まとめ

詰まることが多い独学プログラミングは必然とググる回数も増えていきます

ググる力を身につけるのはもちろん大事ですがスピードを早めることも同じくらい大事です

頑張っていきましょう!

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

GithubでWebサイトを公開する時、原因不明の404エラーが出た時の解決策

Qiita初投稿です。

タイトル通り、Githubで404エラーが出たときに、特にエラー内容が書いていなかったので、リポジトリを作り直したり色々しましたがだめでした。

そこで、私はアカウント名の中のアルファベットの大文字がURLでは小文字になっていることに気が付きました。それを小文字にしたところ公開できました。

具体的にはKanprogramというアカウント名のときは

https://kanprogram.github.io/Home/

と、自動的に小文字になってしまっていたので
kanprogrammingというものに変えたところ

https://kanprogramming.github.io/Home/

無事公開することができました。

初学者ですがこれからも発信していきたいと思います。一緒に頑張りましょう。

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

Bootstrapで使うものと使わないものを分けていいとこどりをする

Bootstrapはとても便利なのですが、全部覚えようとするとけっこうな量があるので使うものを絞ってみました

絞り込む基準

  • CSSを直接書いてもできるけれど、記述が簡単になるもの
  • とりあえずのレイアウト確認に使用できるもの

他のライブラリでできるものはライブラリで

swiperとか

ボタン系

<button type="button" class="btn btn-primary">Primary</button>
<button type="button" class="btn btn-primary btn-lg">Large button</button>
<button type="button" class="btn btn-lg btn-primary" disabled="">Disabled button</button>

レイアウト確認に便利

Emmet使うと即ですし

バッジ系

<p>example<span class="badge badge-secondary">new</span></p>
<span class="badge badge-pill badge-primary">Secondary</span>
<span class="badge badge-primary">Primary</span>

これもレイアウト確認に便利

ドロップダウン

<div class="dropdown">
  <button class="btn btn-secondary dropdown-toggle" type="button" id="dropdownMenu1" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
    dropdown
  </button>
  <div class="dropdown-menu" aria-labelledby="dropdownMenu1">
    <a class="dropdown-item" href="#">item1</a>
    <a class="dropdown-item" href="#">item2</a>
  </div>
</div>

フォーム系

<form>
  <div class="form-group">
    <label for="form-input">label</label>
    <input type="text" class="form-control" id="form-input" placeholder="input">
  </div>
</form>

グリッド系

<div class="container">
  <div class="row">
    <div class="col-md-4">
      <!-- Content1 -->
    </div>
    <div class="col-md-4">
      <!-- Content2 -->
    </div>
    <div class="col-md-4">
      <!-- Content3 -->
    </div>
  </div>
</div>

簡単にレスポンシブ化できるのでとても好き

モーダル系

<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#modal">
  modal
</button>
<div class="modal" id="modal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
  <div class="modal-dialog" role="document">
    <div class="modal-content">
      <div class="modal-body">
        <!-- Content -->
      </div>
    </div>
  </div>
</div>

ナビ(nav)

<nav class="nav">
  <a class="nav-link" href="#!">nav1</a>
  <a class="nav-link" href="#!">nav2</a>
</nav>

次のnavbarのほうが個人的お好み

ナビゲーションバー(navbar)

<nav class="navbar navbar-expand-lg navbar-light bg-light">
  <a class="navbar-brand" href="#">navbar</a>
  <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
    <span class="navbar-toggler-icon"></span>
  </button>
  <div class="collapse navbar-collapse" id="navbarSupportedContent">
    <ul class="navbar-nav mr-auto">
      <li class="nav-item active">
        <a class="nav-link" href="#">item1</a>
      </li>
      <li class="nav-item">
        <a class="nav-link" href="#">item2</a>
      </li>
    </ul>
  </div>
</nav>

仕組みを理解するのにちょっと時間かかるかも

カスタマイズするにはコードの意味やクラス名とかDOM関連知る必要あり

テーブル系

<table class="table">
  <thead class="thead-light">
    <tr>
      <th>head1</th>
      <th>head2</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>item1</td>
      <td>item2</td>
    </tr>
  </tbody>
</table>

まとめ

好みもだいぶいれましたが、Bootstrapはとても便利です

とくに初学者の人はCSSの知識を深めるのにいいと思います

どうしてこの記述なのだろうとか考えると面白いです

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

HTMLとCSSの関心の分離設計(下書き)

課題意識

HTMLとCSSは分離すべきだという一般論があるが、レイアウトの構造を整えるためのHTML要素やアニメーションで表現を変えるためのHTML要素も存在する。

HTMLとCSSは本当に分離できるのか、分離できるとしたら何が分離できて、分離できないとしたら何が分離できないかを整理する必要がある。

また、レイアウトは他のプログラミング機能と違い、単独のモジュールとしてでなく全体で初めて意味を持つ。

そのようなレイアウトの性質を踏まえ、どのようにレイアウトを設計すべきなのか。

レイアウトの共通化の単位はCSS単位ですべきなのかコンポーネント単位ですべきなのか。
コンポーネント単位だとしたら、それはHTMLとCSSが結合した状態に他ならず、分離を考えるよりもむしろ結合を前提にコンポーネント単位で関心を分離する方が適切なのではないか。

そういった事に関する考察。

Memo

  1. What is content and what is layout.
  2. What is separation of concerns.
  3. Why does separation of concerns matter.
  4. Not separation but direction of dependency.
  5. Difference of component and css.
  6. What is Utility class

参考

https://yuheiy.hatenablog.com/entry/2020/05/25/021342

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

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

100日チャレンジの327日目

twitterの100日チャレンジ#タグ、#100DaysOfCode実施中です。
すでに100日超えましたが、継続。
100日チャレンジは、ぱぺまぺの中ではプログラミングに限らず継続学習のために使っています。
327日目は、

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

Firebaseでログイン機能を作ってみる

やったこと

FireBaseを使ってログイン機能を作りました。
(ただし、あらかじめ登録してあるものだけログイン可)

最後にコードも貼り付けます。

使っているもの

できること(サンプル)

  • FirebaseのAuthenticationであらかじめ登録したユーザでログインができます
  • ログインするとFirebaseのDatabaseにタイムスタンプが送られます
  • ログイン時のみナビゲーションヘッダーを出すようにしています

サンプル:
https://simasima.work/index.html

テストユーザアカウント
- メール : test@test.com
- PW : test0000

こちらでテスト的にログインできるはずです。
※ 何のお知らせなくログインできなくなることもあるかも知れませんがご了承ください。

ログイン前

image.png

ログイン後

image.png

まずFireBaseのプロジェクトを作成する

下記記事を参考にして、「1個のアプリ」と表示されたことを確認 ⇒ 左メニューから各機能の設定を行うまでやります。

下記画像にあるスクリプトはすぐ使うので控えておきます。
image.png

参考:Firebaseプロジェクト作成方法

Authenticationでログインアカウントを作る

ログインを許可するアカウントを作ります。

まず、Authentication を選択して、Sign-in methodを選択する。
そして、メール/パスワード を有効にする。
image.png

次に、Usersを選択する(Sign-in methodの隣にある)。
そして、「ユーザを追加」からログインさせたいメールアドレスとパスワードを登録する。
image.png

Databaseの設定をする

左ナビのDatabaseを選択して「データベースの作成」をする。
本番かテストモードかを選択する。
image.png

ロケーションも設定したら完了をクリックする。

完了したら、「コレクションを開始」をクリックする。
ソースコード上はmemosというコレクションIDでやっているので、コピペで使いたい場合はコレクションIDをメモにする。

ここには下図のようにフィールドを設定しておきます。
image.png

準備しておくべきことは以上で完了です!

ソースコード

画像のリンクや、Firebaseの情報を入れ変えることで動くかと思います。
ナビゲーションヘッダーのリンク先も適宜変更してください。

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Email/Password Authentication Example</title>

  <!-- Load required Bootstrap and BootstrapVue CSS -->
  <link rel="stylesheet" href="//unpkg.com/bootstrap/dist/css/bootstrap.min.css" />
  <link rel="stylesheet" href="//unpkg.com/bootstrap-vue@latest/dist/bootstrap-vue.min.css" />

  <!-- Load polyfills to support older browsers -->
  <script src="//polyfill.io/v3/polyfill.min.js?features=es2015%2CIntersectionObserver" crossorigin="anonymous"></script>

  <!-- Load Vue followed by BootstrapVue -->
  <script src="//unpkg.com/vue@latest/dist/vue.min.js"></script>
  <script src="//unpkg.com/bootstrap-vue@latest/dist/bootstrap-vue.min.js"></script>

  <!-- Load the following for BootstrapVueIcons support -->
  <script src="//unpkg.com/bootstrap-vue@latest/dist/bootstrap-vue-icons.min.js"></script>

</head>

<body>

  <div class="container">

    <div id="appFirebaseLogin">

    <div v-if="loginStatus">
        <nav class="navbar navbar-expand-lg navbar navbar-dark bg-dark" > 
            <a class="navbar-brand">Menu</a>
            <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNavDropdown" aria-controls="navbarNavDropdown" aria-expanded="false" aria-label="Toggle navigation">
              <span class="navbar-toggler-icon"></span>
            </button>
            <div class="collapse navbar-collapse" id="navbarNavDropdown">
              <ul class="navbar-nav">
                <li class="nav-item active">
                  <a class="nav-link" href="./index.html">Home <span class="sr-only">(current)</span></a>
                </li>
                <li class="nav-item">
                  <a class="nav-link" href="./contents/face-emotion.html">感情分析</a>
                </li>
                <li class="nav-item">
                  <a class="nav-link" href="./contents/ocr-read.html">OCR機能</a>
                </li>
                <li class="nav-item">
                    <a class="nav-link" href="./contents/dog.html">ワンちゃん検索</a>
                  </li>
              </ul>
            </div>
          </nav>
        </div>

      <div class="row" v-if="loginStatus">
        <div class="col">
          <img class="rounded mx-auto d-block" src="xxxxxxxxx" width="400" height="auto" vspace="30">
        </div>
      </div>

      <div class="row" v-else>
        <div class="col">
          <img class="rounded mx-auto d-block" src="xxxxxxxxx" width="400" height="auto" vspace="30">
        </div>
      </div>

      <div class="row">
        <div class="col">

          <div v-if="loginStatus">
            <div class="row">
              <div class="col-6">
                <div class="form-group">
                  ようこそ、{{ userName }} さん! 
                </div>
              </div>
              <div class="col-6">
                <div class="form-group">
                  <button class="btn btn-primary" v-on:click="handlerLogout">Logout</button>
                </div>
              </div>
            </div>
          </div>

          <div v-else>
              <div class="form-group">
                <label>Email</label>
                <input v-model="email" class="form-control"/>
              </div>
              <div class="form-group">
                <label>Password</label>
                <input v-model="password" type="password" class="form-control">
              </div>
              <div class="form-group">
                <button class="btn btn-primary" v-on:click="handlerLogin">Login</button>
              </div>
          </div>

        </div>
      </div>
    </div>

  </div>

  <!-- FireBaseの使う機能を指定する -->
    <!-- https://firebase.google.com/docs/web/setup?hl=ja#available-libraries -->
    <script src="https://www.gstatic.com/firebasejs/6.2.0/firebase-app.js"></script>
    <script src="https://www.gstatic.com/firebasejs/6.2.0/firebase-auth.js"></script>
    <script src="https://www.gstatic.com/firebasejs/6.2.0/firebase-firestore.js"></script>
    <script>
        // ここは自分のアカウントう情報
        // Your web app's Firebase configuration
        var firebaseConfig = {
            apiKey: "xxxxxxxxxxxxxxx",
            authDomain: "xxxxxxxxxxxxxxx",
            databaseURL: "xxxxxxxxxxxxxxx",
            projectId: "xxxxxxxxxxxxxxx",
            storageBucket: "xxxxxxxxxxxxxxx",
            messagingSenderId: "xxxxxxxxxxxxxxx",
            appId: "xxxxxxxxxxxxxxx",
            measurementId: "xxxxxxxxxxxxxxx"
        };
        // Initialize Firebase
        firebase.initializeApp(firebaseConfig);
        // firestoreのインスタンス
        const db = firebase.firestore();
    </script>


<script>
  const app = new Vue({
    el: '#appFirebaseLogin',
    data: {
      email: '',
      password: '',
      loginStatus: false,
      userName:'',
      userID:'',
      message:'',
      items:[]
    },
    methods: {

            /////////////////// Firebase Authentication ///////////////////

            // ログアウトボタンの挙動
            handlerLogout: async function () {
            console.log('handlerLogout');
            await firebase.auth().signOut();
            await this.checkAuthStateChanged();
            // データ更新を監視するリスナーを削除する Cloud Firestore 用の処理
            this.endSnapShot();
            },

            // ログインボタンの挙動
            handlerLogin: async function () {
            console.log('handlerLogin');

            // DBにログイン日時を書き込む処理
            this.handlerAddMemo();

            try {
                const resSignInWithEmailAndPassword = await firebase.auth().signInWithEmailAndPassword(this.email, this.password);
                console.log(resSignInWithEmailAndPassword);
            } catch(error) {
                console.log(error);
                const errorCode = error.code;
                const errorMessage = error.message;
                if (errorCode === 'auth/wrong-password') {
                alert('Wrong password.');
                } else {
                alert(errorMessage);
                }
            }


            // ログイン処理後 Firebase Authentication 認証状態のチェック
            this.checkAuthStateChanged();


            },

            checkAuthStateChanged: async function(){

            // 認証状態の変更を取得
            let user = await this.promiseAuthStateChanged();



            if (user) {
                // ログイン済み
                console.log('ログイン済み');
                // Vue に値を反映
                this.loginStatus = true;    // ログイン状況
                this.userName = user.email; // ユーザー名(メールアドレス)
                this.userID = user.uid;     // Firebase で管理されているユニークなユーザーID
                // データ更新を監視するリスナーに登録する Cloud Firestore 用の処理
                this.startSnapShot();

            } else {
                // 未ログイン
                console.log('未ログイン');
                this.loginStatus = false;  // ログイン状況
            }

            },

            promiseAuthStateChanged: async _ => {
            return new Promise( (resolve, reject) => {
                const f_auth = firebase.auth();
                f_auth.onAuthStateChanged( user => {
                resolve(user);
                });
            });

            },

      /////////////////// Cloud Firestore ///////////////////

        // Cloud Firestore用。これを呼ぶとDBにログイン日時が書き込まれる
        handlerAddMemo: async function() {
            console.log('handlerAddMemo');

            // ここの中にuser情報をとってくる。
            const data = {
                message: this.message,
                timestamp: firebase.firestore.FieldValue.serverTimestamp()
            };

            try {
            await db.collection("memos").doc().set(data);
            console.log("Document successfully written!");
            } catch(error) {
            console.log(error);
            console.error("Error writing document: ", error);
            }
        },

        // データ更新を監視するためリスナーに登録する
        startSnapShot: function(){
            console.log('常に監視するためリスナーに登録する');
            this.unsubscribe = db.collection('memos').orderBy('timestamp', 'desc').onSnapshot(this.listenerSnapShot);
        },

        // データ更新を監視するリスナーを削除する
        endSnapShot: function(){
            console.log('常に監視するリスナーを削除する');
            this.unsubscribe();
        },

        //データ更新が行われた場合に動作する
        listenerSnapShot: function(querySnapshot){
            //console.log('listenerSnapShot');
            this.items = [];
            const _this = this;

            querySnapshot.docs.map(function(doc){
            const _data = doc.data({serverTimestamps: 'estimate'});
            let timestampDate = new Date();
            timestampDate.setTime(_data.timestamp.seconds * 1000);

            console.log(_this.userName)
            _this.items.push({
                message:_data.message,
                dateString:timestampDate.toString(),
                timestamp:_data.timestamp

            });
            });
        }

            }
            ,
            mounted() {
            console.log('mounted');

            /////////////////// Firebase Authentication ///////////////////
            // はじめて表示されたときの Firebase Authentication 認証状態のチェック
            this.checkAuthStateChanged();
}
  })
</script>


</body>
</html>

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