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

下記のスクリプトを高速にする具体的な方法

現在、特定のクラスを表示、非表示にしたいと
考えております。
下記のスクリプトだと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>

A 回答 (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
    • good
    • 0

#7です。


スクリプトが生成しているスタイルシートを工夫してください。
具体的な方法は実際のHTML、あなたのやりたい事が見えないので割愛しますが
どのようなスタイルシート出来ていれば希望の表示になるかわかれば、現在のスクリプトに何を追加すればよいかもわかるはずです。
    • good
    • 0

処理対象が多すぎるのでその辺を絞る。



<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についているときはどのように回避
するのか、教えていただけると幸いです。

宜しくお願いいたします。

補足日時:2010/06/22 17:25
    • good
    • 0

#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 は期待通りの結果なのですが、他が期待通りの結果ではないので「実質的には使えない」といえそうです。
    • good
    • 0

始めに 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 …
    • good
    • 0

こんなんでいかがでしょうか。



-----
<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>
    • good
    • 0

他の記述方法(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++){
.....
みたいに処理できてコードは楽になりますけど、
速いかどうかは、? です。
    • good
    • 0

obj.style.display = '';


もIEで遅くなる原因の一つでは...
初期値に戻すのに決めうち可能ならば、
obj.style.display ='block'とか、obj.style.display ='inline'
のように指定した方がよい。

抜本的に変えるなら、スタイルシートのルールをjavascriptで動的に
変更する手法もあります。

参考
http://bmky.net/text/note/javascript-css/
    • good
    • 0

指定したもの以外は隠したいという意図だと推測しています。


obj.className の記述が低速になる主因です。
また、document.getElementsByTagName('*'); これも範囲が広すぎます。
変更したいタグやIDを決めて、それを直接指定したほうが良いのではないでしょうか。

この回答への補足

ご回答ありがとうございます。
>obj.className の記述が低速になる主因です。
他の記述方法などあれば教えていただければと思います。

補足日時:2010/06/21 13:12
    • good
    • 0

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