Home / Diary / タグ: javascript

12

目次

  1. JavaScriptでCSSを弄る際のメモ その2
  2. Ajaxにおけるメモリリークの注意点
  3. JavaScriptでCSSを弄る際のメモ
  4. OperaのJavaScriptでマウスホイールを検知できるようになった
  5. 枠付きグラデで四角い角を丸くする - Nifty++
  6. JavaScriptで枠付き丸角をつける
  7. textareaでタブ入力

JavaScriptでCSSを弄る際のメモ その2

このエントリは、JavaScriptによるCSSの操作として新たに書き直しました。

-

前回同様、結構適当に書いてる部分もあるので鵜呑みにしないように。

IEとMozillaでは、スタイルシートの値を取得するには以下の処理を利用すればよい。

function getStyleValue( selector, property ) {
  property = ( property.match( /-/ ) ) ? property.camelize( ) : property;
  var stylesheets = document.styleSheets[0].rules  //IE
                 || document.styleSheets[0].cssRules; //Mozilla
  for( var i = 0, len = stylesheets.length; i < len; i++ ) {
    var css = stylesheets[i];
    if( css.selectorText.toLowerCase( ) == selector.toLowerCase( ) ) {
      if( css.style[ property ] ) return css.style[ property ];
    }
  }
  return null;
}

しかし・・・

全称セレクタ

IEにはほとんどの場面で取得出来なくなる仕様が存在する。

ul * { line-height : 150% }

このようにスタイルシートに記述していた場合

getStyleValue( "ul *", "line-height" );

このようにしてもIEでは取得できない。どうやら内部でアスタリスクが消されるようで、document.styleSheets[0].rulesを参照しても、上記の場合はselectorTextがulのみになってしまう。

じゃあアスタリスクを除いたulだけ指定して取得すればいいじゃん、と思うが

ul { margin : 1em }
ul * { margin : 0.5em }

もし、このように指定されていたら、forループ中に先に指定したulがひっかかってしまい、本来取得したいul要素の子要素全てのmarginは取得できなくなってしまう。

ブラウザの差異を無くすために以下のように記述することがある。

* {
margin : 0;
padding : 0;
font-size : 100%;
font-weight : normal;
font-style : normal;
line-height : 100%;
list-style-type : none;
}

この場合は以下のようにすることで取得することができる。

getStyleValue( "", "line-height" );

ちなみに

ul * span { line-height : 150% }

これを取得する場合は以下のようにする。

getStyleValue( "ul  span", "line-height" );

スペースを二つ空けるのがポイント。一つではダメ。

これらは全てIEのみで、mozillaは関係ない。

グループ化

ul li, span { line-height : 150% }

カンマで区切ってグループ化する場合、IEでは内部で分解される。

getStyleValue( "ul li", "line-height" );
getStyleValue( "span", "line-height" );

上記で両方とも取得できる。が、「ul li, span」では取得できない。

逆にmozillaは内部で分解されないので

getStyleValue( "ul li, span", "line-height" );

と指定する必要がある。ややこしい。

まとめ

JavaScriptでCSSを弄るつもりなら、全称セレクタは使うな。グループ化は避けろ。

そこでプロパティ別整理法をプッシュしてみる。

全てとは言わず、デザイン段階での変更頻度が高い「margin、padding、color、background、border」あたりだけでもやっておくと結構楽。ただし、CSSのサイズが小さい場合は逆効果。

どうでもいいこと

getStyleValueを、同じセレクタで複数スタイルを指定していても(たぶん)大丈夫なように変更。

愚痴

OperaはWidgets実装して浮かれてる暇があったらさっさとDOM2 CSSをサポートしやがれ。ってゆーかサポートしてくださいお願いしますおぺらたん

愚痴 その2

IE7はタブ+RSS実装して浮かれてる暇があったらさっさとdataスキームを実装しやがれ。

Info

SBM Comments

kyorecoba
本当にCopyURL+になってしまいます。
nikutetu
C:\(ユーザー名)\AppData\Roaming\Opera\Opera\menu.iniでできるみたいhttp://twitter.com/amayav/status/5396066616
min3
後で適応させたいです…
mindexinfo

2006
0513

Tagscssjavascript

Ajaxにおけるメモリリークの注意点

Ajaxにおけるメモリリークの注意点

最近作ってるやつは、Firefox+IETabで動作確認しながら作業してるわけだが、なんか動作重いっつーかスワップしまくってねーか? と思ってタスクマネージャー開いたらメモリを300MB食っててえらいビビッた。これだったのか。

今確認したら一回リロードする度に10MB増えてた。10MBて。

Info

2006
0324

Tagsjavascript

JavaScriptでCSSを弄る際のメモ

このエントリは、JavaScriptによるCSSの操作として新たに書き直しました。

-

俺の探し方が悪いんだろうが、JavaScriptでCSSを弄るリファレンスが中々見当たらなかったので、メモも兼ねて書く。

結構適当に書いてる部分もあるので鵜呑みにしないように。あと、Operaは知らね。

スタイルシートのルールを弄る

div内の全要素をgetElementsByTagNameで拾ってforで回してstyleに・・・ってなことをやるよりも、スタイルシート側から操作できるようになれば楽になる。

function addRule( selector, property ) {
 if( document.styleSheets[0].addRule ) //IE
  document.styleSheets[0].addRule( selector, "{" + property + "}" );
 else if( document.styleSheets[0].insertRule ) //Mozilla
  document.styleSheets[0].insertRule( selector + "{" + property + "}", document.styleSheets[0].cssRules.length );
 else
  return false;
}

addRule及びinsertRuleはルールの先頭に追加していく。ルールは基本的に対象が同じなら後から指定したものが有効になるので、どんどん追加していって構わない。

addRule( "div ul.hoge", "display : none" );

これでdiv以下のhogeクラスが指定されてるリスト要素にdisplay:noneを適用して表示しないようにすることができる。

addRule( "div ul.hoge", "display : block" );

あとから追加したものが有効になるので、こうすれば元に戻る。

スタイルシートのルールを取得する

設定できたなら、取得したい時もある。

function getStyleValue( selector, property ) {
 property = ( property.match( /-/ ) ) ? property.camelize( ) : property;
 var stylesheets = document.styleSheets[0].rules        //IE
  || document.styleSheets[0].cssRules;  //Mozilla
 for( var i = 0, len = stylesheets.length; i < len; i++ ) {
  var css = stylesheets[i];
  if( css.selectorText.toLowerCase( ) == selector.toLowerCase( ) )
   return css.style[ property ];
 }
}

こうすることで、現在適用されているルールの値を直接取得することができる。

IEの場合、直接指定されたもののみ取得できるが、Mozillaの場合は、指定していないものはデフォルトの値が入って返ってくる

getStyleValue( "div.hoge", "background" )

IE : #668
Mozilla : rgb(136, 102, 102) none repeat scroll 0% 0%

MozillaはRGBの値が自動的に変換されるのにも気を付ける。

camelizeはハイフン+小文字アルファベットを大文字アルファベットに直す関数。deCamelizeはその逆。

String.prototype.camelize = function( ) {
 return this.replace( /-([a-z])/g,
  function( $0, $1 ) { return $1.toUpperCase( ) } );
}
String.prototype.deCamelize = function( ) {
 return this.replace( /[A-Z]/g,
  function( $0 ) { return "-" + $0.toLowerCase( ) } );
}

こげな感じに宣言しておく。

どうでもいいが、camelizeの逆の動作はdeCamelizeでいいんだろうか? 英語っつーかそこらへんの命名規則に全然詳しくないからわからん。

スタイルシートを無効にする

document.styleSheets[0].disabled = true

これだけ。インライン指定したものは有効なままなので注意。

要素に適用されているスタイルを取得する

div#hoge { margin-top : 10px }

このようにスタイルシートに記述して、該当要素を取得してstyle.marginTopの値を見ても中身は空である。インラインレベル、つまり今現在適用されているスタイルを取得したい場合は以下のようにする。

function getActiveStyle( element, property, pseudo ) {
 if( element.currentStyle ) {           //IE
  property = ( property.match( /-/ ) ) ? property.camelize( ) : property;
  return element.currentStyle[ property.camelize( ) ];
 }
 else if( document.defaultView.getComputedStyle ) { //Mozilla
  property = ( property.match( /-/ ) == null ) ? property.deCamelize( ) : property;
  return document.defaultView.getComputedStyle( element, pseudo ).getPropertyValue( property );
 }
 return "";
}

getActiveStyle( $( "hoge" ), "marginTop" );
getActiveStyle( $( "hoge" ), "margin-top" );
getActiveStyle( $( "hoge" ), "margin-top", ":first-line" );

こんな感じで使う。

getComputedStyleについて

getComputedStyleの第二引数は擬似要素・セレクタを取得したいときに使う。:first-lineとか:visitedとか。

IEの場合は擬似要素・セレクタの取得が不可能っぽい。currentStyle周辺を掘ってみてもそれっぽいものは見当たらなかった。

getPropertyValueについて

div { margin : 20px }

と指定してgetPropertyValueからmarginで取得しても空の文字列が返ってくる。どうやら一括指定のプロパティは指定できないようになっているらしい。

margin :
marginTop : 20px
marginRight : 20px
marginBottom : 20px
marginLeft : 20px

この場合だとこのようになってしまっているので、1方向ずつ取得しなければならない。IEのcurrentStyleならmargin指定でも問題なし。

続く

Info

SBM Comments

nirvash
便利っぽい。暴走しなければ。
mosshm
ページ最下部でspaceを押すとFast Forwardと同様の動作。
kyu
kusigahama
あとで / http://piro.sakura.ne.jp/xul/_rewindforward.html
trickstar_os
マウスジェスチャの進むでもイケル/検索画面で重宝
miya2000
コレって前から有る早送りの機能だよね。今更感があるんだけど。それをスペースキーに割り振ったのが素晴らしいということかな?
firestorm
にゅん。
brainparasite
後で見よう
moe2
(http://extendead.web.fc2.com/)から。 インベーダーから始まり昨今の弾幕シューまでを30分の中でやや圧縮気味だがしっかりと紹介している。とても素晴らしい。 リンク先ではわざわざ日本語字幕を作成してくれている。非常に感

2006
0314

Tagscssjavascript

OperaのJavaScriptでマウスホイールを検知できるようになった

Opera最新テスト版でホイールいけるよ、とのタレコミを頂いたので、早速テスト版ホームページを見てみた。

Changelog:

  • Added support for onmousewheel events.

Opera Weekly build - Desktop Team

マ、マジだー! 現在作成中のアプリケーションで試してみたら、手を加えるまでもなく動作した。よくやったOpera!

window.attachEvent( "onmousewheel", function( e ) { alert( e.wheelDelta ) } );

これで簡易テスト。wheelDeltaだと手前に転がして120、奥なら-120。detailだと手前で3、奥で-3を検出。前者はIE、後者はFirefoxと一緒だな。

ブラウザ event property 手前回転
IE onmousewheel WheelDelta
Firefox DOMMouseScroll detail
Opera onmousewheel 両方

こなかじ?

Info

2006
0305

Tagsjavascriptopera

枠付きグラデで四角い角を丸くする - Nifty++

丸角を作って1ドットの枠線だけじゃ物足りないということで改良した。

Nifty++ サンプル

サンプルページ下部の橙色のところにマウス乗せてホイール回せば枠線が増える。キモいぐらいに。

グラデも搭載。思いっきり手抜きな実装してるにもかかわらずそれなりに見える。

あとは一々枠線や背景色設置するの激しくめどー、なのでそれなりに一括で付けられるように。

で、作ってて思ったんだが、JavaScriptでスタイル再設定とかするのは正直よろしくねーなー、と。

基本的にDOMを扱うので実際に動くのはページの読み込みが完了した後。つまり、一瞬でも設定されてない状態が表示されてから設定されることが多発するわけで、その瞬間がどーしても嫌だなーとか思うわけですよ。

まあ、内部的にはそこまでメンドイことしてないんで直接CSSに書き込んだりしてもいいとは思うが・・・それはそれでローカルソースに内容に関係ない要素一杯とかでなんかムカつくのぅ。

となると・・・やっぱりPHPあたりで生成するのが一番なのかもしれんなーとか思ったり。もしくはCSS3が標準装備されて背景画像が複数設定可能になればみんな幸せになれるんだが、一体何年後になるんだ?

Info

2006
0120

Tagscssjavascript

JavaScriptで枠付き丸角をつける

Nifty Cornersを見た後、これ利用すれば枠付きもいけるんでね? というわけで作ってみた。

サンプル

中のpaddingとかmarginとかに左右されるんで、スクリプト設置してすぐに丸角ってわけにはいかないのね。

そこらへんを解消しようと思ったが、スクリプトでさらにスタイル設定したり消したりする必要があるんで、なんか面倒になったんでやめた。がんばれば枠の太さも設定できそうだがさらにめどい。

そこまでする必要がこの枠付き丸角にあるんかね? と思ったが、CSS2だか3の丸角が結構汚いんで作る価値はあるかもしれん。

そういや作ってる時に思ったんだが、丸角になると1ドットにこだわりたくなるのは何故なんだろう? いや、美しい曲線を描くには1ドットのズレも許されないわけなんだが、ちょいと色変えてグラデかませばいいじゃんとか思いつつも単色で曲線。むぅ・・・

Info

2006
0117

Tagscssjavascript

textareaでタブ入力

ここまで書いといてなんだが、textarea走査して頭にタブ入れてコピペで使い回せばいーじゃん、というのが後で浮かんだ。

var ta = document.getElementsByTagName( "textarea" );
for( var i in ta ) {
    ta[i].onselect = ta[i].onclick = ta[i].onkeyup = storeCaret;
    ta[i].onkeydown = keypress;
}
function storeCaret( ) {
    if( this.createTextRange )
        this.caretPos = document.selection.createRange( ).duplicate( );
    else if( this.selectionStart )
        this.caretPos = this.selectionStart;
    else
        this.caretPos = 0;
}
function keypress( e ) {
    e = ( window.event ) ? window.event : e;
    if( e.keyCode == 9 ) {
        insertAtCaret( this, "\t" );
        e.preventDefault( );
        this.focus( );
        return false;
    }
}
function insertAtCaret( tarea, text ) {
    if( tarea.createTextRange && tarea.caretPos ) {
        tarea.caretPos.text =
        ( tarea.caretPos.text.charAt( tarea.caretPos.text.length - 1) == ' ' )
            ? text + ' ' : text;
    }
    else if( tarea.selectionStart && tarea.caretPos ) {
        tarea.value = tarea.value.substr( 0, tarea.caretPos )
                    + text
                    + tarea.value.substr( tarea.caretPos );
    }
    else {
        tarea.value = text + tarea.value;
    }
}

どっか海外の掲示板からコード拝借したんだが場所忘れた。

Info

2006
0107

Tagsjavascript

暴満館

最新のエントリ
注目のエントリ(はてな)
ゲーム攻略

暴満館 ~The House of Full Violence~
Powered by WordPress.
About | Contact | 新着のエントリ情報 RSS

ページ内の見出し一覧
JavaScriptでCSSを弄る際のメモ その2
Ajaxにおけるメモリリークの注意点
JavaScriptでCSSを弄る際のメモ
OperaのJavaScriptでマウスホイールを検知できるようになった
枠付きグラデで四角い角を丸くする - Nifty++
JavaScriptで枠付き丸角をつける
textareaでタブ入力