- ベストアンサー
【javascript で動的に a タグ内に onclick属性を出力する方法】 について
javascript での 【 html 内への動的タグ生成】について、 javascript にご理解のある方にお教え頂けますと大変嬉しです。 かなり基本的なことで恐縮ですが、当方デザインサイドの人間で javascript も理屈の情報流し読みだけで、全く自ら書く練習をしていない不理解者です。 それでも急ぎで解決してゆきたい問題があり。 どなた様か、何卒宜しくお願い申し上げます。 ---------------------------------------------------------------- 作ろうとしているのは、【現在の Yahoo JAPAN! のTOPページ上部の、ページURLを切り替えずにタブをチェンジして、それに対応する下部の div の内容を切り替える】というインターフェイスです。 ただ、IE5.5 などで全くまともに動作しないので、IE5.5を含んだクロスブラウザ対応のため、【Ajax ライブラリのタブチェンジ】ではなく、巷の情報をアレンジした自前 javascript で作っています。 以下のようなタグを javascript で動的に生成する記述を書いているのですが、これが 【現在の Yahoo JAPAN! TOP】の上部クリック切替タブに相当するものです。 <ul class="menu1" id="nav"> <li id="menu1Nav"><a href="#menu1">メニュー1</a></li> <li id="menu2Nav"><a href="#menu2">メニュー2</a></li> <li id="menu3Nav"><a href="#menu3">メニュー3</a></li> <li id="menu4Nav"><a href="#menu4">メニュー4</a></li> <li id="menu5Nav"><a href="#menu5">メニュー5</a></li> </ul> 書く <li><a></a><li> は、CSS 側の記述で display:block; 化して 幅×高さ を統一するように指定しており、クリックした際は「ボタン」的な長方形の outline が【点線】で表示されます。 ------------------------------------------------------ そのタブを動的生成する関連メソッドが、 function createListItem(id,href,text) { var li = document.createElement("li"); var a = document.createElement("a"); var t = document.createTextNode(text); li.setAttribute('id',id); a.setAttribute('href',href); a.appendChild(t); li.appendChild(a); return li; } function setTabClick(listName,categoryName) { var e = document.getElementById(listName).getElementsByTagName('a')[0]; e.onclick = function(){ showCategory(categoryName); return false; }; } です。 ------------------------------------------------------ このとき【Yahoo JAPAN! TOP 切替タブ】は、クリックした際に outline の【点線】が全く表示されないのでスマートですが、 CSS 側で 当該 li a タグに outline:none; を指定していても、 IE8 や firefox などモダンブラウザではそれだけで「クリック時の周囲【点線】」が見えなくなりますが、 まだシェアの多い IE6/IE7 などでは outline プロパティに対応していないため、クリックしてタブを切り替えたときに、見苦しい【周囲枠点線】が残ってしまいます。 そこで巷の情報より、<a onfcus="this.blur()" id"~">テキスト</a> を挿入すれば、それが見えなくなるとのことで、この動的に生成する <li><a> の a タグの中に onfcus="this.blur()" を常に入れるようにして試してみたいのですが、 ★ <a href="#menu1"> などのラスト部分に、毎回同様にうまく挿入する記述方法について、教えて頂けますと大変幸いです。 上の2つのメソッドのどちらかで、その部分の追加記述ができると嬉しいのですが、a.setAttribute(); / e.onfocus = などで少し試してみるも、元々記述構造をよく理解していないため、意図する結果は得られません。 ------------------------------------------------------ 【上記の onfcus="this.blur()" を 各 a タグの最後に動的に毎回追加する記述方法】 のみで良いのですが、どなた様かお知恵をお借りできませんでしょうか。 自分で長時間試行錯誤する余裕が全くなく、もし早めにコメントを頂けますと大変幸いです。 どうぞ宜しくお願い申し上げます。
- みんなの回答 (6)
- 専門家の回答
質問者が選んだベストアンサー
>function clickHandler( evt ) {} メソッドを作って、 ><ul id="nav"> のラストに onclick="clickHandler( event );"を出すように書ければよりスマートかと思いますが、そもそも <ul id="nav">の後に都合よく onclick="clickHandler( event );" などを出す関数記述が innerHtml なのか何が良いのか良く分かりません。 リスナ登録するだけです。 //@cc_on function setTabClick( ) { var ul = document.getElementById( 'nav' ); ul./*@if(1) attachEvent( 'on' + @else@*/ addEventListener( /*@end@*/ 'click', clickHandler, false ); } もともとのソースの a に onclick を登録してる部分を、ul に変えるだけです。 上記で eventTarget.onclick を使わないのは、リークを避けるため、意図しない上書きを避けるため等々です。 # ul につけるのが無理な場合はさらに上位でもいいです。(最上位の document に付けるようにすると、load を待つ必要もなくなります。) # スクリプトをドキュメントの一番下に置くことでも、onload の必要性をなくすことができ、さらにページの読み込みの妨げも緩和されます。 > Netscape 7.1 でも、、、 Netscape は target にバグがあるので、#3 のままでは動作しないかもしれません。 function clickHandler( evt ) { var target = evt./*@if(1) srcElement @else@*/ target /*@end@*/; target.nodeType == 3 && ( target = target.parentNode ); if( target.tagName == 'A' && /#/.test( target.href ) ) { showCategory( target.href.split( '#' )[1] ); //target.blur( ); evt./*@if(1) returnValue = false; @else@*/ preventDefault( ); /*@end@*/ } } のように修正してください。 #ついでにその他もろもろも修正 function createListItem(id,href,text) { var li = document.createElement( 'LI' ); li.id = id; li.innerHTML = '<a href="'+href+'"'/*@+' hidefocus="true"'@*/+'>'+text+'</a>'; return li; } #DOMって、ツリーを切り取って部分的に扱うには便利だけど、一個一個追加するときは不便。DOCTYPE に影響するところでもないし、この場合はinnerで片付けたほうがすっきりする # ここの掲示板、スペースが消されてしまうので。全角スペースでインデントが入れてあります、コピーするときは、半角などに置換してください。
その他の回答 (5)
- yuu_x
- ベストアンサー率52% (106/202)
連投すみません。 スクリプト部分もどうせなら本元の YAHOO のものを拝借してはいかがですか? http://developer.yahoo.com/yui/index.html http://www.openspc2.org/reibun/JavaScript_technique/sample/12_GUI/005/index.html
お礼
確かにそれも考えましたが、 Yahoo は 現在ほぼ絶滅していますが Netscape 7.1 では別画面を表示させており、自前のjs なら NN7.1でも同じように動作するもので、そちらの方でとりあえず作ってみてしまいました。 時間ができれば、YUI のライブラリの方も内容を見てみたいと思います。 javascript不勉強者でも、CSS 側のコントロールのみでアレンジ設置できるようでしたら。 コメント誠にありがとうございました。
- yuu_x
- ベストアンサー率52% (106/202)
Yahoo は独自属性使ってるみたいですね。 <a href="…" hidefocus="true"><!- blur の必要なさそうですね。 --> http://msdn.microsoft.com/ja-jp/library/ms533783%28en-us,VS.85%29.aspx #3 return false; が抜けてました。
- yuu_x
- ベストアンサー率52% (106/202)
#1 おもいっきりリークパターンだから、IE を相手にするならやめたほうがいい。 onclick はバブルするので、一個一個につけて回らなくても、上位要素で、監視すれば十分です。 <ul onclick="alert((event.target||event.srcElement).id);"> <li id="menu1Nav">…</li> … </ul> focus のタイミングで blur するのではなく、click の処理が終わった後に blur でよくないですか? function clickHandler( evt ) { var target = evt.target || evt.srcElement; if( target.tagName == 'A' ) { showCategory( target.href.split( '#' )[1] || '' ); target.blur( ); } } <ul onclick="clickHandler( event );"> … </ul> その時代にはあまり詳しくありませんが、IE4.0 の時点で HTTP 通信(いわゆる ajax)が導入されてるので使えないわけじゃないと思います。 http://support.microsoft.com/kb/269238/ja
お礼
yuu_x さん、コメント誠にありがとうございます。 このメソッドは、javascript 文法も全く不理解な当方には難しいものです。 function clickHandler( evt ) {} メソッドを作って、 <ul id="nav"> のラストに onclick="clickHandler( event );"を出すように書ければよりスマートかと思いますが、そもそも <ul id="nav">の後に都合よく onclick="clickHandler( event );" などを出す関数記述が innerHtml なのか何が良いのか良く分かりません。 function createListItem() や function setTabClick() の中で、具体的にはどのように書けば良いでしょうか?(例示ではなく)。おすがりで大変恐縮です。 > onclick はバブルするので、一個一個につけて回らなくても、上位要素で、監視すれば十分 でしたら、とすれば <ul id="nav">の後に都合よく onclick="clickHandler( event );" ← この引数はただの例示かと思いますが 実際に必要な記述を動的に生成するには、どのように記述すれば良いでしょうか? onclick の繰り返しが負荷になるなら、次のご投稿で頂いたIE独自拡張の hidefocus="true" を、毎回 <a の後に出すのでもOKなのですが、それも毎回のタグ繰り返しよりは、<ul onclick="~"> の中で上位で1ヶ所監視の方がスマートなのかもしれません。 自分としては、特に記述のスマートさまで極めて求める訳ではありません。 <a の後に hidefocus="true" (href 属性との順序により、前後に半角スペースも出力しなくてはなりませんが)を挿入する記述方法でも問題ありません。 素人質問で恐縮ですが、宜しければご教授お願い致します。
- 15mm
- ベストアンサー率65% (65/100)
function setTabClick(listName,categoryName) { var e = document.getElementById(listName).getElementsByTagName('a')[0]; e.onclick = function(){ showCategory(categoryName); return false; }; e.onfocus=function(){this.blur();}//追加 } 全体の流れ(関数使用方法とか)がよく見えませんが、こういうことですかね? IE8で確認、じゃ意味無いか。。。
お礼
15mm さん、ご回答誠にありがとうございました。 e.onfocus=function(){this.blur();}// の追加で、確かに IE5/IE6/IE7 でもクリック時の点線枠が出なくなりました。 一応ご指摘の記述でも目的達成は可能ですが、より後学のため、yuu_x さんのご回答へのお礼に続けさせて頂きます。 大変ありがとうございました。
補足
それは最初に試したつもりだったのですが、どこか記述が抜けていたようです。
- yambejp
- ベストアンサー率51% (3827/7415)
とりあえずこんな感じでどうでしょう? <script> window.onload=function(){ var tags=document.getElementsByTagName("a"); for(var i=0;i<tags.length;i++){ tags[i].onfocus=function(){this.blur();} } } </script> <ul class="menu1" id="nav"> <li id="menu1Nav"><a href="#menu1">メニュー1</a></li> <li id="menu2Nav"><a href="#menu2">メニュー2</a></li> <li id="menu3Nav"><a href="#menu3">メニュー3</a></li> <li id="menu4Nav"><a href="#menu4">メニュー4</a></li> <li id="menu5Nav"><a href="#menu5">メニュー5</a></li> </ul>
補足
yambejp 様、ご回答誠にありがとうございます。 御好意にすがらせて頂けませんでしょうか。 window.onload=function(){ ~ } にはたくさんの関数・メソッドをコールしており、 できれば当該部分のタブに関連する function createListItem(id,href,text) {} function setTabClick(listName,categoryName) {} の中の方で、求める onclick属性を出力させる記述は可能でしょうか? window.onload=function(){} の方で記述を追加しても良いのですが、 その場合も or ↑ の2つのメソッドの中ででも、id="nav" の ul 内の a 要素にだけ onfcus="this.blur()" を出力したいとの希望です。 他の id 要素内の aリンクには、同効果を適用したくなく。 getElementsById の使い方応用も理解しておらず、不勉強申し訳ありません。 再度ご教授頂けますと大変幸いです。 宜しくお願い申し上げます。
お礼
yuu_x さん、大変ご丁寧なコメントを感謝申し上げます。 トライしてみて、うまくゆけばまた御礼をさせて頂きます。 もしお時間が可能でしたら、 http://oshiete1.goo.ne.jp/qa5276473.html にもコメントを頂けましたら大変嬉しく。 yuu_x さんならすぐお分かりになられるかと。 デザイン側人間で、「自分で調べろ。甘えんじゃねえ」と言われることは重々承知しております。時間の関係で、ダメ元で実力がおありの方におすがりしており。 もしお時間可能でしたら、コメントをお願い申し上げます。