- はじめに
筆者は、業務関係の情報や個人の成果報告など公開のために、いくつかのWebページを作成して公開している。HTMLの記述にあたっては、単純な機能を使って、単純な構成とすることを心掛けている。それが制約となり不十分な部分がいくつか残されている。
今回、JSの比較的簡単なプログラムを作成して、Webページのユーザインターフェイスの改善やHTMLファイルの保守性の向上を行なった。これらはHTML の内容を動的に変化させることで実現しているが、CGIを使わずに、クライアント側のプログラムだけで処理している。
本稿では、作成した以下の5つの機能を紹介する。
- ページ内見出し機能。
- 最終更新日付の表示機能。
- 日本語ページと英語ページの動的切り換え。
- テーブルデータの外部ファイル化。
- テーブル見出し
- ページ内見出し機能。
- JSで作成した機能
- ページ内見出し
一つのページがある程度の長さになる場合には、内容の全体像を提示するために、先頭部分にページ内見出しを作成したり、見出しを記載したサイドバーをつけた複数コラムのページ構成にしたりすることが多い。筆者はいくつかのページでページ内見出しを作成していた。
最初にページを表示する際には全体が見えるように見出しだけを表示して、内容を見たい箇所をクリックして表示するしくみを作成した。JSでstyle属性のdisplayプロパティの値を切り換えることにより表示/非表示を操作できることを利用した。その結果、HTML作成時に本文と見出しとを別々に準備する必要がなくなり、更新作業が容易になった。
HTMLで見出しと内容部分とを以下のように記述する。内容部分はdisplayプロパティの初期値を none にして表示されないようにする。
-
見出し <input type="button" value="+" onclick="javaScript:this.value=iFold(body)">
<div id="body" style="display:none">
内容部分
</div>
「見出し」に続いて表示される + ボタンを押すと関数が呼び出されてdisplayプロパティ値をblockに変更する。すると内容部分が表示される。その際に + ボタンは – ボタンに変更される。今度は – ボタンを押すと、関数がdisplay値をnone に変更して内容部分を非表示にし、また + ボタンに戻す。
一般的に見出しと内容部分の対は複数記述される。個々の見出しに対応する内容部分の、表示/非表示の切り換えは上記の関数でできるが、ページ全体の非表示部分を表示状態にする機能も必要である。印刷する場合に非表示の部分は印刷されない。ページ内に検索をかけた場合に、表示されている部分だけが検索対象になる。そこで一括表示および一括非表示をおこなう関数を作成した。Inputタグによって生成される「全表示」ボタンあるいは「非表示」ボタンを押すと、対応する関数が呼ばれる。
-
<input type="button" value="全表示" onclick="iExpandAll();">
<input type="button" value="非表示" onclick="iFoldAll();">
関数はHTML内の全てのdivタグを捜して、displayプロパティの値を変更する。
図1は実際のページに適用した例である。見出しの1、3および6は内容が非表示になっており、2は内容を表示している状態である。
利用場面はさまざまであるが、表示/非表示の切り換え処理を備えたWebページを、最近はよく目にするようになった。一括表示/一括非表示を備えたWebページも少ないが見かける。
- 最終更新日付の表示
Webページには、最終更新日付の記載されているもの、記載されていないものが見受けられる。閲覧者の立場からすると、更新日付は情報が有用か否かを判断するための重要な手掛かりとなる。他方、ページ作成者の立場からすると、更新のたびに日付を書き換えるのはひと手間がかかり、また忘れることも多々ある。
ページ更新の際のわずらわしさなしに、ファイルの更新日付をページ内に表示できるよう、関数を作成した。
更新日付表示は、単純には document.lastModifiedプロパティで得て
- 08/29/2014 11:36:45
計算機処理ではソートすることが多く、その場合にはymdの順での表現であるとそのまま処理できるので、欧米で一般的な mm/dd/yyyy や dd/mm/yyyy の形式でなく、日本で一般的な形式にした。ISO 規格に準じたyyyy-mm-ddも検討した。ハイフン(-) は文書中に区切り文字として利用されることも多いので、視覚的に日付であることが識別しやすくする為にスラッシュ(/)を用いる方が有利であると判断した。
作成した last_Modified() 関数を呼ぶと、
- Last update : 2014/08/29
全ての HTML ファイルに、JSファイルのインクルード文および <script>last_Modified()</script> の記述の2行を追加することにより、全てのページに常に最終更新日付が表示できる。
- 日本語ページと英語ページの切り換え
KEKでは国際的な研究機関として、情報発信を日本語のみならず英語でも行なうことが要求されている。これまで日本語と英語との、2つのHTMLファイルを作っていた。2つの別々のHTMLファイルの内容を対応させながら更新するのは、負担の大きい作業だった。
1つのHTMLファイル内に日本語と英語とを交互に記述して、閲覧者のボタン操作により日本語部分だけの表示、あるいは英語部分だけの表示と切り換える機能を検討した。
日本語表示で英語非表示用のnihon.cssと、日本語非表示で英語表示用のeng.css との2つのcssファイルを用意して、HTMLファイルが参照するcss ファイルを切り替える方式で作成した。
nihon.cssファイルは
-
.En { DISPLAY: none }
.Nh { DISPLAY: inline }
-
.En { DISPLAY: inline }
.Nh { DISPLAY: none }
-
<link id="lang_style" rel="stylesheet" href="lib/nihon.css" type="text/css" />
本文には、以下のように日本語文と英語文を、それぞれ異なるclass属性値をもった div タグあるいはspanタグで括って記述する。対応する日本語文と英語文の両方でも良いし、一方だけの文でも良い。
-
<div class="Nh">日本語文章</div>
<div class="En">english text</div>
cssファイル切替え用の inputボタンを押すと、表示する言語が切り替わる。
-
<input type="button" value="English"
- onclick="document.getElementById('lang_style').href='lib/eng.css'">
<input type="button" value="日本語表示"- onclick="document.getElementById('lang_style').href='lib/nihon.css'">
css切替方式はcssファイルとの相対位置を意識して HTML ファイルと関数を記述しなければならない。そこで別の方式も検討している。divタグをgetElementsByTagName()メソッドで探して、class属性の値を判別してstyle属性の値を書き換える方式である。HTMLファイルだけに閉じた処理が期待でき、保守が容易になる。
本機能はコンテンツ作成の負担権限を目的としたものであるが、ページ閲覧者の操作に影響を与える。たとえば日本語表示から英語表示に切り替えた後に、ブラウザの戻りボタンを押すと、従来は日本語ページに戻った。本機能を使った場合には当該ページを呼び出したページに戻るという差異がある。
- テーブルデータの外部ファイル化
HTML ファイル内に表をテーブルとして記載する場合は少なくない。タグでテーブルを記載するのは煩雑である。項目の追加や削除といった更新作業は神経を使う作業である。
今回、テーブルをタグで直接に記述するのでなく、Ajax (Asynchronous JavaScript + XML) を用いて、CSV形式の表データを JS で読み込んでページ内に表示する関数を作成した。
表項目の追加や削除は CSV ファイルを編集することで行ない、HTML ファイルを変更する必要はなくなった。EXCELや Open Office などの表計算ソフトで編集できる。項目の追加時に行なっていた、行の順番付も表計算ソフトのソート機能で機械的にできるようになった。
Ajax は UTF-8 を標準としているので、UTF-8 の CSV ファイル作成を検討した。しかし、表計算ソフトは Shift JISが標準になっており、いずれのソフトでもファイル読み込み時あるいは書き出し時にひと手間を要する。作業ミスを引き起こす可能性が高いので、別の方策を検討し続けた。その間、Shift JISを読み込むためのメソッドを見つけた。
作成した関数は、ファイル読み込み、セルの切出し、テーブル表示の3つの処理からなる。
ファイル読み込み処理は、
- XMLHttpRequestオブジェクトを作成
var httpObj = new XMLHttpRequest();
- MimeType をShift JIS に変更
httpObj.overrideMimeType("text/plain; charset=Shift_JIS");
- ファイルを開く
httpObj.open("GET", filename, true);
- テキストの読み込み
file_text = httpObj.responseText;
セルの切出し処理は、読み込んだデータを改行コードとカンマ(,)により切り出して、配列に入れる。
テーブル表示処理は、配列の要素をテーブル関係のタグに埋め込んで、最後に HTML に書き込む。すなわち、JSでテーブルの枠組みを作り、その枠組みの中に読み込んだデータを埋め込む処理を行なう。枠組みとデータの分離ができて、メンテナンス時の負担を軽減できる。
データにカンマが含まれる場合の扱いは課題である。セルの切出し処理の際に、カンマを要素の区切り記号としているので、データ中では使用できない。
- XMLHttpRequestオブジェクトを作成
- テーブル見出し
テーブルは、先頭行に見出しを付けることが多い。行数の多い場合にはスクロールすると見出しが表示されなくなり、読みにくくなる。対策として、最後の行にも見出しを置いたり、中間に置いたりすることがある。
某放送局の Webページで、スクロールの際に特定のブロックがウインドウの先頭に達すると固定される表示され続けるのを見て、これをヒントにテーブルの見出しを固定させる関数を作成した。
テーブルを、1行目の見出しにあたる部分と2行目以降のデータ部分とを分離して記述した。見出し部分には、スタイルを設定した。
-
#fix-box {
- position: static;
top: 100px;
height: 50px;
width: 100%;
}ページをスクロールさせると関数が呼ばれ、見出し部分の位置を割り出して、ウインドウの先頭に達すると position プロパティ値を static から fixed に書き換えて固定させる。以下の関数例中の boxTop の値は、見出し部分の先頭からの位置であり、テーブルの前に書かれている情報量により決まる。
-
boxTop="570"
target=document.querySelector("#fix-box");
sTop = document.body.scrollTop;
if (sTop > boxTop){
- target.style.position="fixed";
target.style.top="0";
else{
- target.style.position="static";
target.style.top="auto";
テーブルの見出し部分が常にウインドウ内に表示されるようになり、見やすくなった。しかしながらテーブルの欄幅に、ズレが生ずるという問題が残っている。欄幅をCSSのwidthプロパティで指定できるが、必ずしも指定した値とならない。すべてのセルのデータの横幅長を評価して欄幅を決めていると思われる。ブラウザによっても差異がある。現時点では、あるブラウザで割り出したズレの少ないwidth 値で他のブラウザでも表示するということを、複数ブラウザの割り出し値について行なって、全体的に最もズレの少ない値を利用している。
図2はスクロールした例である。見出し部分がウインドウの先頭に固定されている。データ部分の最初が見出し部分と重なっている状態である。
最近は、ページ情報の一部を画面上に残すデザインのページを、某放送局以外でも目にするようになった。また、テーブルの見出し部分を最初から固定にして、データ部分だけをスクロールする例も見かける。どの方式が良いかは、全体のデザインに依存するであろう。方式によっては、印刷のための処理が別途必要である
- ページ内見出し
- 最後に
この間、JS やHTML5を使って、例題集を作ってきた。その中から、公開しているWebページに適用すると役立ちできそうなものを、実際に組み入れた。それが本稿で紹介した機能である。例題集は以下のページで公開している。
ブラウザにより、サポート状況が異なる部分があるが、共通する機能だけを使用し、ブラウザごとの処理は行わない方針で作成した。確認はFirefox, Opera, Google Chrome, Internet Explorer, Microsoft Edge, Safari 5.1.7 を用いて、ローカルのHTMLファイルをアクセスすることにより行なった。「年」の処理でのみ、Internet Explorerとその他のブラウザの内部表現の違いを吸収する記述をした。ローカルでのCSV形式ファイル読み込みはFirefox以外は困難なので、Webサーバのアクセスにより確認を行なった。