onclickを使わずにイベント処理をする方法について。
【<h1>をクリックすると同じ<div>を親に持つ<p>が表示/非表示】
されるようにしたいのですが、IEで動作せず、困っています。
下記は現在のコードです。
--------------------------------------------------------------------------
var divs = document.getElementsByTagName('div');
var listener = function(ev){
if(/(?:^|\s)text(?:$|\s)/.test(ev.target.className)){
var next = ev.target.nextSibling.nextSibling;
if(next.style.display != "none"){
next.style.display = "none";
}else{
next.style.removeProperty("display");
}
}
};
if (document.addEventListener) {
document.addEventListener('click', listener, false);// IE以外
} else {
document.attachEvent("onclick", listener);// IE
}
--------------------------------------------------------------------------
<div>
<h1 class="text">見出し</h1>
<p>本文</p>
</div>
<div>
<h1 class="text">見出し</h1>
<p>本文</p>
</div>
<div>
<h1 class="text">見出し</h1>
<p>本文</p>
</div>
--------------------------------------------------------------------------
ev.target.classNameあたりが怪しく…
window.event.srcElement.classNameに変更してみましたが動作しませんでした。
html側の制約があり、出来れば上記のようなclassのみのhtmlで、
更にわがままを言うと
<div class="text">
<h1>見出し</h1>
<p>本文</p>
</div>
のようにdivにclassを振った形で実現したいです。
なお、現在のコードは複数のサンプルコードを参考に試行錯誤したものですので
不要なコードが混ざっているかもしれません。
動作確認環境はIE7、IE8、Firefox、Safari(Windows)です。
納期が迫り大変困っています。アドバイスを頂けますと嬉しいです。
宜しくお願い致します。
No.11ベストアンサー
- 回答日時:
>> #9 yuu_xさん
なるほど…。スタイルシートのルールを書き換えればいいんですね!
質問者さんの動作確認環境はIE7以上だから、兄弟セレクタが使える、と。
(全角空白を半角空白に置換してください)
<script type="text/javascript"><!--
(function(){
var styleSheets = this.document.styleSheets;
var lastStyleSheet = styleSheets[styleSheets.length - 1];
try{
lastStyleSheet.insertRule('.text + p { display: none; }', lastStyleSheet.cssRules.length);
} catch(e){
lastStyleSheet.addRule('.text + p', 'display: none;', -1);
}
})();
//--></script>
stylesheet.insertRule - MDC
https://developer.mozilla.org/En/DOM/Stylesheet. …
document.styleSheets
https://developer.mozilla.org/ja/DOM/document.st …
CSSStyleSheet Prototype (style)
http://msdn.microsoft.com/en-us/library/dd347054 …
addRule Method (styleSheet, CSSStyleSheet Constructor)
http://msdn.microsoft.com/ja-jp/library/aa358796 …
Javascript cssRules - とみぞーノート
http://wiki.bit-hive.com/tomizoo/pg/Javascript%2 …
# 最後に質問者さんにアドバイス。
質問当初に知らないことがあるのは別にいいんですが、回答をもらってそこかしこにある知らないキーワードをGoogle検索してみたり、MDCの資料に目を通したり、Firebugで検証したり…、といろいろやった方が自分のためになると思います。
それから再質問すれば、質問が具体的になって回答も寄せられやすくなると思いますよ。
実際、私も調べながら回答しています。(このスレッドが立つ前から、ここに書いたことを全部知っていたわけではありません)
think49様、ありがとうございます。
仰る通りです。結果を急いでしまいました。
情報不足の中、何度も相談しお手数をおかけしました。
MDCやFirebugという言葉も知りませんでした。。!本当に勉強になります。
期日にも余裕が出たので、ひとつひとつ分からない点をじっくり勉強したいと思います。
今回はこれにて締め切らせていただきます。
有難うございました!
No.9
- 回答日時:
... click が抜けとる。
いぁ、しょーもないことで、連投して申し訳ない。[javascript]
/*@cc_on@*/
document./*@if(1)attachEvent('on'+@else@*/addEventListener(/*@end@*/'click', function(ev) {
var t = ev./*@if(1)srcElement@else@*/target/*@end@*/;
if (t.tagName === 'H1' && /(?:^|\s)text(?:\s|$)/.test(t.parentNode.className)) {
while ((t = t.nextSibling) && t.tagName !== 'P');
t && (t.style.display = t.style.display === 'block' ? 'none' : 'block');
}
}, false);
document.write('\u003Cstyle type="text/css"\u003E.text p{display:none;}\u003C/style\u003E');
[/javascript]
> 初期に本文を非表示にしたいのでしたら、JavaScriptで display:none; にするのが賢いと思います。
ん~、、、これね、、、該当要素をぐるぐる回すのも嫌だから、分かりきってる場合は、上でいいよ。
特定クラスに限定するなら、スタイルシートを書き換えるのが筋だけど、結局ぐるぐる回さなきゃならない。しかも判定が面倒。StyleSheet API にも、querySelector がほしい。
いえいえ、丁寧に有難うございます。
私の方こそ質問を続けてばかりで申し訳ないです。
document.writeでcssを書く方法もありましたね・・!
bodyタグはいじれないし、onloadをどう書くか…でまたはまってしまっていました;;
No.8
- 回答日時:
#4,5,7です。
以下、#5の補足より引用。
> 外部cssでdisplay:noneにしてしまうとjavaScriptで上書き出来ないようです。
> yuu_x様の外部css参照を使えば、実現出来るのでしょうか。
#3でyuu_xさんが紹介された getComputedStyle(currentStyle) は #5 のコードでも使われています。
しかし、そんなこととは関係なく、JavaScriptでしか使われない display:none; を外部CSSで指定するのは好ましくないと思います。
以下、いわゆる「アコーディオンメニュー」を実装する場合で「初期に内容を表示したくない」という前提で書きますが。
下記コードを試してみてください。(全角空白を半角空白に置換してください)
-------
<style type="text/css"><!--
p {
display: none;
}
--></style>
<script type="text/javascript"><!--
function test(event){
var target = event.target || event.srcElement;
var p = target.parentNode.getElementsByTagName('p').item(0);
p.style.display = (p.style.display === 'none') ? 'block': 'none';
}
//--></script>
</head>
<body>
<div>
<h1 class="text" onclick="test(event);">見出し</h1>
<p>本文</p>
</div>
-------
これはアコーディオンメニューのサンプルとして、よく見られるコードです。
期待通りに動作してくれているように見えますが、スタイルシート、JavaScriptの両方が有効でないと動きません。
CSSが有効でJavaScriptが無効なブラウザで閲覧したとすると、アコーディオンは正しく働かず、「JavaScriptを有効にしない限りは本文を表示できない」という事態になります。
ですので、初期に本文を非表示にしたいのでしたら、JavaScriptで display:none; にするのが賢いと思います。
-------
<script type="text/javascript"><!--
function test(event){
var target = event.target || event.srcElement;
var p = target.parentNode.getElementsByTagName('p').item(0);
p.style.display = (p.style.display === 'none') ? 'block': 'none';
}
function init(event){
var doc = event.target || document;
var text = doc.querySelectorAll('.text'); // for Gecko/Webkit/Opera/IE8 (IE7以下は動作しません)
var p;
for(var i=0,l=text.length; i<l; i++){
p = text[i].parentNode.getElementsByTagName('p').item(0);
p.style.display = 'none';
}
}
//--></script>
</head>
<body onload="init(event);">
<div>
<h1 class="text" onclick="test(event);">見出し</h1>
<p>本文</p>
</div>
-------
JavaScriptが無効であれば、アコーディオンが働かず、全ての内容が表示されます。
JavaScriptが有効であれば、アコーディオンが働き、初期の本文は非表示になります。
think49様更なるご回答ありがとうございます。
>#3でyuu_xさんが紹介された getComputedStyle(currentStyle) は #5 のコードでも使われています。
なるほど!チェック不足でした。
>JavaScriptでしか使われない display:none; を外部CSSで指定するのは好ましくないと思います。
>「JavaScriptを有効にしない限りは本文を表示できない」
はい、特に後者はユーザを限定してしまう点で今回の制作条件からアウトになってしまいます。
h1にonclickをつけずに実装するには、
以前のご回答と今回のご回答を両方参考にすれば実現可能でしょうか?
No.7
- 回答日時:
#4,5 です。
「cssTextをreplaceする」って手もありますね。
これなら全てのスタイルを削除しなくてすみますし、実装依存なコードではないので、最悪catchで拾えます。
<script type="text/javascript">
<!--
document./*@cc_on @if(@_jscript_version <= 5.8) attachEvent('on' + @else @*/addEventListener(/*@end @*/ 'click', function(event){
var h1 = event.target || event.srcElement;
var p, style;
if(h1.nodeName !=='H1' || (' '+h1.className+' ').indexOf(' text ') === -1){ return false; }
p = h1.parentNode.getElementsByTagName('p').item(0);
if(p.style.display !== 'none'){
p.style.display = 'none';
} else {
try{ // for Gecko/Webkit/Opera
p.style.removeProperty('display');
} catch(e) { // for IE
p.style.cssText = p.style.cssText.replace(/(^|[ ;])display *: *none(?: *;|$)/i, '$1');
}
}
}, false);
//-->
</script>
>> #6 yuu_xさん
> IE の場合、属性名 ではなく、プロパティ名を使ってるから、きっとそのせいだろうね。
多分、そうですね…。
自分から書いておいて何ですが、element.style.removeAttribute() はやっぱりお勧めしがたいコードに思えてきました。
問題はIEがWeb標準に準拠し始めているってことだと思います。
例えば、IE9から addEventListener() に対応しますが、同じ流れで「removeAttribute() の対象がプロパティ」というバグ(仕様?)も修正されるかもしれません。
すると、こういう可能性もありえます。
// IE9がやってくる
try{
child.style.removeProperty('display'); // IE9は removeProperty() に対応しないので、catchへ
} catch(e) {
child.style.removeAttribute('display'); // removeAttribute() の対象が属性ではないので、シンタックスエラー!
}
IE9が中途半端な実装をしなければ起こりえないことではありますが…。
IE9まで考えないといけないなんて…
cssだけでなくJavaScriptも…!
生半可な知識でJavaScript書けないですね。後々怖いです。
No.6
- 回答日時:
なんてこった。
まだあった。[javascript]
while (t && t.nodeType !== 1) t = t.nextSibling;
t && (t.style.display = t.style.display === 'block' ? 'none' : 'block');
}
[/javascript]
↓
[javascript]
while ((t = nextSibling) && t.nodeType !== 1);
t && (t.style.display = t.style.display === 'block' ? 'none' : 'block');
}
[/javascript]
> なぜか element.style.removeAttribute('display') が有効なIEの仕様
IE の場合、属性名 ではなく、プロパティ名を使ってるから、きっとそのせいだろうね。
IE の場合、無理に標準化するより、まったく別に書いたほうが、と思っている今日この頃。
2度同じものを書かなきゃいけないのは手間だけど、欠点はそれくらいで、利点のが大きい気がする。
No.5
- 回答日時:
#4です。
#4では(いわゆる)クロージャを取り上げましたが、クロージャに各々の要素のデフォルトスタイルを保持するのは難しそうなので、className に保持してみました。
以下、全角空白は半角空白にしてください。
<script type="text/javascript">
<!--
/*@cc_on @if(@_jscript_version <= 5.8) attachEvent('on' + @else @*/addEventListener(/*@end @*/ 'load', function(event){
var doc = event.target || document;
var text = doc.querySelectorAll('.text') || doc.getElementsByClassName('.text');// IE6を踏まえるなら、この部分は getElemensByTagName() で得るなど適宜修正してください。
var p, defaultDisplay;
for(var i=0,l=text.length; i<l; i++){
p = text[i].parentNode.getElementsByTagName('p').item(0);
defaultDisplay = doc.defaultView ? doc.defaultView.getComputedStyle(p, '').display : p.currentStyle.display;
p.className += ' defaultDisplay_'+defaultDisplay;
}
}, false);
document./*@cc_on @if(@_jscript_version <= 5.8) attachEvent('on' + @else @*/addEventListener(/*@end @*/ 'click', function(event){
var h1 = event.target || event.srcElement;
var p, className;
if(h1.nodeName !=='H1' || (' '+h1.className+' ').indexOf(' text ') === -1){ return false; }
p = h1.parentNode.getElementsByTagName('p').item(0);
if(className = (' '+p.className+' ').match(/ defaultDisplay_(\w+) /)){
if(p.style.display !== 'none'){
p.style.display = 'none';
} else {
p.style.display = className[1];
}
}
}, false);
//-->
</script>
丁寧に有難うございます。組み込んでみたところ、IEで表示/非表示することができました。
感動です!!
記入し忘れていましたが、<p>の内容は初期非表示にしたく、現在試行錯誤中です。
外部cssでdisplay:noneにしてしまうとjavaScriptで上書き出来ないようです。
yuu_x様の外部css参照を使えば、実現出来るのでしょうか。
あと1歩頑張ります。。。
厚かましいですがもしアドバイス頂けましたら嬉しいです。
No.4
- 回答日時:
removeProperty() の代替策としては、
・element.style.cssText=''; や element.removeProperty('display'); で上書きする
・clickを定義する前に、getComputedStyle(IEはcurrentStyle)でデフォルトのスタイルを読み込み、クロージャが保持する変数等に保持しておく
・なぜか element.style.removeAttribute('display') が有効なIEの仕様を利用する (実装依存)
以下、全角空白は半角空白にしてください。
<script type="text/javascript">
<!--
document./*@cc_on @if(@_jscript_version <= 5.8) attachEvent('on' + @else @*/addEventListener(/*@end @*/ 'click', function(event){
var h1 = event.target || event.srcElement;
var doc, child, childs;
if(h1.nodeName !=='H1' || (' '+h1.className+' ').indexOf(' text ') === -1){ return false; }
doc = h1.ownerDocument;
childs = h1.parentNode.childNodes;
for(var i=0,l=childs.length; i<l; i++){
child = childs[i];
if(child.nodeName === 'P'){
if(child.style.display !== 'none'){
child.style.display = 'none';
} else {
try{ // for Gecko/Webkit/Opera
child.style.removeProperty('display');
} catch(e) { // for IE
child.removeAttribute('style'); // ただし、styleが保持する全てのプロパティを全てを削除する
// child.style.cssText = ''; // 同上
// child.style.removeAttribute('display'); // IEの仕様を利用した実装依存
}
}
}
}
}, false);
//-->
</script>
cssRule.cssText - MDC
https://developer.mozilla.org/en/DOM/cssRule.css …
getComputedStyle - MDC
https://developer.mozilla.org/ja/DOM/window.getC …
currentStyle
http://msdn.microsoft.com/ja-jp/library/ms535231 …
掲示板/スタイルシート質問板/テキストボックスのスタイル初期化 - TAG index Webサイト
http://www.tagindex.com/cgi-lib/q3bbs/patio.cgi? …
回答ありがとうございます。
大変参考になります!
クロージャという言葉、初めて聞きました。
JavaScript、奥が深いです。
No.3
- 回答日時:
抜けがあった。
[javascript]
/*@cc_on@*/
document./*@if(1)attachEvent('on'+@else@*/addEventListener, function(ev) {
var t = ev./*@if(1)srcElement@else@*/target/*@end@*/;
if (t.tagName === 'H1' && t.parentNode.tagName === 'DIV' && /(?:^|\s)text(?:$|\s)/.test(t.parentNode.className)) {
while (t && t.nodeType !== 1) t = t.nextSibling;
t && (t.style.display = t.style.display === 'block' ? 'none' : 'block');
}
}, false);
[/javascript]
> onclickを使わずに
[CSS]
.text > h1 + p {
display : none;
}
.text:hover > h1 + p {
display : block;
}
[/CSS]
結局 IE では、使えないけどね。
ついで。
[javascript]
next.style.display === 'block' ? (next.style.display = 'none') : (next.style.display/*@if(1) = ''@else@*/.removeProperty('display')/*@end@*/;
[/javascript]
# removeProperty をちゃんと使ってるコードを久しぶりに見た気がする。
ちなみに、style プロパティはインラインスタイルを参照するので、外部 CSS の設定を取得する場合は、getComputedStyle(currentStyle)
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- HTML・CSS テキストを画面の真ん中に配置したいです。 2 2022/11/25 16:11
- JavaScript 入力フォームの javascript で メールアドレスの正規チェックをを行い、ボタンをクリックして 2 2022/04/27 16:06
- JavaScript clear機能を失わずにファイルアップロード機能を作成したい 3 2023/06/10 16:12
- JavaScript jqueryを使ったスムーススクロールのコードを書いたのですが、HTMLコード内にある、a butt 2 2022/04/14 10:59
- HTML・CSS ヘッダーの画像にメインエリアがかぶってしまいます 1 2022/11/28 14:06
- JavaScript jQueryでのドラッグアンドドロップについて 1 2022/07/07 21:04
- JavaScript vertical sliderをautoplayしたい 2 2022/08/25 14:47
- HTML・CSS 書籍を見つつサイト造りの練習をしているのですが、見た目が一致しません 2 2022/11/28 15:00
- HTML・CSS ボタンをクリックした時に、入力フォームのすぐ下部に、「入力欄が空白です」というテキストメッセージが表 1 2022/04/27 16:25
- JavaScript jQueryでのドラッグアンドドロップについて 1 2022/07/30 09:10
このQ&Aを見た人はこんなQ&Aも見ています
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
bt_melter.jsをサイトの一部の...
-
JavaScriptとcookieを利用して...
-
javascriptで、表示されている...
-
配列の大括弧と丸括弧はどう違う?
-
HTML:Tableタグに対し、JavaScr...
-
innerHTML実行後のイベント
-
【Tabキー】特定の範囲内だけで...
-
JavaScriptでオブジェクトを取...
-
「nullまたはオブジェクトでは...
-
<a>タグのテキストを取得
-
任意の座標をクリックさせるには
-
javascript の 命令文の記述で...
-
javascriptでCSVを呼出しvlookup
-
ActiveXobjectが作成できない
-
javascriptであるボタンを押す...
-
JavaScriptのメモ帳アプリ編集...
-
同じIDで定義した要素の配列を...
-
C#テキストボックスの文字を配...
-
google apps scriptの終了のさせ方
-
C#OpenCv V4にのエラーに関する...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
<a>タグのテキストを取得
-
ActiveXobjectが作成できない
-
onchangeイベントを使ってspan...
-
HTML:Tableタグに対し、JavaScr...
-
任意の座標をクリックさせるには
-
モーダルダイアログウィンドウ...
-
Click回数を数え、規定された回...
-
innerHTML実行後のイベント
-
javascript 特定のタグのidの存...
-
[初心者]javascriptのfor文でな...
-
【Tabキー】特定の範囲内だけで...
-
javascriptでスロットゲームを...
-
JavaScriptとcookieを利用して...
-
画像の一部を表示
-
日本語入力の禁止
-
javascriptで、表示されている...
-
javascriptで編集可能不可能の...
-
DIV内のDIV要素を移動する。
-
javascript の 命令文の記述で...
-
重複しないくじの作り方がわか...
おすすめ情報