プロが教える店舗&オフィスのセキュリティ対策術

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 タグの最後に動的に毎回追加する記述方法】 のみで良いのですが、どなた様かお知恵をお借りできませんでしょうか。

自分で長時間試行錯誤する余裕が全くなく、もし早めにコメントを頂けますと大変幸いです。

どうぞ宜しくお願い申し上げます。

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で片付けたほうがすっきりする

# ここの掲示板、スペースが消されてしまうので。全角スペースでインデントが入れてあります、コピーするときは、半角などに置換してください。
    • good
    • 0
この回答へのお礼

yuu_x さん、大変ご丁寧なコメントを感謝申し上げます。

トライしてみて、うまくゆけばまた御礼をさせて頂きます。

もしお時間が可能でしたら、
http://oshiete1.goo.ne.jp/qa5276473.html
にもコメントを頂けましたら大変嬉しく。

yuu_x さんならすぐお分かりになられるかと。

デザイン側人間で、「自分で調べろ。甘えんじゃねえ」と言われることは重々承知しております。時間の関係で、ダメ元で実力がおありの方におすがりしており。

もしお時間可能でしたら、コメントをお願い申し上げます。

お礼日時:2009/09/09 22:41

連投すみません。



スクリプト部分もどうせなら本元の YAHOO のものを拝借してはいかがですか?

http://developer.yahoo.com/yui/index.html
http://www.openspc2.org/reibun/JavaScript_techni …
    • good
    • 0
この回答へのお礼

確かにそれも考えましたが、 Yahoo は 現在ほぼ絶滅していますが Netscape 7.1 では別画面を表示させており、自前のjs なら NN7.1でも同じように動作するもので、そちらの方でとりあえず作ってみてしまいました。

時間ができれば、YUI のライブラリの方も内容を見てみたいと思います。
javascript不勉強者でも、CSS 側のコントロールのみでアレンジ設置できるようでしたら。

コメント誠にありがとうございました。

お礼日時:2009/09/09 19:54

Yahoo は独自属性使ってるみたいですね。



<a href="…" hidefocus="true"><!- blur の必要なさそうですね。 -->
http://msdn.microsoft.com/ja-jp/library/ms533783 …

#3 return false; が抜けてました。
    • good
    • 0

#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
    • good
    • 0
この回答へのお礼

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 属性との順序により、前後に半角スペースも出力しなくてはなりませんが)を挿入する記述方法でも問題ありません。

素人質問で恐縮ですが、宜しければご教授お願い致します。

お礼日時:2009/09/09 19:50

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で確認、じゃ意味無いか。。。

この回答への補足

それは最初に試したつもりだったのですが、どこか記述が抜けていたようです。

補足日時:2009/09/09 19:14
    • good
    • 0
この回答へのお礼

15mm さん、ご回答誠にありがとうございました。

e.onfocus=function(){this.blur();}//
の追加で、確かに IE5/IE6/IE7 でもクリック時の点線枠が出なくなりました。

一応ご指摘の記述でも目的達成は可能ですが、より後学のため、yuu_x さんのご回答へのお礼に続けさせて頂きます。

大変ありがとうございました。

お礼日時:2009/09/09 19:07

とりあえずこんな感じでどうでしょう?



<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 の使い方応用も理解しておらず、不勉強申し訳ありません。

再度ご教授頂けますと大変幸いです。
宜しくお願い申し上げます。

補足日時:2009/09/09 17:57
    • good
    • 0

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