このコードを処理速度向上させることはできますか?
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dt …
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ja" lang="ja">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script type="text/javascript">
//<![CDATA[
function className(str){
var alltag = document.getElementsByTagName("*");
var ary = [];
for(var i=0;i<alltag.length;i++){
if("."+alltag[i].className == str){
ary.push(alltag[i]);
}
}
return ary;
}
window.$ = function(str){
var ID = str.match(/^#(\w+)/),
CLASS = str.match(/^\.(\w+)/),
TAG = str.match(/^(\w+)|(\*)/),
node =
str.match(/^doc/)?
document:
TAG?
document.getElementsByTagName(RegExp.$1==""?RegExp.$2:RegExp.$1):
ID?
document.getElementById(RegExp.$1):
CLASS?
navigator.appVersion.toLowerCase().indexOf("msie")?
className(str):
document.getElementsByClassName(RegExp.$1):
null;
this.style = function(css){
css = css.split(/\:|\;/);
if(ID){
for(var j=0;j<css.length;j++) node.style[css[j].replace(/\s+/g,"").replace(/\-(\w)/,function($1){$1=$1.substr(1);return $1.toUpperCase()})] = css[j+1];
}else{
for(var i=0;i<node.length;i++){
for(var j=0;j<css.length;j++) node[i].style[css[j].replace(/\s+/g,"").replace(/\-(\w)/,function($1){$1=$1.substr(1);return $1.toUpperCase()})] = css[j+1];
}
}
}
return this;
}
window.onload = function(){
var st = new Date().getTime();
for(var i=0;i<10000;i++){
$('#wrap').style("color:#00f; background:#f00; border-left:10px solid #000;");
$('div').style("border-right:10px solid #000; width:100px; height:100px; margin:10px;");
$('.cl').style("border-top:10px solid #000; background:#00f;");
}
var end = new Date().getTime();
alert(end-st);
}
//]]>
</script>
<title></title>
</head>
<body>
<div id="wrap">aaaaa</div>
<div class="cl">bbb</div>
<div class="cl">ccc</div>
</body>
</html>
他にも、もっとこうしたほうが…等ありましたら教えてください。どうか宜しくお願いします。
A 回答 (12件中1~10件)
- 最新から表示
- 回答順に表示
No.11
- 回答日時:
ブラウザの再描画を減らそう、ということで、<style>の中を弄って一括で。
望む動作と違うかもしれませんし、
ブラウザごとの仕様の違いへの対応とかがまだ途中ですが、参考までにどうぞ。
(ところでちゃんと速くなってるのか? 短くはなってるけど)
babu_babooさんのstockのアイデア頂きました。
var $=(function(){
var c = document.styleSheets[0], stock = {};
return function(s){
this.style = function( css ){var _
if(_ = stock[s]){_.style.cssText += ";" + css;return}
var r = c.cssRules || c.rules,
i = r.length,
S = s.toUpperCase()
while(i--)if(s==r[i].selectorText || S==r[i].selectorText){
(stock[s] = r[i]).style.cssText += ";" + css; return}
c.insertRule?
c.insertRule(s + "{" + css + "}", c.cssRules.length ):
c.cssText += s + "{" + css + "}"
};
return this
}
})();
読みづらいコードで申し訳ない・・・。整形なんて久しくしてないもので・・・
「insertRuleの引数が面倒。なんでIEはcssTextの要素名が大文字なんだ?」
ってとこの片付けがまだです。
・このコードを埋め込む<script>タグよりも前に、<style>が少なくとも1つ必要です。
ダミーでいいので<style type="text/css"></style>だけでOK
・$().style()以外の用途が無いこと前提です。ごめんなさい。
・「-cssText は解析範囲が多いので遅い。」が気になるところですが、よくわからなかったので無視。
・エスケープや$とかの指摘は、「処理速度向上」という目的外なので、質問者にお任せ。(逃げただけ?)
No.10
- 回答日時:
#3,4,9です。
#9でUnicodeエスケープに関するURLを貼り切れなかったので補足を。
今更気が付きましたが、バックスラッシュでもエスケープできるようですね。(Unicodeの方が網羅できる文字種は多いですが)
http://www.swlab.it.okayama-u.ac.jp/man/rec-css2 …
http://hp.vector.co.jp/authors/VA022006/css/synt …
No.9
- 回答日時:
一つサンプルコードを書いてみたんですが、長すぎて書ききれなかったのでアドバイスに留めます。
実は私自身が気が付かなかったようなことも他で指摘されまして、その件も含めると大変長くなるので箇条書きにさせていただきます。
-------
- CSSにタグの機構は存在しないので、TAGという名前は望ましくない。適切な名前候補はtype_selector, element_name (CSS2.1仕様の文法規則より)など。
CSS2.1 (W3C)
http://www.w3.org/TR/CSS21/syndata#tokenization
http://www.w3.org/TR/CSS21/grammar.html
CSS2 (Japanese)
http://www.swlab.it.okayama-u.ac.jp/man/rec-css2 …
http://www.swlab.it.okayama-u.ac.jp/man/rec-css2 …
- CLASSという名前も好ましくない。(小文字の) class は「ECMA-262 3rd Edition」で将来の予約語として定義されており、IE8でエラーが発生する。JavaScriptは大文字小文字を区別するため、CLASSは大丈夫なようだが避けた方が無難と思われる。
7 字句について (Lexical Convention)
http://www2u.biglobe.ne.jp/~oz-07ams/prog/ecma26 …
- IE7-では、Array#push は a[a.length] = elm; より数倍遅い。
Script雑感: javascript:遅い push も使い方次第?
http://zombiebook.seesaa.net/article/146326121.h …
- IE7- には getElementsByTagName('*') でコメントノードも拾うバグがある。nodeTypeをチェックしよう。
- function className(str) の名前は望ましくない。
- function className(str) で引き渡せる値はUnicodeエスケープするか正当性検査を行った方がよい。
- cssText は解析範囲が多いので遅い。
- cssText に渡す値はUnicodeエスケープするか、正当性検査すべき。
- もし、querySelectorAll() を使うのならば、関数名を getElementsByClassName() にすべきではない。ネイティブな getElementsByClassName() は生きた(live)ノードリストを返すので名前と機能が一致しない。
- $ の変数名は好ましくない。「ドル記号は機械的に生成されるコード中のみの使用を意図される。(ECMA-262 3rd Editionより)」
7 字句について (Lexical Convention)
http://www2u.biglobe.ne.jp/~oz-07ams/prog/ecma26 …
-------
ものすごい長いですが、まあじっくりと取り組んでみてください。
特にIE7-のバグ関係は対応した方がよいと思います。
Array#push は条件付きコンパイルを利用して、IE7- だけ a[a.length] = elm; な処理に書き換える、という方法が思いつきましたが、そこまでしなくても必要なところで分岐させるだけでいいかも。
cssText の問題は先に挙げたように多岐にわたるので、いっそのことライブラリに渡す方法を変えた方がスマートかもしれません。
例えば、
foo('.test').style({color:'red', backgroundColor: '#fee', border: 'solid 1px #ccc'});
とか。このやり方なら、element.style.property に代入するのも容易でしょう。
for~inを使う場合は、prototypeを拾わないように注意してください。
hasOwnProperty - MDC
https://developer.mozilla.org/ja/Core_JavaScript …
No.7
- 回答日時:
再々投稿!ごめんなさい。
指摘うけて訂正します。「無駄に回答が多い」から、「無駄な回答が多い」になってしまった。
window.onload のあとに、
var className = (function ( mode ) {
var alltag = document.getElementsByTagName( '*' );
var stock = [ ];
return function ( css ) {
if( 2 == mode ) {
var tmp = stock[ css ];
if( tmp ) return tmp;
}
var cnt = 0;
var tag;
var result = [ ];
while( tag = alltag[ cnt++ ] )
if( tag.className == css )
result[ result.length ] = tag;
if( result.length ) {
if( 2 == mode )
stock[ css ] = result;
return result;
}
return null;
};
})(2);
No.6
- 回答日時:
れんとう!おばかぶりはっき!さいそくじゃねぇ?
var className = (function ( mode ) {
var alltag = document.getElementsByTagName( '*' );
var stock = [ ];
if( mode ) {
var i = 0, t, result = [ ];
while( t = alltag[ i++ ] )
result[ result.length ] = t;
alltag = result;
result = null;
}
return function ( css ) {
if( 2 == mode ) {
var tmp = stock[ css ];
if( tmp ) return tmp;
}
var cnt = 0;
var tag;
var result = [ ];
while( tag = alltag[ cnt++ ] )
if( tag.className == css )
result[ result.length ] = tag;
if( result.length ) {
if( 2 == mode )
stock[ css ] = result;
return result;
}
return null;
};
})(2);
No.5
- 回答日時:
さいしょにことわっておきます。
$() はすすめませんよ!でも、おあそびとして、こんなのをかいてみた!
className() です! でも、そくどてきには、びりょうか?
ぜんかくくうはくは、はんかくにしてちょ!
var className = (function ( mode ) {
var alltag = document.getElementsByTagName( '*' );
if( mode ) {
var i = 0, t, result = [ ];
while( t = alltag[ i++ ] )
result[ result.length ] = t;
alltag = result;
result = null;
}
return function ( css ) {
var cnt = 0;
var tag;
var result = [ ];
while( tag = alltag[ cnt++ ] )
if( tag.className == css )
result[ result.length ] = tag;
return result.length ? result: null;
};
})(true);
No.4
- 回答日時:
#3です。
#3の一例としてあげたコードですが、try~catch でも良かったですね。
(全角空白は半角空白に置換してください)
---------
function getElementsByClassName(elm, className){
var result;
try {
return elm.querySelectorAll('.'+className);
} catch(e) {
elm = elm.getElementsByTagName('*');
// 処理
return result;
}
}
---------
構造化プログラミング(一つの入口と一つの出口)的に書くなら、以下のような形でしょうか。
---------
function getElementsByClassName(elm, className){// 一つの入り口
var result;
try {
result = elm.querySelectorAll('.'+className);
} catch(e) {
result = [];
elm = elm.getElementsByTagName('*');
// 処理
}
return result;// 一つの出口
}
---------
> 「RegExpはグローバグオブジェクトなので使用すべきではない」と私は教わりました。
これは「グローバルオブジェクト」に訂正します。
No.3
- 回答日時:
処理速度…。
確かに、興味ある分野ではあります。> function className(str){
ネイティブ関数がある場合は、ネイティブ関数を利用した方が高速になります。
IE6等のバージョンの低いブラウザを考慮するなら、関数オブジェクトが定義済みかどうか調べて処理を分けてみてください。
以下は一例です。(全角空白を半角空白に置換してください)
-------
var doc = this.document,
result, elm;
if('undefined' !== typeof doc.querySelectorAll){
result = doc.querySelectorAll('.foo');
} else {
elm = doc.getElementsByTagName('*');
}
-------
document.getElementsByClassName - MDC
https://developer.mozilla.org/ja/DOM/document.ge …
document.querySelectorAll - MDC
https://developer.mozilla.org/en/DOM/Document.qu …
document.evaluate - MDC
https://developer.mozilla.org/en/DOM/document.ev …
生きている(live)ノードが欲しいなら、getElementsByClassName() を使い、
生きていない(non-live)ノードで欲しければ、querySelectorAll(), evaluate() を使います。
一般には、生きていないノードの方が高速です。
querySelectorAll() は IE8 から対応しますが、getElementsByClassName() はIE8でも対応しないので注意してください。
evaluate() については、amachangさんが作成されたライブラリがあるのでクロスブラウザは簡単ですが、勉強のためなら使わない方が無難だと思います。
W3C DOM Compatibility - Core
http://www.quirksmode.org/dom/w3c_core.html
詳細は書ききれないので、キーワードを元にGoogle検索してください。
> if("."+alltag[i].className == str){
<div class="foo hoge"> の時に対応できません。
この手のコードは getElementsByClassName でGoogle検索すればいくつかのサンプルが手に入りますが、高速化を目指すなら正規表現を使わないようにしてみて下さい。
高速なgetElementsByClassName - 素人がプログラミングを勉強するブログ
http://d.hatena.ne.jp/javascripter/20080805/1217 …
> document.getElementsByTagName(RegExp.$1==""?RegExp.$2:RegExp.$1):
「RegExpはグローバグオブジェクトなので使用すべきではない」と私は教わりました。
RegExp.$1 は、match() なら返り値で配列として受け取れます。
> for(var j=0; j<css.length; j++)
for文で length を毎回評価するのは効率が良くないので、
for(var j=0,m=css.length; j<m; j++)
のようにしてみてください。
> css = css.split(/\:|\;/);
わざわざ、splitを使ってまで node.style.property に値を代入するよりは、node.style.cssText に代入した方が簡単ではないでしょうか。
また、この書き方では、content: ";" とか a[title=";"] に誤爆してしまいます…。
style.cssText の使い処に関する考察 - IT戦記
http://d.hatena.ne.jp/amachang/20070730/1185788557
> if(ID){
「単一ノード or ノードリスト」で処理を分けるぐらいなら、単一ノードも配列の要素として、for文でループさせた方がシンプルに出来ると思います。
実際、jquery.js も prototype.js もそうしています。
この回答への補足
お二人ともどうもありがとうございます。
自分の力量では理解できない内容も多く含まれているので、ちょっとお礼を付けるのが遅くなってしまうと思います。しっかり読んで、最終的にはお礼もつけさせて頂きます。すみません。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- JavaScript ソースコードのいじる場所が分かりません。 1 2022/12/23 02:06
- JavaScript jQueryでのドラッグアンドドロップについて 1 2022/07/30 09:10
- JavaScript 1日1回引けるJavaScriptおみくじについて 1 2022/12/12 22:28
- JavaScript jQueryでのドラッグアンドドロップについて 1 2022/07/07 21:04
- JavaScript 画像の表示位置 3 2022/12/23 08:25
- JavaScript html5に変えるとスライドショーが消えてしまった。 3 2022/03/26 19:53
- HTML・CSS CSS のみのタブ切り替えについて 1 2023/01/11 16:47
- HTML・CSS html/cssで要素が出てこなくて困ってます 1 2022/12/31 16:59
- JavaScript ①入力フォーム→②確認表示画面→③送信完了画面のコードを書いているのです、 入力フォームから受け取っ 2 2022/05/10 16:45
- JavaScript jqueryを使ったスムーススクロールのコードを書いたのですが、HTMLコード内にある、a butt 2 2022/04/14 10:59
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
ボタンを押したあとに画像を表...
-
スマホ上で、左右スワイプで次...
-
ラジオボタンを複数選択したと...
-
jsonテキストデータの並び替え...
-
Adobe acrobat proでフォームを...
-
画面に表示したらアニメーショ...
-
2025年相性がいい人のサイトの...
-
jQueryでのレスポンシブが綺麗...
-
jsで質問です。 formをsubmitし...
-
二次元配列を使って順位をだす...
-
【JS】selectでchangeした時の...
-
sessionStorageを調べています。
-
jsで質問です。 ボタンが二つ存...
-
ブックマークレットについて
-
タグを教えてください。
-
CookieをWebStoeageに変える
-
Outlookのアカウントがあるとメ...
-
jqueryのselect2で検索欄の文字...
-
<tr>指定した表の行要素をボ...
-
食材の期限を管理するためにGAS...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
スマホ上で、左右スワイプで次...
-
タグを教えてください。
-
jqueryのselect2で検索欄の文字...
-
jsonテキストデータの並び替え...
-
初心者です。gulpでコンパイル...
-
ラジオボタンを複数選択したと...
-
階層別の組織図の自動作成について
-
jQueryで同じクラス名のものを...
-
二次元配列を使って順位をだす...
-
読み込んだQRコードをフォーム...
-
画面遷移を行わずに同一ページ...
-
セレクトを全て選択されていな...
-
【Google Apps Script】「ライ...
-
Adobe acrobat proでフォームを...
-
二次元配列の全要素の全要素を...
-
【GAS】WEBアプリでハイパーリ...
-
GASでGoogleフォームの自動返信...
-
フォームが空欄の時にフォーム...
-
セレクトボックスで配列を呼び...
-
イラストレーター、縦中横のシ...
おすすめ情報
