Home / Diary / タグ: javascript
このエントリは、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
- 投稿日
- 2006年5月13日
- タグ
- css、javascript
- このエントリの固定リンク
- http://bmky.net/diary/log/1381.html
- ブックマークに追加する
-
- コメント
2006
0513
Tagscssjavascript
Ajaxにおけるメモリリークの注意点
最近作ってるやつは、Firefox+IETabで動作確認しながら作業してるわけだが、なんか動作重いっつーかスワップしまくってねーか? と思ってタスクマネージャー開いたらメモリを300MB食っててえらいビビッた。これだったのか。
今確認したら一回リロードする度に10MB増えてた。10MBて。
Info
- 投稿日
- 2006年3月24日
- タグ
- javascript
- このエントリの固定リンク
- http://bmky.net/diary/log/1350.html
- ブックマークに追加する
-
- コメント
2006
0324
Tagsjavascript
このエントリは、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
- 投稿日
- 2006年3月14日
- タグ
- css、javascript
- このエントリの固定リンク
- http://bmky.net/diary/log/1342.html
- ブックマークに追加する
-
- コメント
2006
0314
Tagscssjavascript
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年3月5日
- タグ
- javascript、opera
- このエントリの固定リンク
- http://bmky.net/diary/log/1336.html
- ブックマークに追加する
-
- コメント
2006
0305
Tagsjavascriptopera
丸角を作って1ドットの枠線だけじゃ物足りないということで改良した。
Nifty++ サンプル
- 片方だけ丸くすることが可能に。
- 枠の太さを調節可能に。ブラウザが持つ限りどこまでも。
- グラデーションを付けられるようにした。
- 内部の要素に同じ背景色と枠線を付加させたりとか
サンプルページ下部の橙色のところにマウス乗せてホイール回せば枠線が増える。キモいぐらいに。
グラデも搭載。思いっきり手抜きな実装してるにもかかわらずそれなりに見える。
あとは一々枠線や背景色設置するの激しくめどー、なのでそれなりに一括で付けられるように。
で、作ってて思ったんだが、JavaScriptでスタイル再設定とかするのは正直よろしくねーなー、と。
基本的にDOMを扱うので実際に動くのはページの読み込みが完了した後。つまり、一瞬でも設定されてない状態が表示されてから設定されることが多発するわけで、その瞬間がどーしても嫌だなーとか思うわけですよ。
まあ、内部的にはそこまでメンドイことしてないんで直接CSSに書き込んだりしてもいいとは思うが・・・それはそれでローカルソースに内容に関係ない要素一杯とかでなんかムカつくのぅ。
となると・・・やっぱりPHPあたりで生成するのが一番なのかもしれんなーとか思ったり。もしくはCSS3が標準装備されて背景画像が複数設定可能になればみんな幸せになれるんだが、一体何年後になるんだ?
Info
- 投稿日
- 2006年1月20日
- タグ
- css、javascript
- このエントリの固定リンク
- http://bmky.net/diary/log/1299.html
- ブックマークに追加する
-
- コメント
2006
0120
Tagscssjavascript
Nifty Cornersを見た後、これ利用すれば枠付きもいけるんでね? というわけで作ってみた。
サンプル
中のpaddingとかmarginとかに左右されるんで、スクリプト設置してすぐに丸角ってわけにはいかないのね。
そこらへんを解消しようと思ったが、スクリプトでさらにスタイル設定したり消したりする必要があるんで、なんか面倒になったんでやめた。がんばれば枠の太さも設定できそうだがさらにめどい。
そこまでする必要がこの枠付き丸角にあるんかね? と思ったが、CSS2だか3の丸角が結構汚いんで作る価値はあるかもしれん。
そういや作ってる時に思ったんだが、丸角になると1ドットにこだわりたくなるのは何故なんだろう? いや、美しい曲線を描くには1ドットのズレも許されないわけなんだが、ちょいと色変えてグラデかませばいいじゃんとか思いつつも単色で曲線。むぅ・・・
Info
- 投稿日
- 2006年1月17日
- タグ
- css、javascript
- このエントリの固定リンク
- http://bmky.net/diary/log/1297.html
- ブックマークに追加する
-
- コメント
2006
0117
Tagscssjavascript
ここまで書いといてなんだが、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年1月7日
- タグ
- javascript
- このエントリの固定リンク
- http://bmky.net/diary/log/1284.html
- ブックマークに追加する
-
- コメント
2006
0107
Tagsjavascript