アプリ版:「スタンプのみでお礼する」機能のリリースについて

いつもお世話になっています。
以前こちらで質問させて頂き、途中までは解決したのですが
(ありがとうございました)、また新たに問題が発生してしまいましたので・・・どなたか助けて下さい(応用がどうしてもできないので
・・・行き詰まってしまいました><)

やりたいことはテーブルの各行の上をカーソルが通過すると
その行の色が変わる(通過しおわると元の色に戻る)という
プログラムをつくりたいのです。。
しかし問題は、一行そのまま色が変わるというのではないことです。
下にソースがありますが、カーソルが『りんご』上にあるときは
『くだもの1』『くだもの2』のセルも一緒に色を変える、また、
『みかん』でも『バナナ』でもカーソルが上を通過してるときは
『くだもの1』『くだもの2』のセルを一緒に色を変える・・・というようにしたいのです(『なす』や『豚肉』達も同じです)

今できているソースだと『みかん』『バナナ』『メロン』のどれも
『くだもの1』しか色が変更されません。
どうすれば『くだもの2』も一緒に色変更されるのでしょうか?

わかりずらい内容でしたらすみません(><)
お手数おかけしますがどうかよろしくお願い致します。
ソースは以下になります(前回教えていただいた方のソースを
そのまま使用していますm(_ _)m)
※違うプログラムの組み方でも大丈夫です。

<style>
.fruit{
background-Color:blue;
}
.vegetable{
background-Color:green;
}
.cereal{
background-Color:yellow;
}
.onmouse{
background-Color:red;
color:white;
text-decoration:blink;
font-weight:bold;
}
</style>

<script Language="JavaScript">
<!--
window.onload=function(){
var trs=document.getElementsByTagName("tr");
var thisClass="";
var classNames=new Array();
for(var i in trs){
if(trs[i].className) classNames[trs[i].className]=true;
trs[i].onmouseover=function(){
thisClass=this.className;
this.className=this.className+(this.className.indexOf(" onmouse")==-1?" onmouse":"");
document.getElementById(thisClass).className="onmouse";
}
trs[i].onmouseout=function(){
this.className=this.className.replace(" onmouse","");
document.getElementById(thisClass).className="";
}
}

for(var j in classNames){
document.getElementById(j).onmouseover=function(){
for(var i in trs){
if(this.id==trs[i].className){
trs[i].className=trs[i].className+(trs[i].className.indexOf(" onmouse")==-1?" onmouse":"");
}
}
}
document.getElementById(j).onmouseout=function(){
for(var i in trs){
if(trs[i].className)
if(trs[i].className.indexOf(" onmouse")>0){
trs[i].className=trs[i].className.replace(" onmouse","");
}
}
}
}
}
// -->
</script>

<body>
<table width="300" border="1" cellspacing="0" cellpadding="0">
<tr class="fruit">
<td rowspan="4" id="fruit">くだもの1</td>
<td rowspan="4" id="fruit">くだもの2</td>
<td>りんご</td>
<td></td>
<td></td>
</tr>
<tr class="fruit">
<td>みかん</td>
<td></td>
<td></td>
</tr>
<tr class="fruit">
<td>バナナ</td>
<td></td>
<td></td>
</tr>
<tr class="fruit">
<td>メロン</td>
<td></td>
<td></td>
</tr>
<tr class="vegetable">
<td rowspan="2" id="vegetable">野菜1</td>
<td rowspan="2" id="vegetable">野菜2</td>
<td>なす</td>
<td></td>
<td></td>
</tr>
<tr class="vegetable">
<td>とまと</td>
<td></td>
<td></td>
</tr>
<tr class="cereal">
<td rowspan="3" id="cereal">肉1</td>
<td rowspan="3" id="cereal">肉2</td>
<td>豚肉</td>
<td></td>
<td></td>
</tr>
<tr class="cereal">
<td>鶏肉</td>
<td></td>
<td></td>
</tr>
<tr class="cereal">
<td>牛肉</td>
<td></td>
<td></td>
</tr>
</table>

</body>
</html>

どうぞよろしくお願い致します。

A 回答 (6件)

#1,4,5です。



たびたび、申し訳ない。
#5の投稿で

(※このときプロパティclassnmの値は先で定義したcssのセレクタ名称と同じにすること)

とありますが、間違いです。忘れてください。
#4の投稿のときに少し触れましたが、
必要なのはclassnmの値とtdタグのname属性値が同じになっていれば
それに該当するセルが、addMouseOverEventの引数で与えたcssの定義を反映するようになります。
    • good
    • 0

#1、4です。



一個言い忘れた。

さらに定義を増やしたい場合。
つまり、現状では「くだもの」「野菜」「肉」の3つだけだが、
これにさらに四つ目の「きのこ」を増やしたくなった場合は、

1.<style>タグ内にセレクタを増やす
例).kinoko{
background-Color:gray;
}

2.JavaScriptに新たなクラスを作り、clsFoodを継承する。
例)
var clsKinoko = function(){
//clsFoodを継承
clsFood.call(this);
this.classnm = "kinoko";
};
(※このときプロパティclassnmの値は先で定義したcssのセレクタ名称と同じにすること)

3.html内に新たに行を追加。
例)


<tr>
<td rowspan="4" name="kinoko">きのこ1</td>
<td rowspan="4" name="kinoko">きのこ2</td>
<td>まつたけ</td>
<td></td>
<td></td>
</tr>
<tr>
<td>まいたけ</td>
<td></td>
<td></td>
</tr>
<tr>
<td>しいたけ(?)</td>
<td></td>
<td></td>
</tr>

4.最後のscriptタグ内にclsKinokoのインスタンスを生成し、
addMouseOverEventメソッドを呼び出す。

var kinokoObj = new clsKinoko();
kinokoObj.addMouseOverEvent("kinoko");


1~4まですべて他と同じようにすればいいだけなので、
さほど問題は無いかとおもいます。
    • good
    • 0

#1です。


ヒマだったので自分も作ってみた。
簡単なやり方だったらいくらでもやりようはあるし、
すでにいろんな人が回答しているので、
敢えてちょっと難しめに、汎用性を考慮して作ってみた。

<html>
<title>タイトルなし</title>
<style type="text/css">
.fruit{
background-Color:blue;
}
.vegetable{
background-Color:green;
}
.cereal{
background-Color:yellow;
}
.onmouse{
background-Color:red;
color:white;
text-decoration:blink;
font-weight:bold;
}
</style>
<body>
<script language=JavaScript type="text/javascript">
//すべてのスーパークラス(汎用的なメソッドを記載)
var clsSuper = function(){

//name属性値からノードリストを返すメソッド(※IEではgetElementsByNameが使えないため)
this.getElementsByNameAttr = function(strNameAttr){
var temp;
var i;
var arr = [];
if(!!document.all){
for(i=0;i<document.all.length;i++){
temp = document.all.item(i);
if(temp.name == strNameAttr){
arr.push(temp);
}
}
return arr;
}
else{
for(i=0;i<document.getElementsByTagName("*").length;i++){
temp = document.getElementsByTagName("*").item(i);
if(temp.name == strNameAttr){
arr.push(temp);
}
}
return arr;
}
};
};

//clsFruit, clsVege, clsCerealの親クラス
var clsFood = function(){

//clsSuperを継承
clsSuper.call(this);
//addMouseOverEventメソッド使用時に対象とするテーブルのname属性に必要な名前を定義
var targetTableName = "targetTable";

//追加するonmouseoverイベントハンドラの定義
var MouseOverEvent = function(){
var Nodes;
var i;
var obj = new clsSuper();
var tmpAttr = this.getAttribute("classnm");
Nodes = obj.getElementsByNameAttr(tmpAttr);
tmpAttr = this.getAttribute("onMouse");
for(i=0;i<Nodes.length;i++){
Nodes[i].className = tmpAttr;
}
};

//追加するonmouseoutイベントハンドラの定義
var MouseOutEvent = function(){
var Nodes;
var i;
var obj = new clsSuper();
var tmpAttr = this.getAttribute("classnm");
Nodes = obj.getElementsByNameAttr(tmpAttr);
tmpAttr = this.getAttribute("offMouse");
for(i=0;i<Nodes.length;i++){
Nodes[i].className = tmpAttr;
}
};

//マウスのin, out時のイベントハンドラを追加するメソッド
this.addMouseOverEvent = function(onmouseColor,noName){
if(noName !== false && noName !== true){
noName = true;
}
var tableNodes;
var TableNode;
var trNodes;
var trNode;
var trChildNodes;
var tdNode;
var i;
var j;
var k;
var spanNum;
tableNodes = document.getElementsByTagName("table");
for(i=0;i<tableNodes.length;i++){
TableNode = tableNodes.item(i);
if(TableNode.name == targetTableName){
trNodes = TableNode.getElementsByTagName("tr");
spanNum = 0;
for(j=0;j<trNodes.length;j++){
trNode = trNodes.item(j);
trChildNodes = trNode.childNodes;
for(k=0;k<trChildNodes.length;k++){
tdNode = trChildNodes.item(k);
if(tdNode.name == this.classnm){
spanNum = tdNode.getAttribute("rowspan");
}
if(spanNum > 0){
if(noName === false){
if(tdNode.name !== this.classnm && tdNode.name !== undefined){
tdNode.setAttribute("classnm", this.classnm);
tdNode.setAttribute("offMouse", tdNode.className);
tdNode.setAttribute("onMouse", onmouseColor);
tdNode.onmouseover = MouseOverEvent;
tdNode.onmouseout = MouseOutEvent;
}
}else{
if(tdNode.name !== this.classnm && tdNode.name === undefined){
tdNode.setAttribute("classnm", this.classnm);
tdNode.setAttribute("offMouse", tdNode.className);
tdNode.setAttribute("onMouse", onmouseColor);
tdNode.onmouseover = MouseOverEvent;
tdNode.onmouseout = MouseOutEvent;
}
}
}
}
spanNum--;
}
}
}
};

};

var clsFruit = function(){
//clsFoodを継承
clsFood.call(this);
this.classnm = "fruit";
};

var clsVege = function(){
//clsFoodを継承
clsFood.call(this);
this.classnm = "vegetable";
};

var clsCereal = function(){
//clsFoodを継承
clsFood.call(this);
this.classnm = "cereal";
};
</script>

<table width="300" border="1" cellspacing="0" cellpadding="0" name="targetTable">
<tr>
<td rowspan="4" name="fruit">くだもの1</td>
<td rowspan="4" name="fruit">くだもの2</td>
<td>りんご</td>
<td></td>
<td></td>
</tr>
<tr>
<td>みかん</td>
<td></td>
<td></td>
</tr>
<tr>
<td>バナナ</td>
<td></td>
<td></td>
</tr>
<tr>
<td>メロン</td>
<td></td>
<td></td>
</tr>
<tr>
<td rowspan="2" name="vegetable">野菜1</td>
<td rowspan="2" name="vegetable">野菜2</td>
<td>なす</td>
<td></td>
<td></td>
</tr>
<tr>
<td>とまと</td>
<td></td>
<td></td>
</tr>
<tr>
<td rowspan="3" name="cereal">肉1</td>
<td rowspan="3" name="cereal">肉2</td>
<td>豚肉</td>
<td></td>
<td></td>
</tr>
<tr>
<td>鶏肉</td>
<td></td>
<td></td>
</tr>
<tr>
<td>牛肉</td>
<td></td>
<td></td>
</tr>
</table>
<script language=JavaScript type="text/javascript">
var fruitObj = new clsFruit();
var vegetableObj = new clsVege();
var cerealObj = new clsCereal();
fruitObj.addMouseOverEvent("fruit");
vegetableObj.addMouseOverEvent("vegetable");
cerealObj.addMouseOverEvent("cereal");
</script>
</body>
</html>


--------------------------------------------------------------

クラス定義をコードの上側scriptタグ内に持っていき、
実際に動作するコードは最後のscriptタグに置いてある。つまり、

var fruitObj = new clsFruit();
var vegetableObj = new clsVege();
var cerealObj = new clsCereal();
fruitObj.addMouseOverEvent("fruit");
vegetableObj.addMouseOverEvent("vegetable");
cerealObj.addMouseOverEvent("cereal");

実際に動いているのはこれだけ。
addMouseOverEventメソッドの第一引数はスタイルシートのセレクタを取るので
例えば下記のようなcssを増やし、

.onmouse2{background-Color:gray;}

これをフルーツの欄に同じように適用したい場合は

fruitObj.addMouseOverEvent("onmouse2");

というように引数を変えるだけでおk。

さらに、例えば「りんご」の部分だけマウスが乗っかっても
色が変化しないようにしたい場合、下記のように色の変化をさせたくないtdタグにname属性を持たせる。(値はなんでもいい)


<td name="namdemoyoi">りんご</td>


逆に、例えば「りんご」「なす」の部分にマウスが乗っかった場合だけ
色を変化させたい場合は、
下記のように色を変化させたくないtdタグにname属性を持たせ、
addMouseOverEventメソッドの第二引数にfalseと入れる。


<td name="namdemoyoi">りんご</td>


<td name="namdemoyoi">なす</td>


fruitObj.addMouseOverEvent("fruit",false);
vegetableObj.addMouseOverEvent("vegetable",false);

(※ 第二引数は省略するとtrueとしている)

あと、極めつけは、テーブルの行を増やそうが、列を増やそうが、ちゃんと動く(はず)。

仕様として、この機能をテーブルに適用するにはtableタグのname属性に
name="targetTable"と書かれている必要があるようにした。
例)<table name="targeTable"></table>

また、変化させたいセルのname属性とcssのクラス属性に対するセレクタ名称は同じにしておく必要がある。(これは質問文に提示したコードもそうなっているようなのでそのようにした。)
具体的に何を言っているのかと「くだもの」を例にしていうと、
.fruit{background-Color:blue;}
^^^^^^←ココと
<td rowspan="4" name="fruit">くだもの1</td>
このname属性の値(例では"fruit")は同じにする必要があるってこと。

あと、質問文のコードではclass属性をトリガーにしているめ、
各行に最初から色がついているようだが、
cssで定義しておきながら、class属性をトリガーにするのは
どうかと思うので消しといた。
今回投稿したコードでも最初から色をつけておきたいのであれば、
同じようにtrタグのclass属性に"fruit"とか入れるのはかまわない。
(つまり、私の投稿したコードはclass属性をトリガーとしていない)

最後に1つだけ欠点。
クロスブラウザには気を張ってたつもりだったんだが、
いざテストしてみるとIEでしか動かなかった。
まぁ、そろそろめんどくさいしあくまで参考にってことで直さずぶっこんどいた。

javascriptでわざわざクラスの形で設計されているものは少ない(個人で作成する場合は特に)けれど、
最近流行りのAjax等のライブラリはすべて名前空間やクラス設計されているし、
個人とはいえ、作っていくうちにコードはそれなりに大きくなるから
最初からちゃんとクラス設計しておくと、後々見たときに整理されていて分かりやすいメリットがある。

「そんなの規模の大きいコードだけでやればいいじゃん」って言う人がいるけれど、
規模の小さいコードですら、きちんと設計できない人が、
いざ規模の大きいコードの設計をしようとしても絶対できない。

なんで、普段から意識してコードは整理しておくってのが私の持論。
今回はコードが見づらくなるため使用しなかったjavascriptの名前空間の作り方もぜひ一度学んでおいてもらいたいと思う。
(オブジェクトリテラルに放り込むだけなんで、大したことじゃないけど)

以上、参考にどぞ。
    • good
    • 0

こんにちは



ゴチャゴチャっとしたのはちょっと前に出来てたんですけどすっきり出来ないかな~と思ってやってたら遅くなっちゃいました

<style type="text/css"><!--
.fruit {
background-color:blue;
}
.vegetable{
background-color:green;
}
.cereal{
background-color:yellow;
}
.onmouse{
background-color:red;
color:white;
}

--></style>

<script language="javascript"><!--
window.onload=function(){
var TRs = new Array();
TRs = document.getElementsByTagName('tr');

for(var i=0;i<TRs.length;i++) {

TRs[i].onmouseover=function(){
preName = this.className;
this.className = "onmouse";
document.getElementById(""+preName+"1").className = "onmouse";
document.getElementById(""+preName+"2").className = "onmouse";
}

TRs[i].onmouseout=function(){
this.className = preName;
document.getElementById(""+preName+"1").className = preName;
document.getElementById(""+preName+"2").className = preName;
}

if(i == 0 || i == 5 || i == 8) {
TRs[i].onmouseover="";
TRs[i].onmouseout="";
}
}
}
//--></script>

<table width="300" border="1" cellspacing="0" cellpadding="0">
<tr class="fruit">
<td rowspan="5" id="fruit1">くだもの1</td>
<td rowspan="5" id="fruit2">くだもの2</td>
</tr>
<tr class="fruit">
<td>りんご</td>
<td></td>
<td></td>
</tr>
<tr class="fruit">
<td>みかん</td>
<td></td>
<td></td>
</tr>
<tr class="fruit">
<td>バナナ</td>
<td></td>
<td></td>
</tr>
<tr class="fruit">
<td>メロン</td>
<td></td>
<td></td>
</tr>
<tr class="vegetable">
<td rowspan="3" id="vegetable1">野菜1</td>
<td rowspan="3" id="vegetable2">野菜2</td>
</tr>
<tr class="vegetable">
<td>なす</td>
<td></td>
<td></td>
</tr>
<tr class="vegetable">
<td>とまと</td>
<td></td>
<td></td>
</tr>
<tr class="cereal">
<td rowspan="4" id="cereal1">肉1</td>
<td rowspan="4" id="cereal2">肉2</td>
</tr>
<tr class="cereal">
<td>豚肉</td>
<td></td>
<td></td>
</tr>
<tr class="cereal">
<td>鶏肉</td>
<td></td>
<td></td>
</tr>
<tr class="cereal">
<td>牛肉</td>
<td></td>
<td></td>
</tr>
</table>

文字数もあるので簡単に説明すると
window.onload=function(){
※画面表示したときに{ }内のアクションを動かす
var TRs = new Array();
※TRsという配列を設定
TRs = document.getElementsByTagName('tr');
※<tr>というタグを認識
for(var i=0;i<TRs.length;i++) {
※<tr>の数だけ繰り返す
TRs[i].onmouseover=function(){
オンマウスしたときのアクションの設定
preName = this.className;
※preNameにその<tr>のclassをいれる
this.className = "onmouse";
※<tr>のclassをonmouseに変更
document.getElementById(""+preName+"1").className = "onmouse";
※id=●●1"のclassをonmouseに変更(フルーツだったらid=fruit1)
document.getElementById(""+preName+"2").className = "onmouse";
※id=●●2"のclassをonmouseに変更(id=fruit2)
}

TRs[i].onmouseout=function(){
※onmouseoutしたときのアクションの設定
this.className = preName;
※<tr>のclassを元に戻す
document.getElementById(""+preName+"1").className = preName;
※id=●●1"のclassを元に戻す
document.getElementById(""+preName+"2").className = preName;
※id="●●2"のclassを元に戻す
}
if(i == 0 || i == 5 || i == 8) {
※アクションを起こさない<tr>の設定(ページ行頭から最初に出た<tr>が『0』個目となります)
=>左2つのセルはonmouseしても変らないようにしてます
TRs[i].onmouseover="";
TRs[i].onmouseout="";
}
}
}

テーブルの限定をするのであればテーブルにidをつけて
<table id="★★">
function内のTRs = document.getElementsByTagName('tr'); を
TRs = document.getElementById("★★").document.getElementsByTafName('tr');
とすればおそらくできると思う

p.s.
●●、★★は半角英数字で最初はアルファベットで開始
    • good
    • 0

こんにちは



<script language="javascript"><!--
function colorset(cl,colors) {
obj = document.getElementsByTagName("td");
cName = cl.className;
cl.style.backgroundColor = colors;
for(i=0;i<obj.length;i++) {
if(obj[i].className == cName+"1" || obj[i].className == cName+"2") {
obj[i].style.backgroundColor = colors;
}
}
}

function coloroff() {
obj = document.getElementsByTagName("td");
for(i=0;i<obj.length;i++) {
obj[i].style.backgroundColor = "white";
}
}
//--></script>

<table width="300" border="1" cellspacing="0" cellpadding="0">
<tr>
<td rowspan="4" class="fruit1">くだもの1</td>
<td rowspan="4" class="fruit2">くだもの2</td>
<td class="fruit" onMouseover="colorset(this,'red')" onMouseout="coloroff()">りんご</td>
<td></td>
<td></td>
</tr>
<tr>
<td class="fruit" onMouseover="colorset(this,'red')" onMouseout="coloroff()">みかん</td>
<td></td>
<td></td>
</tr>
<tr>
<td class="fruit" onMouseover="colorset(this,'red')" onMouseout="coloroff()">バナナ</td>
<td></td>
<td></td>
</tr>
<tr>
<td class="fruit" onMouseover="colorset(this,'red')" onMouseout="coloroff()">メロン</td>
<td></td>
<td></td>
</tr>
<tr>
<td rowspan="2" class="vegetable1">野菜1</td>
<td rowspan="2" class="vegetable2">野菜2</td>
<td class="vegetable" onMouseover="colorset(this,'green')" onMouseout="coloroff()">なす</td>
<td></td>
<td></td>
</tr>
<tr>
<td class="vegetable" onMouseover="colorset(this,'green')" onMouseout="coloroff()">とまと</td>
<td></td>
<td></td>
</tr>
<tr>
<td rowspan="3" class="cereal1">肉1</td>
<td rowspan="3" class="cereal2">肉2</td>
<td class="cereal" onMouseover="colorset(this,'blue')" onMouseout="coloroff()">豚肉</td>
<td></td>
<td></td>
</tr>
<tr>
<td class="cereal" onMouseover="colorset(this,'blue')" onMouseout="coloroff()">鶏肉</td>
<td></td>
<td></td>
</tr>
<tr>
<td class="cereal" onMouseover="colorset(this,'blue')" onMouseout="coloroff()">牛肉</td>
<td></td>
<td></td>
</tr>
</table>

くだもの1やくだもの2のclassを fruit1 に統一して
if(obj[i].className == cName+"1") {
obj[i].style.backgroundColor = colors;
でも出来るのですが選択的なものを感じるのであえて別のclass名にしました

・・・とりあえずこれで出来ているとは思うのですがスタイルシートの存在を見落としていまして無地背景になってます(--;)
あと右2つの空白セルには何が入るのでしょう?
これも一緒に変更していくという方向で考えた方がいいのでしょうか?(質問ソースはそのようになっているようですが)

p.s.
前回質問もそうですが解決の糸口が見えたのであれば質問を締め切ってください
それで一段落しているのか、まだ別の回答を待っているのか分からないです(><)
解決してないようだったらまた夜考えてみます(^^)
    • good
    • 0
この回答へのお礼

お返事ありがとうございます。
すみません、質問は自分で締め切るのは知りませんでした。。

右2つのセルもなんらかの文字が入るので、
これも一緒に変更していくという方向です。
よろしくお願い致します。
(わかりずらい説明ですみません><)

スタイルシートの存在を見落としていたとの事ですが、
色はちゃんとついてました(^^)/

お礼日時:2007/09/27 08:23

ざっとしか見てないが、html文書内に同じ値の属性idがあるのおかしくないか?


getElementByIdメソッドの返り値はNodeなわけでNodeListではないんだが‥。
そのへんが関与してる希ガス。(ごめん、眠くてちゃんと見てない)

てか、Id決め打ちできるんなら
onmouseenterとonmouseleaveイベントハンドラを持たせたらいいんじゃないか?(汎用的にしたいならイマイチだが‥)
使い方に因ればはもっと簡単に書けると思う。

同じ値の属性をもたせるなら「name」とか「sammary」とかが一般的。
DOMには「name」属性からノードリストを引っ張るgetElementsByNameがある。
(※ ただし、IEではなぜか「name」属性ではなく「id」属性がとれる)

あと、前回の経緯がわからないから、なんでこんなコードになっているのかわからない。
同じ質問したってまた同じ回答されるだけだぜ?
前回の経緯がわかるようにURL貼っておくと、回答者も前回の内容踏まえて回答できるから便利。
    • good
    • 0
この回答へのお礼

お返事ありがとうございます。

OKbokuzyoさんの言う通りですね。。すみません。
この場をお借りしてURLを貼ります・・・m(_ _)m
http://oshiete1.goo.ne.jp/qa3357832.html

私もhtml文書内に同じ値のid属性があるであれ?と
思いましたが、それに近い動きをするので
いいのかな・・・とも思ってしまいました(^^;)
そんなことを思い、色々やってみましたが、、、
わけがわからなくなってきてしまいましたので、
質問致しました。。

お礼日時:2007/09/27 01:45

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!