これはメモです

それ以上でもそれ以下でもないのです

tabindexの初期値について

divなどの通常フォーカスできない要素にJavaScriptでフォーカスを持たせる場合、tabindex="-1"を指定することがある。 ふと気になってtabindexのデフォルト値が何なのか調べてみた。

console.log(document.createElement('div').tabIndex); // -1
console.log(document.createElement('a').tabIndex); // 0
console.log(document.createElement('button').tabIndex); // 0

abuttonといったフォーカス可能な要素は0, それ以外は-1になるよう。 初期値が-1であれば指定不要では…?

と思ってtabindexを指定せずにフォーカスを当ててみようとしたが失敗。

仕様がどうなっているか確認。HTML Living Standardによると、

The tabIndex IDL attribute must reflect the value of the tabindex content attribute. The default value is 0 if the element is an a, area, button, frame, iframe, input, object, select, textarea, or SVG a element, or is a summary element that is a summary for its parent details. The default value is −1 otherwise. HTML Standard 6.6.3 The tabindex attribute

訳すと以下のような意味になる。

  • tabIndexのIDL属性は、 content属性の値を反映する必要がある。
  • 以下の要素のIDL属性は初期値が0。それ以外は-1
    • a
    • area
    • button
    • frame
    • iframe
    • input
    • object
    • select
    • textarea
    • SVGa
    • detailsの子要素であるsummary

聞き慣れないIDL属性、content属性と言う言葉が出てきた。 ざっくり言うと下記のような意味らしい。

  • IDL属性 … JavaScriptのプロパティ。
  • content属性 … HTMLで設定した属性。

つまり、JSのtabIndexプロパティの初期値は0-1で、HTMLに設定したtabindexの値はJSのプロパティに反映されるということらしい。 そのため、最初に調べたのはtabIndexプロパティであって、tabindex属性とは別。 ではHTMLにtabindexを設定しない場合、属性値は何になるのか。

console.log(document.createElement('div').getAttribute('tabindex')); // null
console.log(document.createElement('div').tabIndex); // -1

nullになった。HTMLに設定されたtabindexはJS側にも反映されるが、未指定の状態では相違が生じるということになる。

まとめると

  • HTML属性値とJSプロパティは同一のものに見えるが、実際はそうではない。
  • フォーカス可能要素以外にフォーカスを持たせる場合は、やはりHTML側でtabindex属性を明示的に指定する必要がある。

余談

また別の話だと思うが、ahrefもHTML属性とJSプロパティとで返す値が異なる。 仕様上、HTMLAnchorElementhref属性は絶対URIをを表すと決められている。

<a href="#hoge"></a>
// 表示ページのURLをhttps://example.comとする
document.querySelector('a').href; // https://example.com#hoge
document.querySelector('a').getAttribute('href'); // #hoge

以上。

参考

PHPで連想配列の値が空か判定する

ちょっと詰まったのでメモ。

$arrayとかisset()で判定できるのかなと思いきや出来なかった。

<?php
$array = [
    'elm1' => '',
    'elm2' => [],
];
var_dump(!$array); // false
var_dump(!isset($array)); // false

調べたところ、array_filter()の第二引数(コールバック関数)を省略することでフィルタリングができるとのこと。

コールバック関数が与えられなかった場合、 array のエントリの中で空のものはすべて削除されます。 この場合の「空」の定義については、empty() 関数を参照して下さい。PHP: array_filter - Manual

<?php
$array = [
    'elm1' => '',
    'elm2' => [],
];

$filtered = array_filter($array);

var_dump($filtered); // []
var_dump(!$filtered); // true

参考

MAMPのMySQLでrootパスワードを再設定する

rootを「パスワード設定なし」にしたらエラーでMySQLに接続できなくなり再設定したのでメモ。

接続できません。設定が無効です。

mysqli::real_connect(): (HY000/1045): Access denied for user 'root'@'localhost' (using password: YES)

MySQL サーバに接続しようとしましたが拒否されました。config.inc.php のホスト、ユーザ名、パスワードが MySQL サーバの管理者から与えられた情報と一致するか確認してください。

config.inc.phpとの不一致からエラーが出るよう。

1. パスワードなしでmysqlにログインできるようにする

/Applications/MAMP/conf内にmy.cnfファイルを作成し、下記記述を追加して保存。

[mysqld]
skip-grant-tables

2. 'mysql'データベースのuserテーブル内のrootパスワードをSQLで再設定する

初期パスワードはrootなので、rootにしておくと3.の工程は不要。

UPDATE user SET authentication_string=password('新規パスワード') WHERE user='root';

3. config.inc.phpに記載のパスワードを2. で設定したパスワードに変更する

エラーメッセージにはディレクトリの記載がないので分かりづらい。

/Applications/MAMP/bin/phpMyAdmin5にあるconfig.inc.php内のパスワードを変更する。

- $cfg['Servers'][$i]['password']  = 'root';
+ $cfg['Servers'][$i]['password']  = '新規パスワード';

4. MAMPを再起動

これで直るはず。

参考

create-react-app/TypeScriptの環境構築

create-react-appの環境構築を効率化するため、備忘としてメモ。 大岡由佳 著 りあクト!【I.言語・環境編】【II.React基礎編】第3.1版を参考に行った。 こちらの書籍ではパッケージマネージャーにyarnを使用しているが、普段npmを使用しているためnpmで作業を行う。

環境・バージョン

  • MacBook Air M1 Monterey 12.1
  • Node.js v16.13.0
  • npm 8.1.0

1. create-react-appのインストール

create-react-appのインストールを行う。アプリケーション名はcra-ts-templateとした。 TypeScriptを使用するため、オプションとして--template typescriptを指定する。

npx create-react-app cra-ts-template --template typescript

インストール完了後、ターミナルの最後には下記メッセージが表示される。

We suggest that you begin by typing:

  cd cra-ts-template
  npm start

Happy hacking!

上記コマンドをターミナルに入力し、アプリケーションが立ち上がれば無事インストールできている。

これ以降、カレントディレクトリはcra-ts-templateとして話を進める。

2. TypeScriptのバージョン確認

create-react-appによってインストールされたTyepScriptのバージョンを確認する。 tsc -vで確認できる。tstypescriptではない点に注意。 今回は4.4.4だった。

tsc -v

補足:インストール済みのcreate-react-appを使用する場合

TypeScript及び関連パッケージを最新版に更新しておく必要がある。

TypeScriptのバージョンアップ

下記コマンドで行う。

npm update typescript@latest

関連パッケージのバージョンアップ

まず、npm outdatedで新しいバージョンがリリースされていないか確認する。create-react-appインストール後に行ってみた結果は以下の通り。

npm outdated

Package       Current    Wanted  Latest  Location                  Depended by
@types/node  16.11.19  16.11.19  17.0.8  node_modules/@types/node  cra-ts-template

node.jsのバージョンが16.13.0に対しバージョンが古いように見える。そのため、いったんアンインストールし@types/node@16.13.0のインストールを試みた。(更新が必要なパッケージが多数ある場合、npm-check-updatesを使うと良いよう。1

npm un @types/node
npm i -D @types/node@16.13.0

すると下記のエラー。

npm ERR! notarget No matching version found for @types/node@16.13.0.
npm ERR! notarget In most cases you or one of your dependencies are requesting
npm ERR! notarget a package version that doesn't exist.

@types/node@16.13.0は存在しないらしい。npmで確認しても16.11.19までしかないようなので再インストール。

npm i -D @types/node@16.11.19

これでとりあえずcreate-react-app及びTypeScriptの環境構築は完了。 次回以降、開発を行う上で便利なツール群の導入(ESLintなど)を行っていく。

参考

オリジンについて

<link rel="dns-prefetch">について調べる際、オリジンという言葉が出てきたためメモ。

概要

  • オリジンとは、URLのスキーム(プロトコル)・ホスト(ドメイン)・ポートをあわせたもの。
  • スキーム、ホスト、ポートが一致していれば同一オリジンと言える。
  • 関連する仕組みとして、同一オリジンポリシーCORSがある。

  • オリジン: http://example.com
  • スキーム: http
  • ホスト: example.com
  • ポート: 明示されていない場合、スキームがhttpの場合は80,httpsの場合は443

スキーム、ホスト、ポートが一致していれば同一オリジンと言える。

http://example.comhttp://www.example.comでは、ホストが異なるため同一オリジンとはみなされない。

関連する仕組み

  • 同一オリジンポリシー

あるリソースから他のオリジンのリソースにアクセスできないように制限するもの。セキュリティの面で重要な仕組み。

  • CORS(Cross-Origin Resource Sharing, オリジン間リソース共有)

オリジンを跨いだアクセスを許可するもの。(同一オリジンポリシーの緩和)

その他

プロトコル以外のスキームもある。例えばmailtojavascriptなど。

例)http://www.example.com

  • ホスト: ネットワークに接続された機器を指す。この場合ホスト名はwwwで、Webサーバを示している。
  • ドメイン: インターネット通信時の接続先を示す。この場合ドメイン名はexample.comとなる。
  • FQDN(Fully Qualified Domain Name, 完全修飾ドメイン名): ホスト名+ドメイン名を示す。

参考

UI/UXについて少し勉強した

UXエンジニアに興味を持ってUI/UXの本を読んだので、特に覚えておきたい部分を備忘としてメモ。

デザインについて

デザインとは

「デザイン=設計」。デザインとは見た目だけではなく、機能を有するもの。

デザインの目的

そのデザインが持つ機能や働きにより、何らかの課題を解決すること。 (使いにくいものを使いやすく、分かりにくいものを分かりやすくする。)

デザインの必要性

必要とされる機能に代替手段がないとき、デザインの重要度は下がる。(使いづらい・分かりづらい等の不満があっても、その機能を使うしかないため。) 機能が一般化したとき、競合との差別化要因としてデザインの重要度は高まる。

UiとUX

UIとは

ユーザーインターフェース(User Interface)。ユーザーとサービスの接点となるもの。 直接的・間接的に触れて操作ができるもの。

直接的な例)マウス、キーボード、タッチパネルなど。 間接的な例)Webサイトのリンクやボタン。

UX

ユーザーエクスペリエンス。ユーザーがサービスから受ける体験のこと(使いやすい・使いづらい、情報を得られるまでが早い・遅いなど)。

UIとUXの違い

UIは客観的であり目に見える。一方、UXは主観的であり目に見えない。(=設計・評価が難しい。)

try ... catch についての学習メモ

JavaScripttry ... catchについて今まで使う機会がなく、何も知らなかったので勉強してみたメモ。

結論から言うと、エラーが発生した場合でも処理を停止させないという特徴があるようです。

// 未定義の変数iによりエラーが発生する

// 通常の処理
const a = 1;
const b = a * i; // コンソールにエラー出力
console.log( 'hoge' ); // この行は実行されない

// try ... catchによる処理
const a = 1;
try {
  const b = a * i; // 例外が発生し、catchブロックに処理が移る
} catch (e) {
  console.error( e ); // エラー内容を引数で受取り、エラーを出力
}
console.log('hoge'); // 実行される

関数などに想定していない型の引数を渡される可能性があるが、エラーにより後続の処理を止めたくないといった場合に使うような感じでしょうか。

またthrowを使うことにより、意図的に例外を発生させることもできるようです。

function getNumber(x){
  if ( typeof x !== 'number' || isNaN(x) ) {
    throw new Error( 'Parameter is not a number.' ); // 引数が数値ではない場合に例外を発生させる。
  }
  return x;
}

try{
  getNumber( 's' ); // 例外発生により関数の実行が停止し、catchブロックに処理が移る。
} catch(e) {
  console.error(e); // エラー出力 'Error: Parameter is not a number.'
}

本当にざっくりですが、少し理解できてよかった。サイト制作で使う機会は来るのかな…