- 投稿日:2020-01-22T21:02:33+09:00
p、h1要素の横幅を文字数合わせる
pタグ、h1タグの要素の横幅はデフォルトでは親要素の横幅に合わせられています。
<body> <h1>hello world.</h1> <p>hello world.</p> </body>h1 { background: skyblue; /* デフォルトの状態 display: block */ } p { background: pink; /* デフォルトの状態 display: block */ }これはpタグ、h1タグはデフォルトのdisplayプロパティの設定がblockとなるためです。
pタグ、h1タグのようなデフォルトのdisplayがblockの要素の横幅を文字数に合わせて設定する場合は以下のようにCSS設定をします。
h1 { background: skyblue; display: inline-block; } p { background: pink; display: inline-block; }
- 投稿日:2020-01-22T20:51:16+09:00
pre-commitとtextlintを使ってHTMLに潜むゼロ幅スペース文字や記号の表記ゆれを倒す
概要
括弧や数字の全角半角が表記揺れしていたり、
href
内にゼロ幅スペースが紛れ込んでいてリンク切れが起こってしまったりすることをtextlintを使って防ごうという記事です。textlintとは?
文章の校正をしてくれるリンターツールです。漢字よりひらがなのほうがいい場合や、「てにをは」がおかしいような文章を指摘してくれます。
導入手順
1. プロジェクトの作成
※ この工程は
package.json
を生成するものです。すでにある方はスキップしてください。npm init2. パッケージのインストール
npm install --save-dev textlint textlint-rule-prh # textlint関係 npm install --save-dev husky lint-staged # pre-commit関係
- textlint:textlint本体
- textlint-rule-prh:textlintで使う辞書を読み込めるようにするためのもの
- @textlint/textlint-plugin-text:もともとtextlint本体に付属するプレーンテキスト用のプラグイン
3. pre-commitが動作するように設定する
package.json
に次の項目を追記してください。{ "husky": { "hooks": { "pre-commit": "lint-staged" } }, "lint-staged": { "*.html": "textlint" } }4. textlintの設定ファイルを作成
./node_modules/.bin/textlint --init
作成された
.textlintrc
ファイルの中身を次のように上書きしてください。
これでtextlintがHTMLファイルを読むようになり、オリジナルの辞書を利用するようになります。※今回は使いませんがHTMLを読むためのプラグイン「
textlint-plugin-html
」については後述します。{ "filters": {}, "rules": { "prh": { "rulePaths": ["./prh.yml"] } }, "plugins": { "@textlint/text": { "extensions": [".html"] } } }5. 辞書ファイルを作成
package.json
と同じ階層にprh.yml
というファイルを作成します。
中身を次のように設定してみてください。version: 1 rules: - expected: VS Code patterns: VSCode prh: 正しい表記はVS Code - expected: "" patterns: "/[\\u034f\\u200b\\u200c\\u200d\\u200e\\u200f\\u2028\\u2029\\u202a\\u202b\\u202c\\u202d\\u202e\\u2061\\u2062\\u2063\\ufeff]/" prh: ゼロ幅スペースを検出しました項目を増やしたいときは次の塊を追加することで対応できます。
patterns
には正規表現も利用できますし、リストで複数項目設定することもできます。- expected: 正しい表記 patterns: 検出する表記 prh: エラーメッセージ(説明文)参考:prh/prh.yml at master · prh/prh
6. 試してみる
プロジェクト内に適当なHTMLファイルを作成します。たとえば、
test.html
など。<!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> </head> <body> <p>私はVSCodeが好きです</p> <p>ここに→""←ゼロ幅スペース文字がいます</p> </body> </html>このHTMLファイルが
package.json
と同じ階層にあるとき、次のようなコマンドでリンターに検査させられます。./node_modules/.bin/textlint test.htmlするとおそらく次のようなログがでるはずです。
D:\dummy\dummy\test.html 10:6 ✓ error VSCode => VS Code 正しい表記はVS Code prh 11:9 ✓ error => ゼロ幅スペースを検出しました prh ✖ 2 problems (2 errors, 0 warnings) ✓ 2 fixable problems. Try to run: $ textlint --fix [file]出ない場合は、
node_modules
フォルダを削除し、npm i
コマンドを実行してみてください。7. コミットしてみる
うまくpre-commitが動作していれば次のようなエラーが出てコミットが中断されるはずです。
こちらもうまく出ない場合は、node_modules
フォルダを削除し、npm i
コマンドを実行してみてください。Sourcetree
TortoiseGit
いろいろ試してみよう
検出には正規表現も使えるので、他にも様々な表記ゆれや誤実装を回収できそうです。
- expected: ( patterns: ( prh: 全角括弧を利用してください - expected: ) patterns: ) prh: 全角括弧を利用してくださいなどなど…。Webサイトの運用で表記ゆれやゼロ幅スペースにお困りの場合は試してみてください。
タグを無視する
textlint-plugin-html
HTMLのタグを無視させたい場合は
textlint-plugin-html
を一緒にインストールしてください。npm i -D textlint-plugin-html
.textlintrc
の設定は次のようになります。{ "filters": {}, "rules": { "prh": { "rulePaths": ["./prh.yml"] } }, "plugins": [ "html" ] }なお、どうやら
©
などは「©」として解釈されるようなので、不要な実態参照を検出するルールはできない模様。たぶん。おそらく。検出されない場合がある(追記)
コードの順番など、特定のケースでうまく検出されない場合がある模様。調査中。
https://github.com/textlint-rule/textlint-rule-prh/issues/74参考文献
- 投稿日:2020-01-22T20:43:59+09:00
jQueryのメソッド
jQueryとこの記事について
『jQuery』とは、効果やアニメーションを簡単に実装できるJavaScriptライブラリ。
jQueryを使うとWEBページにアニメーションや効果を簡単につけることができる。
jQueryを勉強中(ど素人)なのですが、復習も兼ねて学んだメソッドを
下記にメモとして記述していこうと思います。随時更新していきます。hide
- セレクタ(HTMLのタグ名やclass名,idなどを指定する)で指定した要素を隠すことができる。
例: $('h1').hide();
show
- セレクタで指定した隠れている要素を表示することができる。
例: $('h1').show(slow);
fadeOut
- セレクタで指定した要素を徐々に隠すことができる。
- アニメーションの速度は()内に引数として指定することができる。(1.0秒 → 1000、slowなど)
例: $('.class').fadeOut(1000);
fadeIn
- セレクタで指定した要素を徐々に表示ことができる。
例: $('.class').fadeIn(slow);
slideUp
- セレクタで指定した要素を下から上にスライドしながら隠すことができる。
例: $('#id').slideUp(1000);
slideDown
- セレクタで指定した要素を上から下にスライドしながら表示することができる。
例: $('#id').slideUp(slow);
css
- セレクタで指定したCSSを変更することができる。引数①にプロパティ、引数②にプロパティの値を設定する。
例: $('p').css('color','blue');
※ちなみに、
$('img').css('display','none'); ⇦ hideメソッドと同じ
$('img').css('display','block'); ⇦ showメソッドと同じtext
- セレクタで指定した要素のHTMLの中身を引数で指定した内容に書き換えることができる。
例: $('p').text('アイウエオ');
html
- セレクタで指定した要素の中身のHTMLを引数で指定したものに書き換えることができる。
例: $('p').html('アイウエオ');
find
- セレクタで指定した要素の子孫要素から、引数で指定した要素を全て取得することができる。
例: $('.class').find('p');
この場合、'.class'というクラス内の'p'要素を取得することができる。
children
- セレクタで指定した要素の子要素(1階層分)から、引数で指定した要素を取得することができる。
例: $('.class').children('p');
addClass
- セレクタで指定した要素に引数で指定したクラスを追加することができる。
例: $('.class1').addClass('.class2');
removeClass
- セレクタで指定した要素から引数で指定したクラスを取り除くことができる。
例: $('.class1').removeClass('class2');
hasClass
- セレクタで指定した要素が引数で指定したクラスを持っているか判定することができる。
例: $('.class1').hasClass('class2');
・if文の条件式として設定することができる
if($('.class1').hasClass('class2'))
{
// 処理内容
}eq
- セレクタで指定したオブジェクトから引数で指定した数値と同じインデックス番号をもつ要素を取得することができる。
例: $('li').eq(2).css('color','red');
index
- セレクタで指定したオブジェクトにおいて、引数で指定した要素が存在するインデックス番号を取得することができる。
例: $('li').index($('active'));
prev
- セレクタで指定したオブジェクトの同じ階層の1つ前の要素を取得することができる。
例: $('#id').prev().css('color','red');
next
- セレクタで指定したオブジェクトの同じ階層の1つ次の要素を取得することができる。
例: $('#id').next().css('color','blue');
attr
- セレクタで指定した要素に引数で指定した属性名・属性値を設定することができる。
- また、第2引数を指定しなかった場合、第1引数で指定した属性名の値を取得することができる。
例: $('h1').attr('id','title');
var url = $('a').attr('href');
val
- セレクタで指定した要素のvalue値を取得することができる。
例: var text = $('#input').val();
animate
- セレクタで指定した要素に対して、引数1で指定したプロパティの値を設定することができる。
- また、引数2でアニメーションの速度を指定することができる。
例: $('h1').animate({'font-size':'20px'},1000)
- 投稿日:2020-01-22T18:34:03+09:00
HTML + JavaScript 非同期でIPアドレスを取得して表示する
ちょっとクライアントでIPアドレスを取得する必要があったので、
やり方を残しておきます。今回はipinfo.ioのJSONP API使用してIPアドレスを取得しました。
こちらはchromeのデベロッパーツールでも簡単に試せます。ちなみにipinfo.ioは自分のIPアドレスを教えてくれるWebサービスです。
JavaScript
$.ajax({ url: "https://ipinfo.io", dataType: "jsonp", success: function(res){ $(".ip-address").text(res.ip); } });chromeのデベロッパーツールのConsoleに、↑をそのまま貼り付けて実行してもらうと
どういった値が取得できるのか確認できます。HTML
<p> あなたのIPは<a class="ip-address"></a>です。 </p>画面に表示させるためにデベロッパーツールのElementsにこちらを追加し、
もう一度Consoleでさっきのスクリプトを実行するとIPアドレスが表示できると思います。まとめ
通常、IPアドレスはサーバで取得することが多いかと思いますが、
今回のようにクライアントでもIPアドレスを取得したい時に役立ちます。
- 投稿日:2020-01-22T17:45:57+09:00
【備忘録】Bootstrap
目的
Bootstrap で web page を作る際に調べた内容の備忘録。
作成した web page はこちら(建設中...)。備忘録
ボタンを押すとページ内の該当箇所にジャンプするアレ
Scrollspy でできる。以下の資料を参照。
https://www.w3schools.com/bootstrap4/bootstrap_scrollspy.asp
- 投稿日:2020-01-22T13:48:42+09:00
CSS3のみでハンバーガーメニューを作る方法
CSSだけでハンバーガーメニューを作れたので参考サイトと作り方をメモします。
参考サイト
https://www.nxworld.net/tips/12-css-hamburger-menu-active-effect.html
- リストを作る
<div id="ham-menu"> <ul> <li>1</li> <li>2</li> <li>3</li> <li>4</li> </ul> </div>2.CSSをいじくる
#ham-menu{ position: fixed; height:100%; width: 300px; right: -300px; top: 0; background-color: #222; padding: 10px 40px; z-index: 999; box-sizing: border-box; /*パディングとボーダーを幅と高さに含める*/ taransition: transform .3s linear 0s; } #ham-nenu:before{ position: absolute; width:50px; height: 50px; top: 0; right: 100%; content: "≡"; text-align: center; font-size: 50px; color: #FFF; line-height: 50px; /*縦位置中央化*/ background-color: #222; z-index: 999; border-radius: 0 0 0 10px; display: block; } #menu-background{ background-color: #222; display: block; height: 100%; opacity: 0; position: fixed; right: 0; top: 0; transition: all .3s liner 0s; z-index: 999; } #ham-menu:hover{ transform: translate(-300px); } #ham-menu:hover + #menu-background{ opacity: .5s; z-index: 999; } li{ list-style: none; padding: .5em 0; }
- 投稿日:2020-01-22T12:05:49+09:00
HTMLになどの特殊空白文字が含まれていないか検品する
(Gitのpre-commitでしっかり検査したい方はこちら)
ブックマークレット
javascript:!function(){const o=(o=>{const e=[];for(const o of[11,847,8203,8204,8205,8206,8207,8232,8233,8234,8235,8236,8237,8238,8289,8290,8291,65279])e.push(String.fromCharCode(o));return e})(),e=[],t=[],n=o=>{let e=o.parentNode,t=0;for(;e;)e=e.parentNode,t++;return t};for(const o of[...document.all]){const t=n(o);e[t]||(e[t]=[]),e[t].push(o)}e.reverse();for(const n of e)if(n&&n[Symbol.iterator])for(const e of n)for(const n of o)if(-1!==e.outerHTML.indexOf(n)){const o=document.createElement("div");let r=null;e.style.backgroundColor="tomato",e.style.outline="2px solid tomato",o.innerHTML=e.outerHTML.replace(new RegExp(n,"g"),""),r=o.firstElementChild,e.replaceWith(r),t.push([r,e])}if(t.length){console.group("★の位置に特殊文字を検出しました");for(const{0:e,1:n}of t){let{outerHTML:t}=n;e.replaceWith(n);for(const e of o)t=t.replace(new RegExp(e,"g"),"★");console.log(n,t)}return console.groupEnd(),void window.alert(`${t.length}個の要素に特殊空白文字が含まれているようです`)}window.alert("OK")}();概要
Microsoft製品(だけではないけれども)を利用していると、原稿に特殊な目に見えない空白文字が紛れ込むことがあります。
代表格が文字コード
8203
のゼロ幅スペースです。一見すると何も入力されていないように見えるますが、実際には目に見えない空白文字が入力されています。これがURLの中に紛れていたりすると非常に厄介です。URLエンコードされてしっかり文字列として解釈されるので、正しくリンクが繋がりません。目視ではこの特殊文字がいないように見えるので、原因に気づくまでに時間がかかってしまうかもしれないですね。
console.log('abc'.length); // > 3 console.log('a'.charCodeAt(0)); // > 97 console.log(String.fromCharCode(97)); // > "a" console.log(String.fromCharCode(97).length); // > 1 console.log(String.fromCharCode(8203)); // > "" console.log(String.fromCharCode(8203).length); // > 1
​
はエディタ上で視認できませんでした。ただ、「?」と表記されることもあるようです。
※ VS Code、Sublime Text3では確認できませんでした。空白文字は意外と種類がある
NeqZ8y5◆mmft4k9vgtL6さんの公開している5chってどうよ?内、「2. スペースは" "だけじゃない的な話」によると、50種類以上もスペースに似た何かがあるようです。
このブックマークレットは、当該記事で紹介されている空白文字をページ内から検出するものです。
アラートダイアログで結果を表示し、コンソールに詳細を出力します。
おまけで元コード
void function () { // 検査する文字列 const strSet = (charCodeSet => { const set = []; for (const charCode of charCodeSet) { set.push(String.fromCharCode(charCode)); } return set; })([ // 引用:http://anti.rosx.net/etc/memo/002_space.html 11, // 垂直タブ 847, // 結合書記素接合子 8203, // ゼロ幅スペース 8204, // ゼロ幅非接合子 8205, // ゼロ幅接合子 8206, // 記述方向制御(左から右へ) 8207, // 記述方向制御(右から左へ) 8232, // 行区切り文字 8233, // 段落区切り文字 8234, // LRE 8235, // RLE 8236, // PDF 8237, // LRO 8238, // RLO 8289, // 関数適用 8290, // 不可視の乗算記号 8291, // 不可視の区切り文字 65279 // ゼロ幅のノーブレークスペース ]); const targets = []; // すべての要素が親要素の多い順(ネストの深い順)に格納される const cache = []; // もともとのマークアップをキャッシュする const getParentLength = node => { let parent = node.parentNode; let count = 0; while (parent) { parent = parent.parentNode; count++; } return count; }; for (const node of [...document.all]) { const length = getParentLength(node); if (!targets[length]) { targets[length] = []; } targets[length].push(node); } // 親の数が多い順 targets.reverse(); for (const layer of targets) { if (!layer || !layer[Symbol.iterator]) continue; for (const node of layer) { for (const str of strSet) { if (node.outerHTML.indexOf(str) === -1) continue; { const dummyContainer = document.createElement('div'); let firstElementChild = null; node.style.backgroundColor = 'tomato'; node.style.outline = '2px solid tomato'; dummyContainer.innerHTML = node.outerHTML.replace( new RegExp(str, 'g'), '' ); // 一次置き換え後の要素のアドレスを確保しておく firstElementChild = dummyContainer.firstElementChild; // 上位階層が多重検出されないように // いったん特殊文字を削除したマークアップに置き換える node.replaceWith(firstElementChild); cache.push([ firstElementChild, node ]); } } } } if (cache.length) { console.group('★の位置に特殊文字を検出しました'); for (const {0: dummy, 1: origin} of cache) { let {outerHTML} = origin; dummy.replaceWith(origin); for (const str of strSet) { outerHTML = outerHTML.replace(new RegExp(str, 'g'), '★'); } console.log(origin, outerHTML); } console.groupEnd(); window.alert(`${cache.length}個の要素に特殊空白文字が含まれているようです`); return; } window.alert('OK'); }();出典
- 投稿日:2020-01-22T11:14:45+09:00
【備忘録】HTML
目的
HTML でものを作っている中で、つまづいた内容についての備忘録。
逐次更新の予定。備忘録
横並びのメニューバーをヘッダ部分につくりたい
header 部分にリストを作成する。 style でリストを横並びにする。
index.html<body> <header> <ul> <li><a class="btn_menu" href="contents/profile_en.html" target="main">Profile</a></li> <li><a class="btn_menu" href="contents/research_en.html" target="main">Research</a></li> <li><a class="btn_menu" href="contents/publication_en.html" target="main">Publication</a></li> <li><a class="btn_menu" href="contents/distribution_en.html" target="main">Distribution</a></li> </ul> </header> </body>display: inline-block; のところで横並びを定義してる。
style.cssheader{ z-index: auto; height: fit-content; width: 100%; position: relative; top: auto; background-color: dodgerblue; text-align: center; z-index: auto; } ul { overflow: hidden; list-style: none; margin: 0 auto; z-index: auto; } ul li { display: inline-block; padding: 10px 20px 10px 20px; }
- 投稿日:2020-01-22T09:19:00+09:00
getElementId使用して気になったこと
AngularフレームワークでTypeScript を使用してたときにビルドエラーになってとりあえず調べた結果をまとめる。
エラー内容
以下のコードを書いていた。
<!-- HTML --> <input type="file" id="recorder"> <audio id="player" controls></audio>// TypeScript const recorder = document.getElementById("recorder"); const player = document.getElementById("voice-player"); recorder.addEventListener("change", function(e: Event) { const file = e.target.files[0]; player.src = URL.createObjectURL(file); });player.srcでsrcは存在しないというエラー。
原因
playerの型がHTMLElement型になっていた。audioタグだしHTMLAudioElementが返ってくると勝手に思ってしまっていた。
.getElementById()はHTMLElement型で返ってくるので自分でキャストする必要があった。
以下のようにキャストした。const player = <HTMLAudioElement>document.getElementById("voice-player");これでビルド通ったけど、キャストする以外に方法はないのだろうか。