「h要素」に思う
検索ヒット率の向上には「h要素」が大事、いやいやコンテンツの方が大事などと、ひと昔前は盛んに書かれていたのが、今時は YouTube再生回数~億ビューなんぞと「注目される事が最優先」という、なんだかな世相。 でもこの流れは、本当に語られるべき事が「文字」に戻って来たとすれば、むしろ好機かも知れません。
本、小説、文書などには「題」「表題」「見出し」「目次」「あとがき」などがありますが、これは人が文字を扱う歴史で、長い内容を分かり易く纏めた結果でしょう。 この分類化は、デジタルの無い時代からあります。「HTML」が作られ、大規模な文書をネット上で扱う時代になり、分類化の技法が「HTML」の仕様に取り込まれて、「h要素」「heading」になったと考えて良いと思います。
これは、やはりデジタル文書をより読み易く、内容の流れを判り易くする機能です。 「h要素」など使わなくてもブログは書けますけどね。
深層から蘇った記事
2092年のある日、スチューデントQは、半世紀以上前のインターネット文化を調べていて、興味深い発見をする。 骨董品のディスクからQが苦労して読み出したのは、とあるブログ記事のデータだった。
Qはデータの最初を調べ、記事が「snowman」による「アメーバブログの終焉」だと気付いた。 これは長く謎とされていた記事に違いないとQは思った。 同名の記事は、2031年に一旦公開されてすぐに削除され、そこにはブログ崩壊のきっかけとなった「snowman事件」の真相が、精細に書かれていると言われていたのだ。 世に知られた「事件」の真相に触れようとしている事に気付いて、Qは指が震えた。
このデータは、当時に「ブラウザ」と呼ばれたプログラムで再生できる。 Qはそれを知っていたが、研究用のマシンは文字を復元出来ても、そんなプログラムは動作しない。「多元エミュレーター」という装置を聞いた事があるが、大学にそんなものがあるとは思えなかった。
Qは1週間余りかかって、記事のテキストを全て取り出して読める様にした。 これまで世に出なかった事実に関する記述を見つける度に、解析はそっちのけになった。 そして、整理が一向に進まない。「このままではあかん。 これを公開するには、記事をもっと読み易くせな。」 そう思い立ったQは、ゼミの教授の部屋に出向いた。
Q:「先生、インターネット全盛の時代の文書データを見つけて、解析をしてるんです。 一応は読める様になったんですが、文章がみんなずらずらと繋がって、手がつけられなくて、困ってしまったんです」
教授:「ははあ、面白い事やってんねんな。 それはきっとHTMLというデータやと思うけど。」
Q:「そうなんです、80年位前に流行したブログの記事なんです。」
教授:「君は、タグ構造の事は知ってるか?」
Q: 「はい、判ってるつもりです。 読める様に、タグを全部外したんです。」
教授:「そんならね、もういっぺん元のデータで、h1とかh2とかというタグを探して、そこが文書の"見出し"と思って整理しなおしたら、うまく行くと思うな。」
Q: 「そんな裏技があるんですか! 知らんかったです。」
数日後、Qは記事の再構成を終わらせていた。 教授に教わった事を最初から知っていたら、倍ほど早く終わったんだなと思った。 整然とした記事が蘇ると、snowmanの気質が見えた気がした。 そして、Qは今回の発見を纏めた論文を書き始めた。 これは間違いなく、世に問うに値する発見だと確信していた。
そうだ、副題は「みだしはみだしなみ」にしよう。
+
まあ下手な例え話になりましたが、文章に「文節」「句読点」がある様に、「表題」「見出し」で、内容が一目で分かり易くなります。 敢えてそれを無視して効果を得るのも、表現の自由、醍醐味ですが、「高度なインプロビゼーションは、高度に定型が判っている人による」とは、私が信じるところです。
タグ種の変換方法は余り書かれていない
ネット上を探しても、「h要素」の変換テクニックについて、適確な記事が見つけられません。 これは「outerHTML」を使わないと、大変手間で不完全な結果になります。
「outerHTML」については以下のページを参照ください。
「h2要素」を「h3要素」に変換する JavaScript
以下は、「h2要素」を「h3要素」に変換する JavaScriptコードの雛形です。 こういう作業コードを作りたいと思ったら、参考にしてください。
◎ 2行目で、変換対象の「element」のタグの頭「<h2 ……」から「…</h2>」までの全てを文字列にして、変数「elem_text」に取得します。
◎ 3行目で、文字として「<h2」を「<h3」に書換えています。
◎ 4行目で、元の「element」を、書換えた内容の「HTML要素」にします。
〔注意1〕
この関数の処理によって、元の変改対象の要素は、新しく書換えた要素になります。 「h2要素」の中身は全て同じまま、HTML編集で「h3」に書換えたのと同じです。 ただし、JavaScriptからの参照は途切れた新要素になり、変換後に JavaScriptで扱うには、再取得が必要です。
〔注意2〕
この関数は、「h要素」という親戚のタグ種間の変更を前提にしています。「p要素」「div要素」の変換にも応用が可能ですが、「親戚のタグ種間」でない場合は、変換で生じる結果を良く検証する必要があります。 例えば、「a要素」を「span要素」に書き換えると、当然にリンク機能は失われます。
「要素」変換コードの精密版 JavaScript
上記の雛形コードは、広範囲に利用されている文書エディター「ckeditor」上で制作したのですが、このエディターの「終了タグ(閉じタグ)の自動補完」が動作する事を前提としていました。
ただ、この自動補完機能は、様々な条件のタグ書換えでは危ういという事を、経験のある方はすぐに気付かれると思います。 実際、ここで紹介している「Rep Heading」というツールでは、「h要素」間の変換は問題なく利用できますが、「p要素」➔「h要素」の変換では、不明な空タグの「p要素」が生成されて混入しました。
やはり、編集補助機能に「終了タグ」の生成を期待するのは、不完全なコードと言えます。 以下の雛形コードは「終了タグ」を書換えるコードを追加したもので、正規表現を使っています。 このコードは、より確実にタグ種の変換が出来ます。
「Rep Heading ⭐」の機能と操作
ツール名「Rep Heading ⭐」は、編集画面に関する起動強化コードを使う「⭐」を付けています。 このツールは常駐型で、「Tampermonkey」にインストールして常に「ON」にしておきます。 編集画面を開くと、このツールが自動で起動します。
「h要素」の種類と場所を表示
通常はステルスですが、「h2」「h3」がページ上に作成されると、編集枠の左外に「h要素」の種類を表示します。「h2」は赤、「h3」は黒の文字色です。
(下図の編集枠色などは Ameblo Writer によるデザインです)
「h要素」の範囲
下は、3個の「h要素」を作った例で、青枠は各要素の実際の範囲を示しています。
表示上は見えませんが、「h要素」は「ブロックレベル要素」なので、ページの両端まで達する範囲を占めます。
「h要素」の種類変更
これが「Rep Heading ⭐」の主機能です。
●「h要素」の範囲を「Ctrl+左Click」すると、「h2」⇄「h3」が入れ替わります。
▪ この操作の結果は、常に枠外の表示に反映し、何度でも変更できます。
▪ 枠外の「h要素」の表示部も、クリックして変更操作ができます。
〔注〕
現在、対応する「h要素」は「h2」「h3」のみで、通常生成されない「h1」や「h4」は、対応していません。
「Rep Heading ⭐」を利用するには
このツールは Chrome / Edge / Firefox版の拡張機能「Tampermonkey」上で動作します。 以下に、このツールの導入手順を簡単に説明します。
❶「Tampermonkey」を導入します
◎ 使用しているブラウザに拡張機能「Tampermonkey」を導入する事が必要です。
既に「Tampermonkey」を導入している場合は、この手順 ❶ は不要です。
拡張機能の導入については、以下のページに簡単な説明があるので参照ください。
❷「Tampermonkey」にスクリプトを登録します
◎「Tampermonkey」の「+」マークの「新規スクリプト」タブを開きます。
◎「新規スクリプト」には、最初からテンプレートが記入されています。 これは全て削除して、完全に空白の編集枠に 下のコードをコピー&ペーストします。
〔コピー方法〕 右サイドバーの マークのボタンを1度押してください。
コード枠内の右クリック ➔ コード全体の選択 ➔ コピー操作 が可能になります。
◎ 最後に「ファイル」メニューの「保存」を押すと、ツールが使用可能になります。
〔 Rep Heading ⭐ 〕 ver. 0.1
// ==UserScript== // @name Rep Heading ⭐ // @namespace http://tampermonkey.net/ // @version 0.1 // @description 記事デザインの「h2」「h3」を「Ctrl+左Click」で変換する // @author Ameba Blog User // @match https://blog.ameba.jp/ucs/entry/srventry* // @exclude https://blog.ameba.jp/ucs/entry/srventrylist.do* // @grant none // ==/UserScript== let retry=0; let interval=setInterval(wait_target, 100); function wait_target(){ retry++; if(retry>10){ // リトライ制限 10回 1sec clearInterval(interval); } let target=document.getElementById('cke_1_contents'); // 監視 target if(target){ main(); }} function main(){ let target=document.getElementById('cke_1_contents'); // 監視 target let monitor=new MutationObserver(insert_tag); monitor.observe(target, {childList: true}); insert_tag(); } // main() function insert_tag(){ let style= '<style class="rep_head">h2::before { content: "h2"; position: absolute; left: -36px; '+ 'padding: 2px 4px 0; height: 18px; font: bold 16px/19px Meiryo; '+ 'border: 1px solid #aaa; background: #fff; color: red; } '+ 'h3::before { content: "h3"; position: absolute; left: -36px; '+ 'padding: 2px 4px 0; height: 18px; font: bold 16px/19px Meiryo; '+ 'border: 1px solid #aaa; background: #fff; color: #000; }</style>'; let editor_iframe=document.querySelector('.cke_wysiwyg_frame'); if(editor_iframe){ let iframe_doc=editor_iframe.contentWindow.document; if(iframe_doc){ if(!iframe_doc.querySelector('.rep_head')){ iframe_doc.documentElement.insertAdjacentHTML('beforeend', style); }}} if(editor_iframe){ let iframe_doc=editor_iframe.contentWindow.document; if(iframe_doc){ let target=iframe_doc.body; // 監視 target if(target){ let monitor=new MutationObserver(change_tag); monitor.observe(target, {childList: true}); }}} change_tag(); } // insert_tag() function change_tag(){ let editor_iframe=document.querySelector('.cke_wysiwyg_frame'); if(editor_iframe){ let iframe_doc=editor_iframe.contentWindow.document; if(iframe_doc){ let h2_elem=iframe_doc.querySelectorAll('h2'); for(let k=0; k<h2_elem.length; k++){ h2_elem[k].onclick=function(event){ if(event.ctrlKey){ event.stopImmediatePropagation(); replace_tag(h2_elem[k]); }}} let h3_elem=iframe_doc.querySelectorAll('h3'); for(let k=0; k<h3_elem.length; k++){ h3_elem[k].onclick=function(event){ if(event.ctrlKey){ event.stopImmediatePropagation(); replace_tag(h3_elem[k]); }}} function replace_tag(element){ let alt_elem=element.outerHTML.toString(); if(witch_h(element)==2){ alt_elem=alt_elem.replace('<h2', '<h3'); } else if(witch_h(element)==3){ alt_elem=alt_elem.replace('<h3', '<h2'); } element.outerHTML=alt_elem; // h2⇄h3の書換 function witch_h(elem){ if(elem.tagName=='H2'){ return 2; } else if(elem.tagName=='H3'){ return 3; } else return 0; } } // replace_tag() }}} // change_tag()
「Rep Heading ⭐」最新版について
旧いバージョンの JavaScriptツールは、アメーバのページ構成の変更で動作しない場合があり、導入する場合は最新バージョンをお勧めします。
●「Rep Heading ⭐」の最新バージョンへのリンクは、以下のページのリンクリストから探せます。