時間帯によって特定位置のセルの背景色を変えるには?



0   名前: サイドミラー : 2005/06/15 18:02
tableを使って時刻表のような物を作ろうとしてるのですが、時間に応じて特定
の位置だけのセルの背景色を変化させたいのです。
例えば8:00 9:40 10:00 12:30 16:00 18:00 のような時刻表で、8時以前なら8:00
の部分のセル、8〜9時40分までなら9:40のセルといった感じの背景色を変えたいと
思うのです。
つまり次発予定の項目セルの背景色だけを変えたいのです。
可能であれば複数の時刻表に対応させたいと考えてます。
よろしくお願いします。

1   名前: Pid : 2005/06/15 18:02
-(1). td/th/tr/col 要素のどれか(色を変えたい部分)に適当な id 属性を割り振っておく(たとえば id="T0800-0940")。

-(2). load イベントに以下の処理を行う関数(イベントハンドラ)を登録する。

-(2a). 現在時刻を調べる(Date オブジェクトの getHours,getMinutes)。

-(2b). 時刻が 8:00-9:40 の間であれば T0800-0940 という文字列を返させる。

-(2c). その id を持つ要素を取得し(getElementById),背景色(style.backgroundColor)を変更する

※ (2b) の段階で if 文が続くのは見苦しいかもしれないので,あらかじめ変換テーブルを作っておくと良いかもしれません。

2   名前: サイドミラー : 2005/06/15 18:02
Pidさんありがとうございます。
なにぶんjavascriptの文法もあちらこちら見て勉強中なもので、
まだ使い方の解らないものもたくさんあります。
教えていただいたgetElementByIdやstyle.backgroundColorもどういう文法で
書いてよいのか、約束事もいま一つ理解できてません。
取りあえずテスト用に作ってみましたが、どうも使い方が間違ってるようで
エラーが出まくりです。
よろしければ添削お願いします。

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=shift_jis">
<title>test</title>

<script type="text/javascript">
<!--
function irokae() {
var now = new Date();
var hour = now.getHours();


if(hour < 7) {idx = "t01";}
else
if(hour < 8) {idx = "t02";}
else
if(hour < 9) {idx = "t03";}
else
if(hour < 10) {idx = "t04";}
else
if(hour < 12) {idx = "t05";}
else
if(hour < 15) {idx = "t06";}
else
if(hour < 18) {idx = "t07";}
else
if(hour < 21) {idx = "t08";}
else
if(hour < 23) {idx = "t09";}

idx = document.getElementById(idx);
document.idx.style.backgroundColor = "#ff99ff"
}
// -->
</script>

</head>
<body onload="irokae()">
<table>
<tr>
<td id="t01">7:00</td><td id="t02">8:00</td><td id="t03">9:00</td>
</tr>
<tr>
<td id="t04">10:00</td><td id="t05">12:00</td><td id="t06">15:00</td>
</tr>
<tr>
<td id="t07">18:00</td><td id="t08">21:00</td><td id="t09">23:00</td>
</tr>
</table>

</body>
</html>

3   名前:  U D  : 2005/06/15 18:02

おしいですね。
提示されたスクリプトにある間違いは(一応)1つだけです。

//1
idx = document.getElementById(idx);
//2
document.idx.style.backgroundColor = "#ff99ff"

1のこれなんですが、変数idxの中身に、すでにdocument.が含まれています。
2のdocument.idxはつまり、document.document.idxになってしまいます。
1を無くして2をdocument.getElementById(idx).style〜とするか、
1をそのまま2をidx.style〜とするか、どちらかでOKです。

まぁこれは基本形だと思うので、後は>>1も参考にして細部変えていけばいいかと思います。
では

4   名前: サイドミラー : 2005/06/15 18:02
ありがとうございます。
構文の使い方がいま一つ理解したなかったもので。

1を無くして
document.getElementById(idx).style.backgroundColor = "#ff99ff"
とする事でできました。

5   名前: 匿名希望 : 2005/06/15 18:02
便乗で質問です。
上記のやり方だと1つ1つのセルしかできませんよね?
これをIDではなくClassでやって複数セルに同時に対応できないものでしょうか?

6   名前: Pid : 2005/06/15 18:02
>>5
var nodes = document.getElementsByTagName('td');
var I = nodes.length;
var i;
for (i = 0; i < I; i++) if (nodes[i].className == idx) nodes[i].backgroundColor = "#ff99ff";


もしくは,table 要素オブジェクトは各セルに簡単にアクセスできるようになっています。たとえば

document.getElementsByTagName('table')[0].rows[3].cells[2].style.background = '#888';

のように書けば,(文書内の最初の table 要素の)上から 4 行目,左から 3 列目のセルの背景色が変わります。これをうまく利用すれば,id/class 属性を使う必要すら無いかもしれません。

7   名前: アラン : 2005/06/15 18:02
似たような事をやりたいのですが
>※ (2b) の段階で if 文が続くのは見苦しいかもしれないので,あらかじめ変換テーブルを作っておくと良いかもしれません。
これについて具体的は方法をお教え願えませんでしょうか?
実はとあるゲームの船の時刻表を作ろうと思っているのですが、
1)24時間にわたり、if文が24個も並ぶ
2)時間ごとに00分だったり20分、40分だったりする
3)次発の時間の部分の色のみ変えたい
現在は24個のセルにIDを付け、時間を分単位に変換し24個のif文で色変えしてます。
もっとスマートにできないかと考えてます。
宜しくお願いします。

8   名前: Pid : 2005/06/15 18:02
>>7
たとえば,

var data = {
  '08:00-09:40' : 'A', // 08:00-09:40 の間なら「A」,以下同じ
  '09:40-10:00' : 'B',
  '10:00-12:30' : 'C',
  '12:30-16:00' : 'D',
  '16:00-18:00' : 'E'
}

のように連想配列を作っておきます。そして,現在の時刻がどこに含まれるかを調べる関数を作ります。

function Scheduler() {
  // 現在時刻を取得する
  var d = new Date;
  var now = { hh : d.getHours(), mm : d.getMinutes() }

  for (var pp in data) {
    // たとえば「08:00-09:40」という文字列から数値を切り出す
    var d1 = {
      hh : eval(pp.split('-')[0].split(':')[0]), // 8
      mm : eval(pp.split('-')[0].split(':')[1]) // 0
    }
    var d2 = {
      hh : eval(pp.split('-')[1].split(':')[0]), // 9
      mm : eval(pp.split('-')[1].split(':')[1]) // 40
    }

    // 現在時刻が 8:00-9:40 の間かどうかを調べる。違ったら次のデータへ
    if ((d1.hh == now.hh && d1.mm <= now.mm)
      || (d1.hh < now.hh && now.hh < d2.hh)
      || (d2.hh == now.hh && now.mm <= d2.mm)) return data[pp];
  }

  // どのスケジュールデータとも合わなかったら false を返す
  return false;
}

あとは,メイン処理の適当な所で Scheduler() を実行すれば,現在時刻に応じた値が返ってきます。

【例】// 8:00-9:40 の間であれば「A」という id 属性値を探す
   var id = Scheduler();
   var node = document.getElementById(id);

かえって面倒でしょうか (^^;)。でも一度作ってしまえば,あとはデータを追加・変更するだけで済みますので,データ量が膨大な場合は楽かもしれません。

なお,上記は 23:00-01:00 のように日をまたぐ場合のことを考えていません。もっと良いやり方があればぜひ教えて下さい。

【追記】getTime() を使って,ミリ秒で比較すると良いかもしれません。

9   名前: Pid : 2005/06/15 18:02
おまけ。>>8 をオブジェクトとしてまとめてみました。日付をまたぐ場合にも対応。

【メソッド】
・ Scheduler.exec() 現在時刻に登録された関数を実行し,その値を返す。


var Scheduler = new function() {

  // 時刻の設定と関数の登録
  this['08:00-09:40'] = function() { /* ここに実行したい内容を書く */ }
  this['09:40-10:00'] = function() { /* ここに実行したい内容を書く */ }
  this['10:00-12:30'] = function() { /* ここに実行したい内容を書く */ }
  this['12:30-16:00'] = function() { /* ここに実行したい内容を書く */ }
  this['16:00-18:00'] = function() { /* ここに実行したい内容を書く */ }
  this['18:00-03:00'] = function() { /* ここに実行したい内容を書く */ }

  this.defaultValue  = function() { /* ここにデフォルトで実行したい内容を書く */ }

  this.exec = function() {
    var now = (new Date).getTime();

    for (var pp in this) {
      if (!pp.match(/-/) || !pp.match(/:/)) continue;

      var tmp1 = {
        hh : eval(pp.split('-')[0].split(':')[0]),
        mm : eval(pp.split('-')[0].split(':')[1])
      }

      var tmp2 = {
        hh : eval(pp.split('-')[1].split(':')[0]),
        mm : eval(pp.split('-')[1].split(':')[1])
      }

      var dat1 = function(d) {
        d.setHours(tmp1.hh, tmp1.mm);
        return d;
      } (new Date).getTime();

      var dat2 = function(d) {
        d.setDate(d.getDate() + (tmp1.hh > tmp2.hh ? 1 : 0));
        d.setHours(tmp2.hh, tmp2.mm);
        return d;
      } (new Date).getTime();

      if (dat1 < now && now < dat2) return this[pp]();
    }

    return this.defaultValue();
  }
}

一覧へ戻る