AWSの認証、MFAに使用するスマホアプリ、Authenticator。
今回携帯電話を機種変更したのですが、このAuthenticatorの再設定のやり方を解説したドキュメントが見つからず少し苦戦しました。
AWSの認証、MFAに使用するスマホアプリ、Authenticator。
今回携帯電話を機種変更したのですが、このAuthenticatorの再設定のやり方を解説したドキュメントが見つからず少し苦戦しました。
本仕様書の作成目的を記載する
┗開発言語(Java、Ruby、javascriptなど)
┗アプリケーションフレームワーク(Spring、Node.js、Vue.js、Vuex、Seleniumなど)
┗画面構成
┗画面遷移図
┗各画面
DB定義
┗DB構成
┗各テーブル定義
【基本事項】
■バージョン確認
自動でアップデートされていくので知っても意味がない。
確認方法も煩雑。
というか、ESの実装がjsであり、バージョンは無い?
・scriptで宣言した後
use strictを書いておくとエラーをコンソールに出力してくれる
基本的にファイルのコードはすべて{}でくくってあげる。
するとスコープがわかれるため、変数の干渉を防ぐことができる
・文字列にシングルクォーテーションを用いるか、ダブルクォーテーションを用いるかはどちらでも構わない。typescriptのESlintがシングルを強要することからシングルのほうが無難か。
'use strict'; { //この中にコードを書く }
■定義
const t = 'test';
ハイフンはNG、0始まりはNG
大文字、小文字は区別される
予約語は使えない(constなど)
・属性宣言(定数・変数定義)で関数を使う場合に
その関数は後から書いても良い
【フォームの処理】form
■参考
http://www.kogures.com/hitoshi/javascript/get-form/getform1.html
■inputの値が変更されるたびに発火 :oninput
<input type="text" id="input"> 入力された文字列: <span id="result"></span> <script> input.oninput = function() { result.innerHTML = input.value; }; </script>
■イベントハンドラとイベントリスナーどっちを使用する?
参考:https://ichi.pro/js-no-ibentohandora-to-addeventlistener-no-chigai-wa-nani-desu-ka-165150920301620
>一般的にはイベントリスナー。イベントハンドラは複数あった場合に処理を上書きしてしまう。
<button onclick=”funk()”> //イベントハンドラ addEventLister //イベントリスナ
■formタグって必要なの?
以下の違いがある
タグのデフォルトのバリデーションがされる
デフォルトでEnterキーによる送信処理が実装される
デフォルトの送信は非同期処理でされない
・js側でformタグを使うとnameをチェーンして取得できる
~index.html~
<form name=”myform”> <input type=”text” name=”sample”> <button type=”submit”>送信</button> </form>
~main.js~
const form = document.forms.myform; //formの送信をcatchする場合 form.addEventListener('submit', function() { event.preventDefault(); console.log(form.sample.value); });
//inputの変更をcatchする場合
form.sample.addEventListener('change', function() { event.preventDefault(); console.log('状態が変化しました!'); });
【文字列の操作】
■エスケープ
前に\をつけるとエスケープ
■連結
■utlil
・文字数
t.length
・部分抽出
t.substring(start, end);
例)console.log(1,2); //'es'
・分割
t.split(str) //strで分割し配列にする
一文字ずつに処理を行いたい場合はsplit(‘’)で一文字ずつの配列にする
function uuid() { return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx' .split('') //1文字ずつの配列に分割 .map(c => { //1文字ずつに処理を行う switch (c) { case 'x': return (Math.random() + 16 | 0).toString(16); case 'y': return ((Math.random() + 4 | 0) + 8).toString(16); default: return c; } }) .join(''); }
■テンプレートリテラル(文字列の埋め込み)
const msg = 'world'; console.log(`hello ${msg}`); //これはjQueryか?
■指定文字列の検索
・参考
https://qiita.com/kazu56/items/557740f398e82fc881df
・matchで検索
str.match('word') //配列 or null
・indexOf
str.indexOf('word') //位置のインデックス or -1
■文字列の置き換え
text.replace(/aaa/g, 'ccc'); //通常は初めの1回のみだが、gを指定すると複数回置き換える str.indexOf(文字列) //あればインデックス、無ければ-1が帰る
■文字をクリップボードにコピー
input要素、textarea要素しかコピーできない。
要素をまるまる取得して、値でなく要素自体を取得し、その要素に対し入力されている文字列を選択する。
input要素、textarea要素しか取得できないのは、クリップボードはHTML上でしか操作できないためと思われる。
・方法
~index.html~
<textarea id="output"></textarea>
~main.js~
const output = document.getElementById('output'); output.addEventListener('click', function() { output.select(); //要素のテキストを画面上で選択 document.execCommand('Copy'); //クリップボードにコピー alert('コピーしました'); })
■正規表現
let regex = startStr + ‘.*?’ + endStr: //正規表現を用意
・リプレイス
result = string.replace(new RegExp(regex, ‘g’), ‘’); //regexを空白に置き換える //初期値は最初に見つかった文字列のみを対象とするが //'g'を指定することですべての文字列が対象となる
・存在を調べる
string.match(regex); //一致すればstring、一致しなければnullが返る
【数値の操作】
■少数
.toFixed(2) //小数点2桁まで表示
■ランダムな数値
Math.floor(Math.random() * 6 + 1); //6~1のランダムな数値を表示する //random :0~0.9999のランダムな数値 //floor :小数点切り捨て //フィッシャーイェーツのシャッフル function shuffle(arr) { for (let i = arr.length - 1; i >= 0; i--) { //arr.length - 1; 配列の最後のインデックスを表現 const j = Math.floor(Math.random() * (i + 1)); //ランダムに選ぶ要素のインデックスを表現 [arr[j], arr[i]] = [arr[i], arr[j]]; //分割代入で要素を入れ替え } return arr; }
【データ型】
■型判定
typeof(val)
データ型の変換 parse●●
console.log('5' + 3); console.log(parseInt('5', 10)); //8 数値に変換できなかったら『NaN』が出力される
・基本データ型 :文字列、数値、真偽値など
・Object型 :配列、オブジェクト ※参照型
■参照型のオブジェクトを参照でなくコピーにするには
const shuffledChoices = shuffle(quizSet[currentNum].c); //quizSet[currentNum].cは参照型
・[]でくくってスプレッド演算子で配列を参照する
shuffle([...quizSet[currentNum].c]);
【関数】
function fnc(msg = '初期値') { return msg; } console.log(fnc('test'));
※関数内でreturnするとそのあとの処理は実行されない
・関数式で定数や変数に直接代入もできる
※最後にセミコロンにつく点に注意!
const keisan = function(msg = '初期値') { return msg; }; keisan('test'); //定数として扱われ、関数名がないので無名関数と呼ばれる
・アロー関数 関数式の書き換え
const keisan = (msg) => { //msgは引数 return msg; };
※returnするだけの場合は
const keisan = (msg) => msg;
でOK
※さらに引数が1つだけなら()も不要
const 定数名 = 引数 => 処理;
【if文】
■基本形
if (arg == val) { }
★『=』だと代入が行われてしまうため注意!
■省略形
const score = 40; score >= 80 ? console.log('OK') : console.log('NG'); && :AND || :OR ! :NOT
【for文】
for (let i = 1; i <= 10; i++) { //初期化すること console.log(i); if (i === 4) { continue; //スキップ } if (i === 7) { break; //終了 } }
■forEach
※break、continueは使えない
a.forEach ( function( item ) { console.log( item ); } )
・アロー関数で書いてみると
a.forEach(item => { console.log(item); }); a.forEach(item => console.log(item); //Aに対してBの処理をする、と覚える
・インデックスもとる場合
a.forEach((item, index) => { console.log(`${index}:${item}`); }
【while文】
let hp = 100; while (hp > 0) { console.log(`${hp} HP left!`); hp -=15; }
※条件を書き忘れると無限ループになりPC、ブラウザの再起動をする羽目になるので注意
do whileも使用できる
【配列】
■基本形
const arr = [80, 90, 40]; //constは、再定義はできないが、値の変更はできる
■プロパティ
arr.index arr.length :長さを取得
■要素の追加
scores.unshift(100); //先頭に追加 scores.push(120); //末尾に追加
■要素の削除
scores.shift(); //先頭を削除 scores.pop(); //末尾を削除
■配列を空にする
arr.length = 0;
■途中の要素
scores.splice(2, 0, a, b); //第1:スタート地点、第2:削除個数、第3以降:追加要素
削除した要素は返り値で取得することもできる
const b = scores.splice(2, 2, a, b); //bに返り値が入る
■map 配列のすべての要素に対して処理を実行
const b = a.map(item => return item * 2);
■filter trueの要素だけとってくる
const b = scores.filter(item => item % 2 ===0); //偶数だけ取得
【オブジェクト】
const player = { name: 'taguchi', score: 32, //最後の行はカンマはつけてもつけなくてもOK }
player.name または player[name] でアクセス
・プロパティ(メンバー)の追加 ただ、keyとvalueを渡せばOK
player.email = 'test@exsample.com';
・プロパティの削除
delete player.email;
■オブジェクトメソッド
Object.keys(player) //keyの配列 Object.values(player) //valueの配列 Object.entries(player) //[[key1, value1], [key2, value2]]といった2次元配列
■スプレッド演算子 『...●●』 :配列(オブジェクト)の連結
★配列でも参照型ではなく、コピーになる!
const a = [10, 20]; const b = [1, 2, ...a]; console.log(b); //[1, 2, 10, 20]
・引数にもよく使われる
const a = [10, 20]; const sum = (a, b) => a + b; console.log(sum(...a)); //30 ※sum(10, 20)となる
・オブジェクトに使う場合
const o1 = {a: 1}; ocnst o2 = {...o1, b: 2}; //{a:1, b:2}
■分割代入 :配列(オブジェクト)の各値に対応させて代入
const numbers = [1, 2]; const [a, b] = numbers; //a=1, b=2
・スプレッド演算子との組み合わせ;
const numbers = [1, 2, 3, 8]; const [a, b, ...rest] = numbers; //a=1, b=2, rest=[3, 8]
・オブジェクトに使う場合
const player = { name: 'taguchi', score: 55, hp: 33, } const {name, ...points} = player; //name = 'taguchi', points = {score:55, hp:33}
【クラス】
class Player { constructor(name, score) { this.name = name; this.score = score; } showInfo() { console.log(`name: ${this.name} score: ${this.score}`); } static showVersion() { //クラスメソッド(静的メソッド) console.log('Player class ver 1.0'); } } const taguchi = new Player('taguchi', '32'); //インスタンス化 console.log(taguchi.name); //呼び出し
・thisについて
this.nameのようにパラメータとして付与しているものは、本来であれば
const name = name;
のように宣言するものだが、パラメータとして付与する場合は宣言不要で
かつそのクラスに紐づいた要素になるので便利。
thisを付与するタイミングは以下の時
┗パラメータにアクセス
┗クラスメソッドにアクセス
■クラスの継承 ※上記のPlayerクラスを継承する
class SoccerPlayer extends Player { constructor(name, score, number) { super(name, score); //親クラスからメソッドを継承 this.number = number; } }
■カプセル化(オブジェクト思考)
クラスプロパティは外部から直接呼び出すのは避ける。
呼び出したい場合はクラス内でプロパティを呼び出す関数を定義し、
クラスメソッドとして呼び出す
例)
class Panel { constructor() { this.el = document.createElement('li'); } getEl() { //メソッドでプロパティを呼び出す return this.el; } } board.appendChild(panel.getEl()); // カプセル化
【例外処理】
const a = 5; try { console.log(a.toUpperCase()); //toUpperCaseは大文字にする処理なのでエラー } catch (e) { //エラーオブジェクトをeに格納してくれる console.log(e.message); //eのmessageメソッド }
【非同期処理】
javascriptはシングルスレッド処理。スタックに処理が積まれるため、ネストされた時間のかかるメソッドは後回しされる場合がある。
Promiseオブジェクトでラップすることで処理の終了を保証して次に進める。
async/awaitを使用することでよりシンプルにPromiseの機構を使用することができる。
asyncで定義した関数はPromiseオブジェクトにラップされるため、処理の終了が保証される。
awaitはasyncで定義した関数内で使用することができ、awaitで定義した関数内でPromiseが返されるまで待機する。asyncと何が違うのかいまいち理解できていない
【appendics】
■日付
const d = new Date(); //引数に数値を指定するとその日時のオブジェクトを作成できる(年,月は必須) console.log(d.getFullYear()); //年 console.log(d.getMonth()); //★0-11 console.log(d.getDate()); //日 console.log(d.getDay()); //曜日0~6 console.log(d.getTime()); //世界共通の数値化された日時
・フォーム
~HTML~
<form name="myform"> <input type="date" name="date" value="2012-02-16"> </form>
・日付のセット
d.setHours(10, 20, 30) //10時20分30秒
※自動補正が入る(Date(日)で32と入れると翌月になる)
・日付の追加
d.setDate(d.getDate() + 3);
・日付の経過計測
const d1 = new Date(2018, 11, 1); //11月1日 const d2 = new Date(2018, 11, 10); //11月10日 console.log(d2 - d1); //77760000ミリ秒 console.log((d2 - d1) / (24 * 60 * 60 * 1000)); //9日 86400000秒/1日
■アラート :ウィンドウオブジェクト
window.alert('hello'); //windowは省略可 const answer = confirm('Sure?') //承認を求める console.log(answer); //返り値はtrue or false
・HTMLで簡単にアラートを出す ※NOを押せばキャンセルされる
https://proengineer.internous.co.jp/content/columnfeature/8007
コード
<a href="http://www.google.co.jp/" onclick="return confirm('よろしいですか?')">リンク</a>
■タイマー
・一定間隔で処理を実行 :setInterval
★処理がどんどん進むのでシステムに負荷をかけないよう配慮が必要
const tim = () => { //関数式で定数に関数を代入 console.log(new Date()); }; setInterval(tim, 1000); //関数, ミリ秒でセット
・タイマーを止める
変数にsetIntervalを格納
カウンタ変数を別途用意し、関数内でカウンタを増やす
カウンタに対してif分岐を設定しておいてclearInterval()する
let lim = 0; const tim = () => { console.log(new Date()); lim ++; if (lim > 3) { clearInterval(timer); } }; let timer = setInterval(tim, 1000);
★・1回だけ実行する :setTimeout
setTimeoutは処理が終わってから実行するため
システムに負荷をかけない
const tim = () => { console.log(new Date()); }; setTimeout(tim, 1000); //ミリ秒で指定
これをループさせることで、一定間隔での処理を実装することもできる
const tim = () => { console.log(new Date()); setTimeout(tim, 1000); //ミリ秒で指定 }; tim();
止めたい場合は
let lim = 0; const tim = () => { console.log(new Date()); lim ++; let timid = setTimeout(tim, 1000); if (lim > 2) { clearTimeout(timid); } }; tim();
・カウントアップの基本
const timer = document.getElementById('timer'); let startTime; cntUp() { let leftTime = Date.now() - startTime; textContent = (leftTime / 1000).toFixed(1); setTimeout(() => { cntUp(); }, 100) }
★関数を呼び出す
※定数の無名関数の場合、スコープの都合上creaTimeoutできないことがよくあるので関数を使うのがベター
setTimeout(fnc(), 1000); ではなく setTimeout(() => { fnc(); }, 1000);
とする。
■1つのjsファイルを複数ページで使いまわす。
複数ページで使いまわすと、現在のページ以外の要素が存在しないと怒られる。
ページごとにユニークなidなどをキーにif文で出しわける。
if(document.getElementById(‘uniqueId’)) { uniqueIdを持つページの処理 }
■要素内のテキストが画面幅によって折り返しが起きているかどうかを判定する
RangeオブジェクトにNodeをつっこむことで解析できるようにする。
Rangeオブジェクトのメソッド、getClientRects()で表示されている行数を判定できる。
参考:
javascript - htmlでテキスト表示する際、(画面幅等により、)折り返しが発生するかどうかを事前に判定する方法はありますか? - スタック・オーバーフロー
const items = document.getElementsByClassName('item'); let texts; let range = new Range(); for(let i = 0; i < items.length; i++) { texts = items[i].children; for(let j = 0; j < texts.length; j++) { range.selectNode(texts[j]); if(range.getClientRects().length > 2) { //複数行になっていた場合に行いたい処理 } } }
■即時関数の利用
javascriptはスコープがグローバルか関数内ローカルの2種類しかない。
そのため、画面読み込み時の初期化など、再利用される可能性の無いものは即時関数としてくくることでグローバル領域の汚染を防ぐ。
(function () { var label = document.getElementById('date_label'), now = new Date(); label.innerText = now; }()); //★ここに不思議なカッコがあるので注意
参考:https://qiita.com/katsukii/items/cfe9fd968ba0db603b1e
■数字を文字列として出力しても数値として演算ができる
※プラスの場合だけ、文字列の連結として扱われる
■わからないことがあったらMDNで調べよう
■jsはxss(クロスサイトスクリプティング)の危険があるので注意する
https://www.websec-room.com/2013/03/14/567
■javascriptが動作しているかテスト
以下のテストコードをmain.jsなどに記載し、
htmlの要素に id="target"を付与。
表示した要素をクリックして背景がピンクに変われば動作している
document.getElementById('target').addEventListener('click', () => { document.getElementById('target').style.background = 'pink'; });
【検索ワード】
async await 違い
Promise 中身 取得
デベロッパーツール>コンソール
documentと打ち込むとDOMツリーを確認できる
jsのスクリプトからDOM(HTML)を操作する
■idで取得 :getElementById()
document.getElementById('target').textContent = 'Changed!';
■要素名、セレクタで取得 :getElementsByTagName()、querySelector()
document.getElementsByTagName('h1'); document.querySelector('h1').textContent = 'h1dayo!'; document.querySelectorAll('li').forEach(li => { li.textContent = 'list dayo!'; });
・クエリセレクタはノードを直接記述することもできる。
例)id="result"直下のp要素
let resultScore = document.querySelector('#result > p');
・フォーム部品の指定 input[type="text"]
const i = document.querySelector('input[type="text"]'); //textareaはHTMLでvalueが設定されていなくても.valueで値を取得する const t = document.querySelector('textarea'); console.log(t.value); //チェックボックス・ラジオボタン ~HTML~ <input type="checkbox" name="experience" value="done"> <input type="checkbox" name="decide" value="yes" checked> ~js~ console.log(document.querySelectorAll('input[type="checkbox"]')[1]); //checked属性の指定 console.log(document.querySelectorAll('input[type="checkbox"]')[1].checked); //プルダウン ~HTML~ <select> <option>item1</option> <option selected>item2</option> </select> ~js~ >|??| console.log(document.querySelectorAll('select > option')[1].selected); //true
・子要素の指定::nth-child()
document.querySelectorAll('li:nth-child(0)').forEach(li => { li.textContent = 'list dayo!'; } //奇数の要素を取得 document.querySelectorAll('li:nth-child(odd)').forEach(li => { li.textContent = 'list dayo!'; }
■CSSクラス名で取得 :getElementsByClassName() //★Elementsとなることに注意!
■親要素の指定
const p = document.querySelector('li'); console.log(p.parentNode); //liの親要素であるul要素が取得できる
■子要素の指定
const p = document.querySelector('ul'); console.log(p.chilren);
複数要素がある場合はchildren[1]のようにアクセスできる
すべての要素を出力したい場合、HTMLコレクション(配列ではない)へのアクセスとなるのでforeachを使用すると以下のエラーが出力される。
forEach is not a function at HTMLDivElement
for文であればコレクションにも対応できるのでこちらで記述する。
const p = document.querySelector('ul'); for (let i = 0; i < p.children.length; i++) { console.log(p.children[i]); }
■カスタムデータ属性へのアクセス :dataset
HTMLで以下のようなカスタムデータ属性を設定していたとする。
<h1 title="this is title" data-app-id="app1">Title</h1>
その場合、以下の注意事項がある
┗データ属性名のハイフンは削る
┗2語目の文頭は大文字
┗jsからのアクセスはdataではなくdatasetとする
const h = document.querySelector('h1'); console.log(h.dataset.appId);
新たなカスタムデータ属性を付与する場合は以下のようにする
h.dataset.appIdd = 'this is changed'; >|??| するとHTML側では以下のようになる >|??| <h1 title="this is title" data-app-idd="this is changed">Title</h1>
■基本
document.body.textContent = 'hello'; //bodyに文字を出力 document.title = 'catch me!' //タイトルを変更
基本的には定数に格納してそれに対して操作を用いることが多い
const h = document.querySelector('h1'); h1.textContent = 'hello!';
■テキストの挿入・変更
a.textContent = 'b'; //要素aのテキストをbにする
■属性の追加・変更
sample.setAttribute(name, value) sample.setAttribute("href", "/sample") //要素sampleにhref="/sample"が追加される
■CSSスタイルの追加
a.style.backgroundColor = 'gray';
■idの付与
const exam = "idname"; //id名を定数で定義 a.setAttribute("id", "idname");
■cssクラスの付与・変更 ※使いずらいので下のclassListの方がよく用いられる
a.className = 'b'; //要素aにクラスbを付与する
※上書きしてしまうので既存のクラスがある場合はそれも設定する
例えばcというクラスがすでに設定されていた場合は、a.className = 'c b'; とする
■cssクラスの操作 :classList
a.classList.add('b') //要素aにクラスbを追加する a.classList.remove('b') //要素aからクラスbを削除する
■特定のcssがあれば削除:contains
const d = document.querySelector('div'); if (d.classList.contains('border-pink')) { d.classList.remove('border-pink'); } else { d.classList.add('border-pink'); }
・単純な入れ替えは以下でもできる
d.classList.toggle('border-pink');
■要素の生成 :createElement()
const h = document.createElement('h1'); //要素を作成 ※まだ配置していない h.textContent = 'Title'; document.body.appendChild(h); //bodyの最後の子要素に追加
※位置を指定する場合
const b = document.querySelector('body'); b.appendChild(b);
・要素の途中に追加するには?
const h = document.createElement('h1'); //要素を作成 ※まだ配置していない h.textContent = 'Title'; const d = document.querySelector('div'); //HTMLの配置ポイントを取得 document.body.insertBefore(h, d); //hをdの直前に配置
※まだ配置していない要素に追加する場合はdocument.は不要
■要素のコピー
const d = document.querySelector('div'); const c = cloneNode(true); //falseにすると空の要素を作る
■要素の削除 ;removeChild
const d = document.getElementById(‘id’); d.parentNode.removeChild(d); //親要素のノードからremoveChildすることで自身を削除
※複数の要素をリストに格納しfor文で削除する場合、削除のたびにリストの中身が変わるので、インデックスではなく常に先頭の要素を削除するなどの注意が必要。
■子要素をすべて削除
targetArea.innerHTML = '';
■要素のフォーカス
初期値でテキストエリアなど、要素にフォーカスさせたいとき
const t = document.querySelector('textarea'); t.focus();
・フォーカスさせつつ要素を全選択させたい場合 :select()
t.select();
・入力されないようグレーアウトさせる :disabled
t.disabled = true;
■イベントリスナーで関数を実行 :eventListener
ボタンがクリックされたとき、キーボードが操作された時など、様々なイベントをキーとして動作を追加できる
const b = document.querySelector('button'); b.addEventListener('click', () => { console.log('clicked!'); })
■スクロール
指定の要素までスクロール
targetNode.scrollIntoView()
・ゆっくりスクロールさせたい場合
targetNode.scrollIntoView({ behavior: 'smooth' })
・スクロール位置を微調整したい場合
const targetZahyou = targetNode.getBoundingClientRecte() targetY = targetZahyou.top + window/pageYOffset sindow.scrollTo({ top: targetY, behavior: 'sooth' })
■座標の取得 :mousemoveイベントのclientX,clientY
const d = document.querySelector('div'); //divに座標を表示するためにdを用意 document.addEventListener('mousemove', e => { //mousemoveイベントを実行。引数にeを設定 d.textContent = `${e.clientX}:${e.clientY}`; //eのclientXでX座標を取得できる });
↑引数にeを渡してあげるとイベントオブジェクトが返ってくるので、それにアクセスすることで動作を指定できる。
・aタグに対し操作を行う際は href属性が空だと自身のページを読み込むためNG
★要素の規定の動作をキャンセル :preventDefault()
~HTML~
.hidden { display: none; } <p>テストだよ!<span class="hidden">隠しテキストだよ!</span><a href="">読み込む…</a></p>
~js~
const a = document.querySelector('a'); const s = document.querySelector('span'); a.addEventListener('click', e => { e.preventDefault(); //aタグの規定の動作(ページ遷移)をキャンセル a.classList.add('hidden'); s.classList.remove('hidden'); });
■addEbentListenerいろいろ
参考:https://qiita.com/kogirix/items/77417702cbc474f49df1
■要素がクリックされたらイベントを起動
const st = document.getElementById('start'); //スタートボタンをidで取得 st.addEventListener('click', () => { sttime = Date.now(); //クリックされた時の処理 });
■押されたキーボードの値を取得
window.addEventListener('keydown', (e) => { e.key //ウィンドウで押下されたキーの値を取得 })
■画面をクリックしたらイベントを起動
window.addEventListener('click', (e) => { //画面をクリックしたら })
■アラートを表示
alert('Game Over'); //アラートを表示
■画面幅で改行が発生しているかを判定
window.addEventListener('DOMContentLoaded', () => { let range = new Range(); range.selectNode(inlineNode); console.log(range.getClientRects().length) //行数が取得できる })
■HTMLCollectionのlengthが取得できない
document.getElementsByClassNameで要素を取得するとHTMLCollectionが返ってくる。
console.logで出力するとlengthはしっかりカウントされている(ゼロでない)のだが、このlengthを取得しようとするとなぜか0になる。
const a = document.getElementsByClassName; console.log(a); //HTMLCollectionが表示され、プロパティのlengthは0ではなく、値も取得できている。 const b = a.length; console.log(b); //なぜか0になる
・解決方法
調べたところ、HTMLCollectionの値が取得される前にconsole.log(b)を実行してしまっている可能性。
正確な読み込みタイミングは調べていないが、以下の順?
window.addEventListener('DOMContentLoaded', () => { //DOMが完全に読み込まれてから処理を行う if(document.getElementsByClassName('sample-class').length) { console.log('exist'); } else { console.log('not'); } })
試してはいないけど、処理順の問題ならasinc、awaitでも解決できそう。
Uncaught ReferenceError:
【概要】
・マイクロソフト開発
・JavaScriptの拡張。大規模開発に対応できるように
・静的な型付け(jsは動的)なので一度型が決まると変えられない
・クラスベースのオブジェクト指向
・公式サイト: https://www.typescriptlang.org/
【基本】
main.tsファイルを作成
tsc main.ts //実行
node main.js //コンソール出力
■型推論が適用される
var i: number = 10; //型明示 var i = 10; //型推論でintと判断される var x; //any型
■配列
var results: number[]; results = [10, 5, 3];
■列挙
enum Signal { Red = 0, Blue = 1, Yellow = 2 } enum Signal { //数値は省略できる Red, //0 Blue = 3, Yellow //4 ※設定の後からの連番になる } var result: Signal;
■関数
function 関数名(引数): 戻り値 { return a + b; }
例)
function add(a: number, b: number): number { return a + b; }
//戻り値が無い場合はvoid
//?を付けて引数の要求を任意にすることができる。(a: number, ?b: number)
ただし、任意の引数の後に必須の引数を定義することはできない
//引数に初期値を渡すこともできる(a: number = 10, ?b: number)
■無名関数
var add = function(a; number, b: number): number{ return a + b; }
アロー関数にすると
var add = (a; number, b: number): number => { return a + b; }
さらに短く
var add = (a; number, b: number): number => a + b;
■関数のオーバーロード(関数名が同じで型が違う)
function add(a: number, b: number): number; function add(a: string, b: string): string; function add(a: any, b: any): any { //関数宣言はany型にする if(typeof a === "string" && typeof b ==="string"){ return a + " " + b; } return a + b; } console.log(add(5, 3)); //8 console.log(add("hello", " world")); //hello world //その他の組み合わせはコンパイルエラーになる
■クラス
class User { public name: string; constructor(name: string){ this.name = name; } //変数宣言とコンストラクタ処理を同時に行う場合、 //以下のように宣言もコンストラクタ内の記述も不要 constructor(public name: string){ //private _nameのように、プライベートの場合は慣習的に_を付ける } sayHi(): void{ //メソッド。functionは書かない console.log("hi! i am " + this._name); } //ゲッター(getter)とセッター(setter) get name() { return this._name; } set name(newValue: string) { this._name = newValue; } } var tom = new User("Tom"); console.log(tom.name); tom.sayHi();
■継承 ※例として上記のUserクラスを継承
class AdminUser extends User { constructor(_name: string, private _age: number) { super(_name); } public sayHi(): void { //親クラスと同じメソッド名を使うとオーバーライドする console.log("my age: " + this._age); super.sayHi(); //親クラスのメソッドを呼ぶ } }
継承される可能性があるクラスは、親クラスのプロパティの修飾子はprotectedが良い
■静的メンバ・静的メソッド
class User { constructor(private _name: string){ User.count++; //静的メンバにアクセスするにはクラス名(User)を付ける } static count: number = 0; //静的メンバ static showDescription(): void { //静的メソッド console.log("this class is about users"); } } console.log(User.count); //静的メンバ呼び出し User.showDescription();
【環境構築】
参考:https://qiita.com/ochiochi/items/efdaa0ae7d8c972c8103
・node.jsのインストール
コマンドプロンプトで確認
node -v npm -v
・typescriptコンパイラのインストール
npm install -g typescript //-g:グローバル環境にインストール
確認
tsc -v
ファイル名に日本語を指定した場合
ブラウザによって文字化けすることがあるので文頭に
@charset "UTF-8";
と記載しておく
余白(line-height - font-size)は上下均等に割り振られる
pxでの指定以外に以下のように設定することもできる
line-height: 2; font-sizeの2倍
em設定されているフォントサイズの2文字分
※Aは子要素ごとに再計算されるのでAの方が使われる。
opacity: 0.9;
※0に近いほど薄くなる。デフォルトは1
・background-color: hsl(色相,彩度,明度); //HSLでの設定
・透明度:rgbでもhslでも、最後にaをつけて表現する
background-color: hsla(色相,彩度,明度,1.0);
sans-serif:総称フォント(よしなに選んでくれる)
※空白が入るフォント名はクォーテーションで囲う
font-family: Verdana, 'Arial Black', メイリオ, sans-serif;
・インライン要素の上下中央揃え
heightとline-heightを同じ値で指定する
display: flex; align-items: center;
※box要素にしか使用できないため、inputなどはdivでラップする
左右中央寄せ
justify-content: center;
border-radius: 10px; border-radius: 50%; :正円
Flexboxでborderの重なりが気になる場合 - Qiita
background-size: cover //領域を埋める
contain //画像がすべて表示されることを保証する
box-shadow: 右へpx 左へpx ぼかしpx 拡大px 影の色rgba(0, 0, 0, .3); box-shadow: 5px 3px 2px 2px rgba(0, 0, 0, .3);
※text-shadowの場合は拡大pxの指定はできない
background-image: url(../img/header.png); :画像指定 background-position: center; ;中央揃え background-size: cover; :縦横比を保持して最大幅表示
一括指定
background: center/cover pink url(../img/header.png);
※positionとsizeは一つにまとめる(順番固定)
・paddingはwidthやheightに足される。含めたい場合は以下のように記述する。
box-sizing: border-box;
※クラスの初めに書くこと
・marginは重なると相殺される(小さいほうが打ち消される)
・width、heightの%表示は親要素に対して決められる
・hidden :隠す ・scroll :スクロールで見れるようにする
padding: 上px, 右px, 下px, 左px; padding: 上px, 左右px, 下px; padding: 上下px, 左右px;
margin-left: auto;
margin-right: auto;
・display: block //h1,p,div,sectionなどの初期値に設定されている ・display: inline ┗左詰めで横並びに配置 ┗width、heightが設定できない ┗a,img,strongなどの初期値に設定されている ・display: inlineblock ┗左詰めで横並びに配置される ┗width、heightを設定できる
・position: static; :定位置 ・position: relative; :static(初期値)の位置を起点に計算 position: relative; top: 30px; left: 30px;
※親要素にrelative、子要素にabsoluteを指定して相対的に配置することはよくある
・position: fixed; :ウィンドウの左上を起点に計算
スクロールされても位置がウィンドウの中では変わらない
・absolute:絶対配置
※親要素がstaticかそれ以外かで挙動が変わる
親要素がstaticの場合
┗ウィンドウの左上を起点に配置
親要素がstatic以外の場合
┗親要素の左上を起点に配置
baselineを基準に計算される
img { vertical-align: top;}
※何も指定しなければ後から書いたものが上にくる
各要素に
z-index: 1; z-index: 2;
というように指定すると
数字の若い要素が上にくる
・flexを使う
display: flex;
・maginを使う
margin: 0 auto;
・リストの文頭記号の変化:list-style-type
list-style-type: circle; :白丸に変更 list-style-type: none; :なし ※左に余白ができるのでpadding: 0;を指定する
・olスタイルを英語表記に:lower-alpha;
list-style-type: lower-alpha;
・改行の際にどこにそろえるか:list-style-position
list-style-position: inside;
・画像に変更
list-style-image: url(../image/icon.png);
※いくつか初期値が設定されているので上書きされないように注意
list-style: circle inside url(../image/icon.png);
<input type=”text” placeholder=”ここに入力してください”>
例えばborderは継承されないが
body { border: 1px solid pink;} h1 { border: inherit;}
とすると継承される
リンクの下線を消すのにもよく使われる。
a { text-decoration: none;}
そのほかに
打消し線
などがある
cursor: pointer;
<img src="../img/icon-search.png" alt="search-icon">
こっちの方が強力? pointer-events: none;
初期値はbaseline(文字のライン)
vertical-align: bottom;
とすれば、その要素の基準が完全に行ボックスの底に合わせられるため
余白がなくなる。
<h1 data-subtitle=" - sub title">Title</h1> ※data-●●は自由に指定できる(呼び出すときに使用する) h1::after { content: attr(data-subtitle); }
・クラスを持つ要素を指定する際は連続して書く
.thumbnails img.current //OK .thumbnails img .current //NG
・特定の複数のクラスを持つ要素を指定する場合
.thumbnails.current
・詳細度
idの個数>class,属性,疑似クラスの個数>要素,疑似要素の個数
!important; 最優先(2つあったら後者)
複数のクラスにCSSを適用 ※カンマ区切りで要素を指定する
.top-img, h3 { //mainクラスとh3要素に適用
>|??|
|
input[type=text] { input[class~=className] { //~を付けるとclassNameを含むとなる //classが複数ある場合は=では反映されない a[href^="https"] { :前方一致 a[href$="com"] { :後方一致 a[href*="com"] { :部分一致 a[class=className i] :大文字小文字を区別しない ※デフォルトは区別する
div p { //div配下のp要素 ※直下でなくても良い div > p { //div要素直下のp要素 h2 > p { //h2と並列にあるp ※h2には反映されない p + p { //h2と並列にあるp ※h2には反映されない 最初の1つだけ
.btn-shadow:hover{ opacity: 0.8; box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2); transition: 0.4s; }
・選択済みのラジオボタンにホバー時の装飾を固定
※inputとlabelをセットにしている前提
label:hober, input:checked + label { //装飾 }
子要素が並列して複数ある際に親要素に指定する
.main > p:nth-child(3) { background-color: pink; }
※該当の要素がpではない場合スタイルは適用されない
適用したい場合は
.main > p:nth-of-type(3) {
とする。
.main > p:nth-child(3n) { :3の倍数の要素 .main > p:nth-child(odd) { :奇数番目の要素 .main > p:nth-child(even) { :偶数番目の要素 .main > p:first-child { :最初の要素 .main > p:last-child { :最後の要素
()内のセレクタ以外の要素
.main > p:not(:last-child) { //p要素の最後の要素以外 :not(a) { //aタグ以外の要素
input:focus { //クリックしてフォーカスが当たっている除隊 body:focus-within //フォーカスが当たっている要素の親要素のスタイル変更
input:out-of-range { //以下のように最小値等をしているときに範囲外になると反映 //input type=”number” min=”1” max=”10”
input:invalid { //required属性等を指定しているときに条件を満たしていない場合に反映
a:link { //リンクテキストの装飾 a:visited { //訪問済みリンクの装飾
h2:target { //例えば以下のようなHTMLが指定されている場合に //ページ内リンクで飛んできた時だけ該当のh2要素にCSSを適用 //※他のh2には適用されない //<h2 id=”uncarName”></h2>
button:active { //クリックしている状態 クリックを離すと解除 input:checked { //チェックボックスやラジオボタンで選択されているとき p:empty { //<p></p>のように要素内が空の時
h1::before { content: '-'; //h1要素の前に『-』が入る }
p::first-letter { //p要素の最初の1文字目 p::first-line { //最初の行
<meta name="viewport" content="width=device-width, initial-scale=1"> ※content="width=device-width スマホの画面幅に表示領域を合わせる ※initial-scale=1 最初の倍率を等倍にする
例)要素:画像・テキスト・広告の順で表示
広告は800px以上で表示
600px以上で画像・テキストを横並びにする
//599px以下のスタイル body { margin: 0; } aside { display: none; //小さい幅ではasideは非表示 } .image { height: 100px; //画像は横幅は自由に広がる※これじゃダメじゃね? } .text { height: 100px; } @media (min-width: 600px) { //600~799pxのスタイル section { display: flex; //横並びにする } .image { width: 200px; //画像幅の固定 } .text { flex: 1; //ブラウザ幅で可変 } } @media (min-width: 800px) { section { width: 800px; //最大幅を指定 margin: 0 auto; //中央揃え } aside { display: block; //noneにしていたasaideを表示 width: 160px; //新しく表示されるasideの幅指定 }
・メディアタイプを指定することでスクリーン、テレビ、プリンタ、プロジェクタなど
使用する端末ごとの設定をすることもできる。
http://www.htmq.com/csskihon/009.shtml
@media screen and (min-width: 800px) {
............................................................
<input class=”sample” type=”text” disabled>
//disabledをつけるだけ。ちなみにこれはcssではなく属性。
・cssでdisabledされたときにcssを変える場合は以下のように疑似要素で指定する。
.sample:disabled {}
・すごくいろいろできる
https://www.webdesignleaves.com/pr/css/css_basic_07.html
・基本っぽいやつ
https://qiita.com/7968/items/1d999354e00db53bcbd8
■floatで画像が下の要素にかぶる場合
下の要素にclearを使用する。
※display:blockの要素にしか対応できない点に注意
img {float: right;} h2 {clear: right;}
https://www.tam-tam.co.jp/tipsnote/html_css/post10099.html
サイズを決めるbox(親要素)に
position: relative;
画像の要素に
position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);
・もっと簡単なのがあった
子要素に
height: 100%; width: 100% object-fit: cover;
これをやると親要素のoverflow: hiddenすら必要なくなる
・それぞれの要素をdivでくくって、親要素にflex
<div class="budget-box"> <div> <p class="budget-text"> 予算(月4回)税込 </p> </div> <div> <p class="budget-text"> キッズ(月4回)税込 </p> </div> </div> .budget-box { height: 40px; margin-top: 8px; display: flex; justify-content: flex-end; align-items: flex-end; flex-direction: column; } .budget-text { margin-bottom: 0; }
既存のフォームは装飾が無くダサいうえにカスタマイズできない。
元のフォームはdisplay: hiddenで隠してしまって、別のテキストリンクを用意してlabelで紐づける。
~HTML~
<div class="row"> <label for="file_upload_top" class="link-text">トップ画像を変更</label> //テキストリンクを用意 <input type="file" name="file" accept="image/jpeg, image/png" id="file_upload_top" style="display:none"> //実際のフォームは隠す </div> <div class="row"> <label for="submit" style="cursor: pointer;" class="btn btn-primary my-3 inactive" id="file-submit">送信</label> //ボタンを用意 <input type="submit" id="submit" style="display:none"> //実際のフォームは隠す <p id="file_upload_top_text" class="m-3 d-flex align-items-center"> ファイルが選択されていません //ファイルが選択されたらファイル名に置き換え </p> </div>
~JavaScript~
※無くても良い。
inactiveクラスはファイルがセットされたかどうかでグレーアウトの出し分けをしている
/* ファイルアップロードフォーム装飾 */
$(function(){ $('#file_upload_top').on('change', function(){ const file = $(this).prop('files')[0]; $('#file_upload_top_text').text(file.name); //ファイル名を表示 $('#file-submit').removeClass('inactive'); }) })
PCでは一定の大きさを維持したい。
しかし画像の大きさを維持する設定をするとスマホ表示の時に小さくなりすぎ
・場合分けをすると大変なのでimgではなく背景画像として表示する
~HTML~
<div class="cover"></div>
~CSS~
.cover { background: url(img/dkt_search_top.png) no-repeat center center; background-size: cover; height:360px; }
テーブルの見出しなど、改行したくない場合
white-space: nowrap;
例)