時間割表示スクリプト(DOM版)についての説明

 時間割表示スクリプト(DOM版)について説明します。

  1. 概要
  2. JavaScript
  3. 関数
    1. print_tt()関数
  4. クラス
    1. クラス ClassTimeTable
    2. フィールドの概要
    3. コンストラクタの概要
    4. メソッドの概要
    5. クラスの使用例
  5. 出力されるHTML
    1. print_tt()関数が出力するHTML
      1. 解説
    2. ClassTimeTable.createClasstimetable()メソッドが生成するHTML
  6. 添付のCSS
    1. CSSの内容

概要

 時間割表示スクリプト(DOM版)はJavaScriptによって作成されています。そのため、CGIの使えないサーバをご利用の場合でも使用することができます。

 時間割表示スクリプト(DOM版)には、簡単に時間割テーブルを出力することのできる関数がひとつと、時間割テーブル全般を扱うクラスがひとつ用意されています。時間割テーブルを扱うクラスには、フィールドがいくつか、それとメソッドがいくつか用意されています。

 出力されるHTMLにはスタイルに関する指定がなされていません。そのかわり、CSSを用いて見た目を制御できるよう、クラスがいくつか指定されています。

JavaScript

 時間割表示スクリプト(DOM版)は外部JavaScriptファイルとして提供されます。時間割を表示させたいページに、外部JavaScriptファイルを読み込むための行を追加します。

head要素内に追加する行
<meta http-equiv="Content-Style-Type" content="text/css">
<meta http-equiv="Content-Script-Type" content="text/javascript">
<script src="./classtt_dom.js" type="text/javascript" charset="Shift_JIS"></script>
<link rel="stylesheet" href="./classtt.css" type="text/css">

 強調されている部分で、ファイルへのパスを指定します。ファイルの位置によってはパスを書き換える必要があるかもしれません。よくわからない場合には、htmlファイルと関係ファイルを同じフォルダ(ディレクトリ)に入れておくとよいでしょう。

 なお、classtt_dom.jsがJavaScriptのファイル、classtt.cssが時間割テーブルのスタイルを指定しているCSSファイルです。

関数

 簡単に時間割を表示したい場合はprint_tt()関数を使うとよいでしょう。この関数を使うことで、7列7行の時間割テーブルを表示させることができます。

使用例
<script type="text/javascript">
print_tt();
</script>
表示例

 この関数を使用すると、使ったその箇所に7列7行の時間割テーブルが生成、表示されます。学校名はさくらの高校と表示されます。

 テーブルの列数、行数を指定することはできません

クラス

クラス ClassTimeTable

 授業時間割を表示するためのクラスです。先ほど説明したprint_tt()関数は、その内部でClassTimeTableクラスを使用しています。

 print_tt()関数で呼び出される時間割ではなく、自分の好みにそうよう表示を変更したいという場合には、ClassTimeTableクラスを使用します。

フィールドの概要

cDate
インスタンスが作成された時点の日です。
cDay
インスタンスが作成された時点の曜日です。
cHours
インスタンスが作成された時点の時間です。
classArray
授業が格納されている配列です。
cMinutes
インスタンスが作成された時点の分です。
cMonth
インスタンスが作成された時点の月です。
colNumber
列数を格納するフィールドです。
courseHour
授業時間を格納するフィールドです。6が格納されます。inClass()メソッドが使用するものであり、通常ユーザーが使用することはありません。
cSeconds
インスタンスが作成された時点の秒です。
cTime
インスタンスが作成された時点の時刻を、1970年1月1日 00:00:00(UTC) からのミリ秒で表したものです。
cYear
インスタンスが作成された時点の年です。
daysArray
曜日が格納されている配列です。
elementsId
生成されるオブジェクトのid属性値を格納するフィールドです。デフォルトではTMO_CTT_TARGETが格納されます。
rowNumber
行数を格納するフィールドです。
schoolName
学校名を格納するフィールドです。デフォルトではさくらの高校が格納されます。
tableName
時間割の名前を格納するフィールドです。

コンストラクタの概要

ClassTimeTable(colNumber, rowNumber)
ClassTimeTableを作成し、その引数であるcolNumberrowNumberをあとで使用できるように保存します。

メソッドの概要

createClasstimetable()
時間割テーブルのオブジェクトを生成します。
createDivision()
時間割テーブル等の親オブジェクトとなるdiv要素を出力します。
getClassid(tDay, tHours, tMinutes)
引数(tDay - 曜日、tHours - 時間、tMinutes - 分)に基づくclassId(授業ID)を取得します。引数を指定しない場合は、開講中のclassIdを取得します。
getClassname(classId)
引数(classId - 授業ID)に対応する授業の名前を取得します。
getCurrentclass()
開講中の授業の名前を取得します。
getElementsid()
生成されるオブジェクトに与えられるid属性値を取得します。
getNextclass()
次の授業の名前を取得します。
getTablename()
設定されている時間割テーブルの名称を取得します。プログラムが内部的に使用するメソッドであり、ユーザーが使用することはないでしょう。
inClass(cMinutes)
引数(cMinutes - 分)で指定された時間が授業中であるかを判定します。授業中ならばtrueを、授業が終了していた場合はfalseを返します。このメソッドによって得られる結果はあくまでも目安に過ぎないことにご注意ください。inClass()メソッドは授業終了の判定にcourseHourフィールドを使用します。
setColnumber(colNumber)
列数を設定します。列数のデフォルト値は7です。また設定値が常に奇数となるよう調整されます。最大列数は7であり、それ以上の値が与えられた場合は7が設定されます。
setElementsid(elementsId)
生成されるオブジェクトに与えられるid属性値を設定します。id属性のデフォルト値はTMO_CTT_TARGETです。
setRownumber(rowNumber)
行数を設定します。行数のデフォルト値は7です。また設定値が常に奇数となるよう調整されます。
setSchoolname(schoolName)
学校名を設定します。学校名のデフォルト値はさくらの高校です。
setTablename(tableName)
時間割テーブル名を設定します。時間割テーブル名のデフォルト値は学校名時間割です。

クラスの使用例

 クラスを使ってテーブルを表示する場合、どのようにすればよいかを説明します。サンプルスクリプトとして、print_tt()関数がどのようにクラスを使用しているかを見てみましょう。

print_tt()関数

 メインのルーチンであるprint_tt()関数では、時間割等の生成対象となるdiv要素がcreateDivision()メソッドによって作成されています。その他のオブジェクトの生成および追加(置き換え)はtableManager()関数、announceManager()関数でおこなわれています。tableManager()関数およびannounceManager()関数がそれぞれ再帰呼び出しされていることに留意してください。

function print_tt() {
    var ctt = new ClassTimeTable();
    ctt.createDivision();

    tableManager();
    announceManager();
}

function tableManager() {
    var ctt = new ClassTimeTable;
    
    var targetDivision = document.getElementById(ctt.getElementsid());
    var elementTable = ctt.createClasstimetable();
    var oldTable = document.getElementById('TBL_' + ctt.getElementsid());
    if (oldTable) {
        if (oldTable != elementTable) {
            targetDivision.replaceChild(elementTable, oldTable);
        }
    } else {
        targetDivision.appendChild(elementTable);
    }

    var waitTime = 0;
    var date = new Date();
    var waitTemp = 15 - ((date.getMinutes() % 15) + 1);
    waitTime += (waitTemp) * 60 * 1000;
    waitTemp = 60 - (date.getSeconds() + 1);
    waitTime += (waitTemp) * 1000;
    waitTime += 1002 - date.getMilliseconds();
    setTimeout('tableManager()', waitTime);
}

function announceManager() {
    var ctt = new ClassTimeTable;

    var nextClass = ctt.getNextclass();
    var currentClass = ctt.getCurrentclass()
    var nowDate = ctt.cYear.toString() + '年' + ctt.cMonth.toString() + '月' + ctt.cDate.toString() + '日' + ctt.daysArray[ctt.cDay] + '曜日';
    var nowTime;
    if (ctt.cHours.toString().length == 1) {
        nowTime = '0' + ctt.cHours.toString() + '時';
    } else {
        nowTime = ctt.cHours.toString() + '時';
    }
    if (ctt.cMinutes.toString().length == 1) {
        nowTime += '0' + ctt.cMinutes.toString() + '分';
    } else {
        nowTime += ctt.cMinutes.toString() + '分';
    }
    if (ctt.cSeconds.toString().length == 1) {
        nowTime += '0' + ctt.cSeconds.toString() + '秒';
    } else {
        nowTime += ctt.cSeconds.toString() + '秒';
    }

    var epTime = document.createElement('p');
    epTime.setAttribute('id', 'TAT');
    epTime.setAttribute('class', 'tmo_announce_time');
    epTime.setAttribute('className', 'tmo_announce_time');

    var epClass = document.createElement('p');
    epClass.setAttribute('id', 'TAC');
    epClass.setAttribute('class', 'tmo_announce_class');
    epClass.setAttribute('className', 'tmo_announce_class');

    var textNode;
    var elementNode;
    textNode = document.createTextNode('現在時刻は');
    epTime.appendChild(textNode);
    elementNode = document.createElement('strong');
    elementNode.setAttribute('class', 'time_announce');
    elementNode.setAttribute('className', 'time_announce');
    textNode = document.createTextNode(nowDate + ' ' + nowTime);
    elementNode.appendChild(textNode);
    epTime.appendChild(elementNode);
    textNode = document.createTextNode('。');
    epTime.appendChild(textNode);

    if (ctt.inClass()) {
        elementNode = document.createElement('strong');
        elementNode.setAttribute('class', 'class_announce');
        elementNode.setAttribute('className', 'class_announce');
        textNode = document.createTextNode(currentClass);
        elementNode.appendChild(textNode);
        epTime.appendChild(elementNode);
        textNode = document.createTextNode('が開講中。');
        epTime.appendChild(textNode);
    }

    textNode = document.createTextNode('次の授業は');
    epClass.appendChild(textNode);
    elementNode = document.createElement('strong');
    elementNode.setAttribute('class', 'class_announce');
    elementNode.setAttribute('className', 'class_announce');
    textNode = document.createTextNode(nextClass);
    elementNode.appendChild(textNode);
    epClass.appendChild(elementNode);
    textNode = document.createTextNode('です。');
    epClass.appendChild(textNode);

    var targetDivision = document.getElementById(ctt.getElementsid());
    oEpclass = document.getElementById('TAC');
    if (oEpclass) {
        targetDivision.replaceChild(epClass, oEpclass);
    } else {
        targetDivision.appendChild(epClass);
    }
    oEptime = document.getElementById('TAT');
    if (oEptime) {
        targetDivision.replaceChild(epTime, oEptime);
    } else {
        targetDivision.appendChild(epTime);
    }

    var waitTime = 1000;
    var date = new Date();
    waitTime -= date.getMilliseconds();
    setTimeout('announceManager()', waitTime);
}

 また、このサイトのトップページで使われているスクリプトも参照して見てください。

1列3行のテーブルを出力するスクリプト

 createDivision()メソッドでオブジェクト生成対象のdiv要素を作成した後に、tableWriter()関数、classWriter()関数、dateWriter()関数を実行しています。時間割はtableWriter()関数、次および開講中の授業案内はclassWriter()関数、日付および時刻はdateWriter()関数によって管理されています。それぞれの関数は、tableWriter()関数が15分ごと、classWriter()関数が3分ごと、dateWriter()関数が1秒ごとに再帰呼び出しされます。

var ctt = new ClassTimeTable();
ctt.createDivision();
tableWriter();
classWriter();
dateWriter();

function tableWriter() {
    var ctt = new ClassTimeTable(1, 3);
    ctt.setTablename('時間割');

    var targetDivision = document.getElementById(ctt.getElementsid());
    var elementTable = ctt.createClasstimetable();
    var oldTable = document.getElementById('TBL_' + ctt.getElementsid());
    if (oldTable) {
        if (oldTable != elementTable) {
            targetDivision.replaceChild(elementTable, oldTable);
        }
    } else {
        targetDivision.appendChild(elementTable);
    }

    var waitTime = 0;
    var date = new Date();
    var waitTemp = 15 - ((date.getMinutes() % 15) + 1);
    waitTime += (waitTemp) * 60 * 1000;
    waitTemp = 60 - (date.getSeconds() + 1);
    waitTime += (waitTemp) * 1000;
    waitTime += 1002 - date.getMilliseconds();
    setTimeout('tableWriter()', waitTime);
}

function classWriter() {
    var ctt = new ClassTimeTable;

    var targetDivision = document.getElementById(ctt.getElementsid());
    var classDivision = document.createElement('div');
    classDivision.setAttribute('id','CLS_' + ctt.getElementsid());
    var textNode;
    var elementNode;
    textNode = document.createTextNode('次の授業:' + ctt.getNextclass());
    elementNode = document.createElement('p');
    elementNode.setAttribute('class','tmo_nextclass');
    elementNode.setAttribute('className','tmo_nextclass');
    elementNode.appendChild(textNode);
    classDivision.appendChild(elementNode);
    if (ctt.inClass()) {
        textNode = document.createTextNode('開講中:' + ctt.getCurrentclass());
        elementNode = document.createElement('p');
        elementNode.setAttribute('class','tmo_currentclass');
        elementNode.setAttribute('className','tmo_currentclass');
        elementNode.appendChild(textNode);
        classDivision.appendChild(elementNode);
    }
	
    var oldDivision = document.getElementById('CLS_' + ctt.getElementsid());
    if (oldDivision) {
        if (oldDivision != classDivision) {
            targetDivision.replaceChild(classDivision, oldDivision);
        }
    } else {
        targetDivision.appendChild(classDivision);
    }

    var waitTime = 0;
    var date = new Date();
    var waitTemp = 3 - ((date.getMinutes() % 3) + 1);
    waitTime += (waitTemp) * 60 * 1000;
    waitTemp = 60 - (date.getSeconds() + 1);
    waitTime += (waitTemp) * 1000;
    waitTime += 1002 - date.getMilliseconds();
    setTimeout('classWriter()', waitTime);
}

function dateWriter() {
    var ctt = new ClassTimeTable();
    var currentdate = ctt.cYear.toString() + '/' + ctt.cMonth.toString() + '/' + ctt.cDate.toString() + '(' + ctt.daysArray[ctt.cDay] + ')';
    var currenttime = '';
    if (ctt.cHours.toString().length == 1) {
        currenttime = '0' + ctt.cHours.toString();
    } else {
        currenttime = ctt.cHours.toString();
    }
    if (ctt.cMinutes.toString().length ==1) {
        currenttime += ':0' + ctt.cMinutes.toString();
    } else {
        currenttime += ':' + ctt.cMinutes.toString();
    }
    if (ctt.cSeconds.toString().length ==1) {
        currenttime += ':0' + ctt.cSeconds.toString();
    } else {
        currenttime += ':' + ctt.cSeconds.toString();
    }

    var targetDivision = document.getElementById(ctt.getElementsid());
    var dateDivision = document.createElement('div');
    dateDivision.setAttribute('id','DATE_' + ctt.getElementsid());
    var textNode;
    var elementNode;
    textNode = document.createTextNode(currentdate);
    elementNode = document.createElement('p');
    elementNode.setAttribute('class','tmo_date');
    elementNode.setAttribute('className','tmo_date');
    elementNode.appendChild(textNode);
    dateDivision.appendChild(elementNode);
    textNode = document.createTextNode(currenttime);
    elementNode = document.createElement('p');
    elementNode.setAttribute('class','tmo_time');
    elementNode.setAttribute('className','tmo_time');
    elementNode.appendChild(textNode);
    dateDivision.appendChild(elementNode);
	
    var oldDivision = document.getElementById('DATE_' + ctt.getElementsid());
    if (oldDivision) {
        if (oldDivision != dateDivision) {
            targetDivision.replaceChild(dateDivision, oldDivision);
        }
    } else {
        targetDivision.appendChild(dateDivision);
    }

    var waitTime = 1000;
    var date = new Date();
    waitTime -= date.getMilliseconds();
    setTimeout('dateWriter()', waitTime);
}

出力されるHTML

 print_tt()関数およびClassTimeTableクラスによって出力されるHTMLには、スタイルに関する設定がいっさいなされていません。そのかわり、CSSを用いてスタイルの変更ができるよう、主要な要素に対してclass属性の指定がなされています。

print_tt()関数が出力するHTML

 print_tt()関数が出力するHTMLを模式的に示します。

表示
テーブル名
曜日 曜日 曜日 曜日 曜日
23:45 科目名 科目名 科目名 科目名 科目名
00:00 科目名 科目名 科目名 科目名 科目名
00:15 科目名 科目名 科目名 科目名 科目名
00:30 科目名 科目名 科目名 科目名 科目名
00:00 科目名 科目名 科目名 科目名 科目名

次の授業は科目名です。

現在時刻はyear年month月date日day曜日 hours時minutes分seconds秒科目名が開講中。

HTML
<div id="TMO_CTT_TARGET">
<table id="TBL_TMO_CTT_TARGET" class="tmo_ctt">
<caption>テーブル名</caption>
<col class="clock_time">
<col class="days">
<col class="days">
<col class="today">
<col class="days">
<col class="days">
<thead>
<tr>
<td> </td>
<th>曜日</th>
<th>曜日</th>
<th>曜日</th>
<th>曜日</th>
<th>曜日</th>
</tr>
</thead>
<tbody class="past">
<tr>
<th>23:45</th>
<td>科目名</td>
<td>科目名</td>
<td>科目名</td>
<td>科目名</td>
<td>科目名</td>
</tr>
</tbody>
<tbody class="present">
<tr>
<th>00:00</th>
<td>科目名</td>
<td>科目名</td>
<td>科目名</td>
<td>科目名</td>
<td>科目名</td>
</tr>
<tr class="nexttime">
<th>00:15</th>
<td>科目名</td>
<td>科目名</td>
<td class="next">科目名</td>
<td>科目名</td>
<td>科目名</td>
</tr>
<tr>
<th>00:30</th>
<td>科目名</td>
<td>科目名</td>
<td>科目名</td>
<td>科目名</td>
<td>科目名</td>
</tr>
</tbody>
<tbody class="future">
<tr>
<th>00:00</th>
<td>科目名</td>
<td>科目名</td>
<td>科目名</td>
<td>科目名</td>
<td>科目名</td>
</tr>
</tbody>
</table>
<p id="TAC_TMO_CTT_TARGET" class="tmo_announce_class">次の授業は<strong class="class_announce">科目名</strong>です。</p>
<p id="TAT_TMO_CTT_TARGET" class="tmo_announce_time">現在時刻は<strong class="time_announce">year年month月date日day曜日 hours時minutes分seconds秒</strong>。<strong class="class_announce">科目名</strong>が開講中。</p>
</div>

解説

div要素
時間割テーブルをはじめとする各オブジェクトを子要素に持つdiv要素です。
table要素
時間割テーブルを表現しているtable要素にはclass属性にtmo_cttが設定されています(以下、table.tmo_cttのように表示)。
col要素
列に対してはcol要素でクラスを設定しています。時間を表示する列にはcol.clock_timeが、本日の行にはcol.todayが、その他の列にはcol.daysが設定されています。
tbody要素
行はtbody要素によってグループ分けされています。本日の行はtbody.present、昨日以前の行はtbody.past、明日以降の行はtbody.futureに含まれています。
tr要素
次に開講される授業を示す行は、tr.nexttimeです。
td要素
次の授業はtd.nextと表現されます。
p要素
次の授業を案内するパラグラフはp.tmo_announce_class、日付時刻を案内するパラグラフはp.tmo_announce_timeです。
strong要素
科目名はstrong.class_announce、日付時刻はstrong.time_announceによって強調されています。

ClassTimeTable.createClasstimetable()メソッドが生成するHTML

 上述のtable要素とその子要素の説明に同様です。

添付のCSS

 print_tt()関数およびClassTimeTableクラスによって出力されるHTMLには、スタイルに関する設定がいっさいなされていませんでした。基本的な見た目はclasstt.jsと一緒に配布されているclasstt.cssによって指定されています。スタイルを変更したいという場合にはCSSを書き換えることで対処します。

CSSの内容

table.tmo_ctt {border: solid gray 2px; border-collapse: collapse; width: auto; margin: 0;}
table.tmo_ctt th {border: solid gray 1px; background: #FFFFCC; padding: 4px; width: auto;}
table.tmo_ctt td {border: solid gray 1px; padding: 4px; width: auto;}
table.tmo_ctt tbody.past {background: #EEEEEE;}
table.tmo_ctt tbody.future {background: #EEEEEE;}
table.tmo_ctt tr.nexttime {background: #FFEEFF;}
table.tmo_ctt col.today {background: #FFEEFF;}
table.tmo_ctt td.next {background: #FFCCFF;}
p.tmo_announce_class strong {color: black;}
p.tmo_announce_time strong {color: black;}

 CSSでの指定はごく基本的な範囲にとどめています。そのほとんどはtable.tmo_cttに対する指定であり、テーブルの枠および罫線、背景色等に対する設定が中心です。スタイルの設定されている要素については、上記の出力されるHTMLをご参照ください。

 ここではCSSに関する説明はしませんが、CSSを解説しているサイト等を参考に、いろいろ試してみられることをお勧めいたします。


「ときめきメモリアルONLINE」Geek's Side

公開日:2006.05.03
最終更新日:2006.05.06
webmaster@kototone.jp
Creative Commons License
こととねは、クリエイティブ・コモンズ・ライセンス(表示 - 継承 2.1 日本)の下でライセンスされています。