Hatena::ブログ(Diary)

IT戦記 このページをアンテナに追加 RSSフィード Twitter

2007-07-30

style.cssText の使い処に関する考察

cssText って知ってますか?

cssText っていいうのは CSSRule オブジェクトとか CSSStyleDeclaration が持っている情報を css ファイルに書く形式の文字列にしてくれる機能です。

乱暴に言ってしまえば、 css 系のオブジェクトが持っている innerHTML みたいなものです。

具体例を見てみましょう。

こんな感じの body があるときに

<body style="margin: 1em; padding: 1em; border: 1em">....</body>

こんな感じで使えます。

alert(document.body.style.cssText); // 'margin: 1em; padding: 1em; border: 1em'

簡単でしょう?(ボブ略

設定も出来ますよ

こんな感じ

// さっきの続き
document.body.style.cssText = 'width: 100px'; 
alert(document.body.style.margin);  // ''
alert(document.body.style.padding); // ''
alert(document.body.style.border);  // ''
alert(document.body.style.width);   // '100px'

簡単でしょう?

クロスブラウザ

Safari 3, Opera 9, Firefox 2, IE 6, IE 7 で動いたよ!

パフォーマンスは?

めっちゃ適当に計ってみたら、普通に style.width = '100px'; みたいに一個一個入れてくより、目安 2 〜 3 割遅いことが分かった。

で、

あんまり使う必要なくね?

うんうん。そう思う

でも

さっき便利な使い方を 3 つ思いついたので紹介します。

デバッグ時に値を見るとき

これは普通に便利。

いちち style.xxxx を書くのがめんどくさいとき

うん。あるある。

スタイルをキャッシュしておいて戻したりしたいとき(本題)

たとえば、キャッシュしておいて

var style = element.style;
var cache = style.cssText;

いろいろいじっても、元に戻せる機能を付けたいとか。

style.cssText = cache; // これだけで元の style に戻せる。

便利!

ちなみに

実はこれよりもっと効率的な方法があるのですが、その方法は IE では動きませんでした。その方法は以下。

// キャッシュするとき
var style = element.style;
var cache = {};
for (var i = 0, l = style.length/*←IEではこれがない*/; i < l; i ++) {
    var n = style[i]; // ←IEではこれもない
    cache[n] = style[n];
}

// 戻すとき
for (var i = 0, l = style.length; i < l; i ++) {
    var n = style[i];
    if (!(n in cache)) { // キャッシュにないプロパティは削除
        style[n] = '';
    }
}
for (var n in cache) style[n] = cache[n]; // キャッシュされてるものを戻す

長ったらしいけど、これが一番効率的だと思います。

もちろん、全プロパティを走査すれば簡単にキャッシュできるのですが、それだと激重です。

まとめ

style.cssText ってべんりー!

2007-07-20

はてなスターのマイページで、その人のエントリーが見れたらいいのに

また、はてなスターのネタか!

ごめんって><

自分のエントリーに★が付いてたときの話し。

自分のエントリーについてる★をクリックすると http://s.hatena.ne.jp/だれか/ みたいなページに飛ぶんだけど、

そのページに飛んだ気分としては、その人のことを知りたい気分な訳ですよ。「誰誰?わくわく><」みたいな?

だから、そこでその人が持ってるブログとか(フィード)のサマリーが出てたらいいなあ。ついでにそこで★付けられたらいいなあ。

で、 Friends が増えていって、いつのまにかみんな仲良し!馴れ合い馴れ合い!ひゃっほーい!

あと、ブログ始めたばっかりの人がすぐに読者を獲得できたりして、いいことばっかりじゃないかなあ!><

2007-07-19

はてなスターの好きなところ

僕がはてなスターが好きなところ

自分のはてなスターのページを見て。

http://s.hatena.ne.jp/amachang/

そのページの Friends を見て。

「あ。まだあの人 Friends じゃないや。あの人が面白いと思う記事を書きこう。」

ってたまに思っちゃうところがすごく好き。

そろそろ、はてなスターについてちょこっといっとくか

僕は

はてなスター大好き!

でも、メッセージの送信機能が Mac OSX + Firefox の環境を考慮してない><

問題は Enter キーのイベントハンドリング。

WindowsIME は変換して決定するときの Enter キーのイベントを Firefox に渡さないんだけど、

Mac OSX の IME は変換して決定するときの Enter キーのイベントを Firefox にわたしちゃうんだよね><

だから、一回変換するごとに投稿されちゃって変な感じのメッセージになっちゃうんです。

これは、かなり難しい問題なんですけど、やっぱり form にして submit イベントに引っ掛けるのがいいと思います。

keydown ではどうしてもこの問題の解決は難しいと思うのです><

追記:

via:http://b.hatena.ne.jp/kazuhooku/20070719#bookmark-5324366

keydown じゃなくて keypress だと IME の時のイベントは送られないようですね!

じゃあ form submit にしなくても keypress でいいのか。

2007-07-18

今回の CSS Nite の件について

このエントリーについて

このエントリーでは、この CSS Nite の一連の騒動について自分の本心を包み隠さずに書きたいと思います。そして、今まで取ってきた行動が僕のどういった感情からであったかということを、少し冷静になった今改めて振り返ってみたいと思います。

今回の騒動について??な人は、まとめページをご覧ください。

今回の CSS Nite 騒動について

僕がどのようにして CSS Nite を知り、どのような感情を抱いて、どのような発言をしたかについてまとめてみたいと思います。

この騒動が起こる前に、僕が CSS Nite に抱いていた感情について

まずこの騒動の流れを追う前に、僕が CSS Nite に対してどういった感情を抱いていたか、「僕が何故 CSS Nite のことを嫌っているのかについて」お話をしたいと思います。

それは、僕が初めて CSS Nite のイベントに参加したときのことです。

その二次会で CSS Nite 関係者二人に、僕のエンジニアとしての信念を否定されるようなことを言われました。しかも、その時は回りがほとんど関係者で僕は何も言い返すことができませんでした。それは、おおよそお金を取って開催したイベントの関係者の発言とは思えませんでした。そのときの彼らからは、「自分たちに限っては、人に対して失礼なことを言える」というような傲慢な自信のようなものを感じました。

その日は、その発言の直後退席したのですが、彼らは周りを身内で固めてとても幸せそうに笑っていました。その姿が今も僕のトラウマになっています。

これが僕が CSS Nite を嫌うようになったきっかけです。

それから、もう一度 CSS Nite のイベントに足を運んだんですが。その時も彼らの態度は酷く、お金を払ってきた客に対する態度と、自分たちが無料で招待した客に対する態度は、明らかに逆だろというものでした。僕がここで感じたのは、都合のいい客は VIP 待遇で囲みこんでしまって客を見下す運営側の姿勢でした。それから、僕は CSS Nite のイベントに行かないことにしました。

今回の騒動を知った経緯〜ブログのエントリーを書くまで

で、僕が今回の CSS Nite の一連の騒動を知ったのは、 CSS Nite の主催者でマイミクの鷹野さんの mixi の日記でした。

今は公開されていませんが「ブチ切れた! 儲かると思うなら自分でやればいい。」という内容で、このエントリーにリンクが貼られていました。さらに、このエントリーから以下の二つのエントリーがリンクされていました(現在リンクは削除されています)。

CSS Niteについて考えてみる | Transrain

Web標準の日々 (smashmedia)

一つ目のエントリーは神戸エンジニア悠希さんのもので、二つ目のエントリーは執筆活動や講演活動などもされている河野さんという方のものでした。

この二つのエントリーでは CSS Nite のお金取り過ぎじゃない?と取れるような発言がされていました。ここで、僕はドキっとしました。なぜなら、僕自身も「CSS Nite お金取り過ぎじゃない」そう思っていたからです。

そして何故か、悠希さんだけがもの凄い勢いで mixi や はてブ や コメント欄 で叩かれていました。何故あのとき、あの人たちは河野さんには牙をむかなかったんでしょうか。僕は思いました「これってただの弱いものイジメなんじゃないでしょうか。」それに僕だって同じことを思ってたんです。「僕だって叩かれていいはずだ。いや、同じことを思ってた人間は他にももっともっといたはずだ。なら、なんでみんな静観してるんだよ!」って思いました。

だから、僕はこのエントリーを書きました。

収支概算を公表します:[Shibuya.JS Technical Talk] - IT戦記

このエントリーをネタという位置づけにして逃げたことはもの凄く反省しています。明確に「僕は CSS Nite はお金取り過ぎだと思います」と発言すべきだった。そう思っています。

そして、その後も収支に対する疑問をブックマークしていきました。

はてなブックマーク - amachangのブックマーク

これに関しては僕は自分の発言一言一言が非常に大人げなかったと反省しています。

ブログのエントリーを書いたあと

ブログのエントリーは僕の意図しない方向に転んでしまいました。それは、有料 vs 無料という構図です。

僕は、 YAPC とか LL 魂とか凄く好きだし、有料イベントに対して批判をしてるつもりはなかったのです。僕は、「僕も CSS Nite は金取り過ぎだと僕も思う!」ということが言いたかっただけなのです。

そして、さっき僕は一つのことに気が付きました。 YAPC が 10,000 円だったら参加しないのか?ということです。僕は、たぶんすると思います。いや 20,000 円だろうが 30,000 円だろうが参加したいと思います。

僕はただ単に「あんなにひどい CSS Nite」が高いってことがムカついていただけなんだ。と気が付きました。

だから、僕は僕が本当に思っていたことを言うことにしました。

僕が言いたかったこと

服装や身なりを指して、エンジニアのことをバカにすんな!

お前がかっこいいと思ってる人間よりも、もっとかっこいい人間が僕の周りにはいっぱいいるんだよ!

僕はかっこいい人間に囲まれて JavaScript を書いているんだよ!それをバカにするな!

そんなやつに Web 標準なんて言われたくないんだよ!!!!

本当に今回の騒動は

申し訳ありませんでした。僕は本当に餓鬼で感情的でどうしようもないバカなんです。

みなさん、悠希さんを叩いたあのときのように僕を叩いてください。

2007-07-14

収支概算を公表します:[Shibuya.JS Technical Talk]

ネタですよ><

http://cssnite.jp/archives/post_746.php

なんか、収支概算が流行っているようなので、 Shibuya.JS の収支を非公式に概算してみた。

チケット収入01400
協賛費--0
収入小計--0
会場費--0
人件費(撮影費、モデレータ、講師料)--0
ノベルティ 書籍--0
企画費--0
制作費--0
入場パス--0
印刷代 ガイドブック等(ナガヤマン作)01400
書籍買い取り--0
通信費--0
販売手数料--0
はてなガム01400
経費小計--0
差額--0

すげえ!Shibuya.JS すげえ!

僕は

いや。ネタですよ。

い、いや、ネタですってば。

く、比べちゃらめええええええええええ

追記:あ。あと一つ忘れてました

参加者の笑顔 priceless

2007-07-10

どう書く?.org に JavaScripter が少ない・・・。

ほら

コード見てもらうことは

そのコードを見てもらえないことの 10 倍以上の勉強効果があると思う!

どーせ、 JavaScript のソースは隠せないんだし!

どう書く?.org で色んな人の JS が読みたいです!

うほ!

目指せ No.1 言語!

2007-07-03

IE で removeChild した要素はどこへいくか?

普通のブラウザだと

parent.removeChild(child);
alert(child.parentNode); // null

なぜか、 IE だと DocumentFragment が生成されている。

parent.removeChild(child);
alert(child.parentNode);          // [object]
alert(child.parentNode.nodeName); // #document-fragment

な、なぜ?

変なブラウザだなー

Opera の CSSStyleSheet.insertRule はちょっとバグってる

以下のコード

var element = document.createElement('style');
element.appendChild(document.createTextNode(''));
document.getElementsByTagName('head')[0].appendChild(element);
var sheet = element.sheet;

// 以下のように CSSStyleSheet の先頭に二つのルールを挿入していく
sheet.insertRule('html body { background: gray }', 0); // 0 番目にこのルールを挿入
sheet.insertRule('html body { background: red }', 0);  // 0 番目にこのルールを挿入

このようにするとルールの順番は html body { background: gray } のほうが下にくるので、

カスケーディング順位(CSS のルールの優先順位)は html body{ background: red } より html body{ background: gray } のほうが上位になるはずである。

ということはこれを実行すると、body 要素の背景は gray になるはずである。

しかし Opera では

背景は red になってしまう。

これは、 OperainsertRule の第二引数に関わらず、ルールをルールリストの最後に挿入してしまうためである。

ブックマークレット化したので、実際にやってみてください。(IE は全くの独自仕様なのでこのブックマークレットはうごきません。あしからず)

javascript:var element=document.createElement('style');element.appendChild(document.createTextNode(''));document.getElementsByTagName('head')[0].appendChild(element);var sheet = element.sheet;sheet.insertRule('html body { background: gray }', 0);sheet.insertRule('html body { background: red }', 0);void(0);

まとめ

現状 insertRule を使う場合は、以下のようにルールをルールリストの最後に追加しなければブラウザ間の整合性が保てなくなってしまう。

sheet.insertRule('html body { background: black }', sheet.cssRules.length);

まあ、 IE 独自の addRule も最後にしか挿入できないし、どっちにしろそうなんだけどね(ぇ

Safari で CSSStyleSheet オブジェクトを生成する方法

今まで Safari では出来ないと思っていました

var element = document.createElement('style');
document.getElementsByTagName('head')[0].appendChild(element);
var sheet = element.sheet;
alert(sheet); // null

こんな感じで null になってしまうのです。。。

しかし!

さっき出来る方法が分かりました!

var element = document.createElement('style');

element.appendChild(document.createTextNode('')); // この行を追加

document.getElementsByTagName('head')[0].appendChild(element);
var sheet = element.sheet;

alert(sheet); // [object CSSStyleSheet]

このように TextNode を追加することで sheet オブジェクトが取得できるようになりました。

あー。どうして今まで試さなかったんだろう!

でも、分かってスッキリ!

そのオブジェクトが enum 可能なプロパティを持っているか

こうやってやってるけど、なんかいい方法ないかなあ

for (var i in obj) { var hasProp = true; break }

document.createStyleSheet で動的に CSS を生成

今まで

var element = document.createElement('style');
document.getElementsByTagName('head')[0].appendChild(element);
if (ie) {
    var sheet = element.styleSheet;
}
else {
    var sheet = element.sheet;
}

みたいにやっていた。

ところが

dojo のソースを眺めていたら

IE には createStyleSheet という関数があるみたい。

createStyleSheet を使うとこうなる。

if (ie) {
    var sheet = document.createStyleSheet();
}
else {
    var element = document.createElement('style');
    document.getElementsByTagName('head')[0].appendChild(element);
    var sheet = element.sheet;
}

あまり代わり映えはしないけど。無駄な要素を挿入しなくてもいいので、こっちのほうが軽いかな。

IE は多数派なので、直しておこうっと。