下記のスクリプトを高速にする具体的な方法
現在、特定のクラスを表示、非表示にしたいと
考えております。
下記のスクリプトだとIEでの動作が遅いので改善方法を模索しております。
どなたかご教授ください。
宜しくお願いいたします。
<script type="text/javascript">
var ids = new Array();
ids = ['default','aaa','bbb'];
function change(site){
if(!document.getElementsByTagName){return;}
var objs = document.getElementsByTagName('*');
var check = ids.join('|');
var re = new RegExp('(?:^|\\s)'+site+'(?:$|\\s)');
for(var i=0; i<objs.length; i++){
var obj = objs.item(i);
if(re.test(obj.className)){
obj.style.display = '';
}else{
if(obj.className){
if(obj.className.match(check)){
obj.style.display = 'none';
}else{
obj.style.display = '';
}
}
}
}
}
</script>
<html>
<select name="site_change" id="site_change" onchange="change(this.value)">
<option value="default">デフォルト</option>
<option value="aaa">aaa</option>
<option value="bbb">bbb</option>
</select>
<div class="aaa bbb">aaa bbb</div>
<div class="aaa">aaa</div>
</html>
No.9ベストアンサー
- 回答日時:
#5, 6です。
以下、別の方のアイデアをそのまま拝借しただけですが…。
--------
<style type="text/css"><!--
body.default .aaa, body.default .bbb, body.aaa .bbb, body.bbb .aaa { display: none; }
body.aaa .aaa, body.bbb .bbb { display: block; }
--></style>
<script type="text/javascript"><!--
function changeBodyClassName (body, className) {
if (body.tagName !== 'BODY' || /^(?![a-zA-Z][0-9a-zA-Z_\-]*$)/.test(className)) { return false; }
body.className = body.className.replace (/(?:^| )(?:(?:default|aaa|bbb)(?= |$)|$)/, className);
}
//--></script>
</head>
<body onload="changeBodyClassName ((event.target ? event.target.body : document.body), 'default');">
<form><p><select name="site_change" id="site_change" onchange="changeBodyClassName (this.ownerDocument.body, this.value);"><option value="default">デフォルト</option><option value="aaa">aaa</option><option value="bbb">bbb</option></select></p></form>
<div class="aaa">aaa</div>
<div class="bbb">bbb</div>
<div class="aaa bbb">aaa bbb</div>
--------
classNameの判定は比較的よく使われる文字だけでCSS2.1やHTML4.01規定に準じていません。
あしからず。
---------------
#5, 6 で指摘したid属性値の件ですが、その後、的外れな指摘であることが分かりました。
> 細かい指摘なのですが、私の知る限りでは、HTML4.01, XHTML1.0, HTML5 の中でid属性値に半角スペース(#x020)を指定できる(X)HTMLはありません…。
ある方から「HTML5では " " を使える」「CSSでidセレクタのエスケープは \A0 (NO-BREAK-SPACE)」という指摘を受けました。
同時に「規定と実装は別の話」という指摘も受けまして、私の環境で確かめたところでは \A0 はブラウザの実装が追いついていないようでした。
#6 は全面的に撤回します。すみませんでした。m(_ _)m
No.8
- 回答日時:
#7です。
スクリプトが生成しているスタイルシートを工夫してください。
具体的な方法は実際のHTML、あなたのやりたい事が見えないので割愛しますが
どのようなスタイルシート出来ていれば希望の表示になるかわかれば、現在のスクリプトに何を追加すればよいかもわかるはずです。
No.7
- 回答日時:
処理対象が多すぎるのでその辺を絞る。
<div id="x">
<div class="aaa bbb">aaa bbb</div>
<div class="aaa">aaa</div>
</div>
var objs = document.getElementsByTagName('*');
↓
var objs = document.getElementById('x').getElementsByTagName('*');
(可能なら'*'も'div'にする)
これでobjsの数を大幅に減られせばある程度改善すると思います。
また、根本的に考え方を変えて、(他の方の回答にもあるけど)スタイルシートの方をいじるのがいいと思う。
http://wiki.bit-hive.com/tomizoo/pg/Javascript%2 …
一応以下にサンプルも書いたけど、けっこういい加減です。(部分的には元より遅い箇所すらあります。)
(特に高速化なら)ほんっとの実データを知らない第三者が書く以上は過不足や向き不向きがあるとお考えください。
<html>
<head>
<title></title>
<script type="text/javascript">
function change (S) {
var SSid = '_change_Temporary_StyleSheet';
var SS = document.getElementById(SSid);
var H = document.getElementsByTagName('head')[0];
var SOL = S.options.length;
var i;
var cssText;
var list = new Array();
var sheet;
for(i=0;i<SOL;i++) list[i] = S.options[i].value;
if(SS) H.removeChild(SS);
SS = document.createElement('style');
SS.id = SSid;
SS.type = 'text/css';
H.appendChild(SS);
sheet=document.styleSheets[document.styleSheets.length -1];
if(sheet.insertRule) {
for(i=0;i<SOL;i++) {
cssText = (list[i] != S.value)?'{display:none}':'{display:block !important}';
sheet.insertRule('.'+list[i]+cssText,0);
}
} else {
for(i=0;i<SOL;i++) {
cssText = (list[i] != S.value)?'display:none':'display:block !important';
sheet.addRule('.'+list[i],cssText);
}
}
}
</script>
</head>
<body>
<form>
<select onchange="change(this)">
<option value="default">デフォルト</option>
<option value="aaa">aaa</option>
<option value="bbb">bbb</option>
</select>
</form>
<div class="aaa bbb">aaa bbb</div>
<div class="aaa">aaa</div>
<div class="bbb">bbb</div>
<div class="ccc">ccc</div>
</body>
</html>
この回答への補足
ご回答ありがとうございます。
動き的には上記であげたスクリプトと同等の動作をし、
早さも改善されていて、非常に参考になりました。
classがtdやらtrについているときはどのように回避
するのか、教えていただけると幸いです。
宜しくお願いいたします。
No.6
- 回答日時:
#5です。
#5では「 (X)HTMLのバージョンによっては(おそらくHTML5なら)、<div id="aaabbb"> という書き方も出来る」と書きましたが、その書き方では CSS,JavaScript で期待通りに結果を得られませんでした。
先に検証しておけば良かったですね…。失礼しました。
----
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8" />
<title>HTML5</title>
<style type="text/css"><!--
#aaa\20bbb { color: red; }
--></style>
</head>
<body>
<div id="aaabbb">Hello, World!</div>
<script type="text/javascript"><!--
alert (document.getElementsByTagName('div').item(0).id); // aaa bbb
alert (document.getElementById('aaa bbb').firstChild.nodeValue); // Uncaught TypeError: Cannot read property 'firstChild' of null
//--></script>
</body>
</html>
----
document.getElementsByTagName('div').item(0).id は期待通りの結果なのですが、他が期待通りの結果ではないので「実質的には使えない」といえそうです。
No.5
- 回答日時:
始めに document.styleSheets でスタイルを設定する方式を思いつき、高速化のためとはいえ既存スタイルを無視して insertRule でスタイルを追加し続けるのはスマートでないと思い、「HTMLStyleElement.firstChild.nodeValue を変更すれば良いのではないか」と考え、コーディングしてみたが、IEでどうしても HTMLStyleElement.firstChild を取得できず、つい昨日に「IEの HTMLScriptElement, HTMLStyleElement 他いくつかは特殊実装だ」とアドバイスをもらったのを思い出して、「IEなんて、この世からいなくなれば良いんだ!」と声を大にして主張したくなったこの頃…。
----------
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8" />
<title>HTML5</title>
<style type="text/css"><!----></style>
<script type="text/javascript"><!--
function change (event, win) {
var target = event.target || event.srcElement,
doc = (target && target.ownerDocument) ? target.ownerDocument : (target || win.document),
cssText = '.aaa { display: none; }\n.bbb { display: none; }\n',
style;
if (target && target.tagName === 'SELECT') { cssText += '.' + target.value + '{ display: block; }'; }
else if (event.type !== 'load') { return false; }
style = doc.getElementsByTagName('style');
style = style.item(style.length - 1);
if (style.firstChild) { style.firstChild.nodeValue = cssText; }
}
//--></script>
</head>
<body onload="change(event, this);">
<form><p><select name="site_change" id="site_change" onchange="change(event);"><option value="default">デフォルト</option><option value="aaa">aaa</option><option value="bbb">bbb</option></select></p></form>
<div class="aaa">aaa</div>
<div class="bbb">bbb</div>
<div class="aaa bbb">aaa bbb</div>
</body>
</html>
----------
>> #4 null_pさん
細かい指摘なのですが、私の知る限りでは、HTML4.01, XHTML1.0, HTML5 の中でid属性値に半角スペース(#x020)を指定できる(X)HTMLはありません…。
# (X)HTMLのバージョンによっては(おそらくHTML5なら)、<div id="aaabbb"> という書き方も出来るのではないかと思いますが。
CSS/日本語のID・クラス名について | OKWave
http://okwave.jp/qa/q5832331.html
id 属性 - グローバル属性 - HTML5 タグリファレンス - HTML5.JP
http://www.html5.jp/tag/attributes/id.html#the-i …
No.4
- 回答日時:
こんなんでいかがでしょうか。
-----
<html>
<head>
<script type="text/javascript">
var ids = new Array();
ids = ['default','aaa','bbb'];
function change(site){
var obj;
for(var check in ids){
if((obj = document.getElementById(ids[check])) != undefined){
if(site == ids[check]){
obj.style.display = "block";
}else{
obj.style.display = "none";
}
}
}
}
</script>
</head>
<body>
<select name="site_change" id="site_change" onchange="change(this.value)">
<option value="default">デフォルト</option>
<option value="aaa">aaa</option>
<option value="bbb">bbb</option>
</select>
<div id="aaa bbb" class="aaa bbb">aaa bbb</div>
<div id="aaa" class="aaa">aaa</div>
</body>
</html>
No.3
- 回答日時:
他の記述方法(IE8/Safari4/Firefox3/Opera10)
どのブラウザーでも、どんなクエリーでも、とはいきませんが、
document.querySelectorAll('セレクター')
で、CSSセレクターで、該当する要素を取得できます。
var objs = document.querySelectorAll('.aaa,.bbb,.default');
とか
var objs = document.querySelectorAll('.aaa');
or(var i=0; i<objs.length; i++){
.....
みたいに処理できてコードは楽になりますけど、
速いかどうかは、? です。
No.2
- 回答日時:
obj.style.display = '';
もIEで遅くなる原因の一つでは...
初期値に戻すのに決めうち可能ならば、
obj.style.display ='block'とか、obj.style.display ='inline'
のように指定した方がよい。
抜本的に変えるなら、スタイルシートのルールをjavascriptで動的に
変更する手法もあります。
参考
http://bmky.net/text/note/javascript-css/
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- JavaScript 以前の質問だと、どの条件でも配列が表示されてしまいます。 1 2022/07/09 11:40
- JavaScript セレクトボックスで配列を呼び出したい。 1 2022/07/08 20:14
- JavaScript 1日1回引けるJavaScriptおみくじについて 1 2022/12/12 22:28
- JavaScript コードレビューをお願いします。 1 2022/07/16 05:38
- JavaScript clear機能を失わずにファイルアップロード機能を作成したい 3 2023/06/10 16:12
- JavaScript console.logがどうしても2つ機能しないのでアドバイスをくださいお願いします 2 2022/07/07 22:13
- JavaScript プログラムがうまく動きませんレビューお願いします 1 2022/07/10 05:08
- JavaScript jQueryでのドラッグアンドドロップについて 1 2022/07/07 21:04
- JavaScript セレクトボックスを2つ選択してメッセージなどを表示するには。~運賃検索プログラムを完成させたい~ 1 2022/07/22 11:10
- JavaScript JavascriptからSQLへ繋ぎ方が分からない 3 2022/07/07 00:27
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
removeEventListenerについて
-
MAX関数を使ってからLEFT JOIN...
-
テキストエリア内の一部の文字...
-
背景色を透明化
-
jQueryでクリックされた要素のi...
-
IFRAMEの表示/非表示を切り替え...
-
javascriptテキストBOX色を元に...
-
javascriptでオブジェクトの重...
-
【HP作成】クリックすると下...
-
createElementで作成した要素を...
-
ラジオボタンの切替で表示する...
-
読み込んだQRコードをフォーム...
-
classの中の<a>タグにidを追加
-
console.log結果をhtmlで表示し...
-
displayの状態を取得したい
-
変数内容をHTML内で表示する方法
-
iframe内のリンクが飛ばないの...
-
[急ぎ] videoタグで埋め込んだm...
-
取得した要素がインライン要素...
-
embed要素のsrc属性の値を変更...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
MAX関数を使ってからLEFT JOIN...
-
HTMLタグに複数のクラスを設定...
-
変数名をどのようにつけるのが...
-
401エラードキュメントを401.ht...
-
javascriptテキストBOX色を元に...
-
読み込んだQRコードをフォーム...
-
タブで開いてさらにタブ内をア...
-
createElementで作成した要素を...
-
removeEventListenerについて
-
表示・非表示のスクリプトで、...
-
HTMLとJavaScriptで作ったタイ...
-
HTMLとJavaScriptで作ったタイ...
-
getElementByIdの戻り値がnull...
-
指定したパスが現URLに含まれて...
-
[急ぎ] videoタグで埋め込んだm...
-
IFRAMEの表示/非表示を切り替え...
-
iframe内のリンクが飛ばないの...
-
removeAttribute()メソッドで削...
-
背景色を透明化
-
jQueryで同じid属性が複数あっ...
おすすめ情報