【task-bar】 渋谷で働くひよっこクリエイターのブログ -3ページ目

アメブロをスキン上で書けるユーザースクリプトを書いてみた

最近またJSでくだらない物を作る機会が増えました。
こんにちは、たすくです。


今、テストも兼ねて、ブログを書いてるんですが、
最近流行りの、スキン上編集(?)をできるようにして、書いてます。

試しにキャプチャを・・・

【task-bar】 渋谷で働くひよっこクリエイターのブログ


ほら!
ってわかんないかwww


【task-bar】 渋谷で働くひよっこクリエイターのブログ


こういうことです。

正確には、アメブロを見てる時にいきなり編集できるのではなくて、
記事を編集しているエディタ画面から「表示を確認する」をクリックしてポップアップさせると、
どちらの画面側からでもリアルタイムに編集&プレビューできるようになるのです。


仕組みは簡単で、全然作ればいいだけなんですけどね。


【task-bar】 渋谷で働くひよっこクリエイターのブログ


ざっくりとした仕組みの図。これが全てです。
グリースモンキーは、あらかじめ指定したページにJavaScriptを仕込んでおくFirefoxのアドオンなのですが、
今回はエディタ側ではなく、プレビュー画面側にJSを仕込むことにしました。

ここまででわかった方は閉じていいです。
以下はダラダラとした説明。


window.openerで取得、更新、イベント監視
プレビュー画面はエディタの画面から新規ウインドウで立ちあがるようになっているので、
ここでエディタ画面(親)>プレビュー画面(子)の関係が生まれます。
しかもブログ記事の画面と違い、ドメインがblog.ameba.jpでエディタ側と同じなので、
JavaScriptを使って子から親ウインドウの要素にアクセスすることができます。

addEventListenerでイベントを監視することもできちゃうので、
エディタ側からの更新は普通にkeyupイベントとかで取れちゃいます。
(jQueryを使ってるのでonメソッドですが)

最初はsetIntervalやsetTimeoutを使って定期的に取りに行く方式にしてたんですが、
だんだんブラウザが重くなっちゃったりしたのでやめました。(キューが溜まりすぎちゃったのかな)

また、アメブロのエディタは今多分3つあって、
そのうち2つにはHTMLタグ表示モードと非表示モードがあるので、全部で5パターンもあります。

実はスキンの方も今確認した感じだと新しいスキンと古いスキンで2種類あるので、
それぞれに対応するように汎用的に書かないといけないのがただただ面倒でしたww


親ウインドウのドキュメントのiframeの中のドキュメント
エディタがHTML非表示のモードだったりすると、エディタの中ってiframeが使われてるんですよね。
そうすると、ただ親ウインドウを監視してるだけだとイベントは取れません。

親ウインドウのドキュメントのiframeの中のドキュメントを取らないと。
window.opener.documentの中のhogehogeIframe.contentWindow.documentです。(iframeの取り方はお好きにどうぞ)
ここのイベントを監視してあげる。


プレビュー側にはcontenteditable=trueを仕込む
プレビュー側にはHTML5から追加された(される?)contenteditableの値をtrueにしてあげて、
編集可能にしてあげます。これ簡単だわー。
あとは普通にkeyupイベントとかが取れるので、先ほどのエディタ側からの更新の逆バージョンを
してあげればいいだけです。
欲を言えばfocusやblurも取れると嬉しかった。書き方が間違ってるのかなぁ?



はい、これで大体説明したかな?
簡単でしょ?ただめんどくさいだけです。



JavaScriptはユーザーインターフェースを構築するただの道具にすぎない
まぁ、こんな感じで、普段からくだらないJSを書いたりしてるのですが、
目的はあくまでよりよいインターフェースを研究することです。

実際に見られる自分の記事がどんな見た目になるのかって、自分はすごく気にするし、
それを確認するために都度新しいウインドウが開いちゃうのはやっぱり嫌ですよね。

「こういう風にしたら便利になるんじゃないか」っていうのを想像できたらよりよいけど、
こうやって簡単に自分の環境で試すと、意外とイケてなかったり、
また別のアイディアが浮かんできたりするものです。



ではまた。


あ、スクリプトは配布するつもりはありませーん!
僕を知ってる方で欲しい人がもしいたら、個人的にご連絡くださいw



jQuery1.7がリリースされたと聞いて ― on()/off() メソッドの追加

暇さえあればレンタルサーバー借りてドメイン取って何か作りたいと思っている。
けどその前にPC買わなきゃかな・・・。

こんばんは、たすくです。



jQuery1.7が出たと聞いて、いつもはそんなに更新情報をチェックしたりしないんですが、
ちょっと時間ができたのでちゃんと読んでみました。


やはり注目すべきは.on() .off()メソッドでしょう!

The new .on() and .off() APIs unify all the ways of attaching events to a document in jQuery — and they’re shorter to type!

新しい.on()と.off()のAPIは、ドキュメントにjQueryでイベントを紐付ける全部の手段を統合するよ!
しかも、文字数もマジで短くなったよ!
(※意訳です)
http://blog.jquery.com/2011/11/03/jquery-1-7-released/
The .on() method attaches event handlers to the currently selected set of elements in the jQuery object. As of jQuery 1.7, the .on() method provides all functionality required for attaching event handlers. For equivalents to older jQuery event methods, see .bind(), .delegate(), and .live().

.on()メソッドは、今選択されているエレメンツにイベントハンドラを紐付けるぜ!jQuery1.7では、イベントを紐付けるための全ての機能を提供するんだ。昔のbind()、delegate()、live()のようなメソッドと同等のね!
(※意訳です)
http://api.jquery.com/on/

結局どういうことなのよ
今まで、例えば<div>タグにクリックイベントを仕込もうと思ったら、
$('div').click(fn);
$('div').bind("click",fn);
$('div').live("click",fn);
$(document).delegate("div","click",fn);
とか色々あったんですよね。
将来出現する<div>タグにも効くのはlive()やdelegate()を使った書き方です。

これはクリックイベントは$(document)オブジェクトに仕込んで、
targetが<div>になっているかを見るような作りになっているそうです。
詳しくはこのあたりを参照ください。

【jQueryの.bind(), .live(), .delegate()の違い | JSer.info】
http://jser.info/post/3307464125

【The Difference Between jQuery’s .bind(), .live(), and .delegate() - Alfa Jango Blog】
http://www.alfajango.com/blog/the-difference-between-jquerys-bind-live-and-delegate/

個人的にはlive()ぐらいまで追えてたんですが、
delegate()とかは聞いたことがあっても使ったことはありませんでした。


.on()だけ覚えれば色々できるらしいよ
今回のバージョンから、それを統一できるようにしたんだそうです。
例えば、

(function($){
    var clickHundler = function(){
        $('body').append("<div>追加!</div>"); //★
    }

    $(function(){
        $('div').on("click",clickHundler);
    });
})(jQuery);

こう書くと、bind()とかと一緒で、★の部分で新たに追加された<div>タグにはクリックイベントはつきません。

でも、

(function($){
    var clickHundler = function(){
        $('body').append("<div>追加!</div>"); //★
    }

    $(function(){
        $(document).on("click","div",clickHundler);
    });
})(jQuery);

こう書くと、$(document)オブジェクトで持ってるので、
delegate()と同じことができる、ということだそうです。(多分)
★の部分で新たに追加された<div>タグにも、クリックイベントがつきます。


events-mapも地味に便利っぽいよ
.on( events-map [, selector] [, data] )
events-map A map in which the string keys represent one or more space-separated event types and optional namespaces, and the values represent a handler function to be called for the event(s).

events-map 1つのマップに対して、文字列のkeyに1つの、またはスペースで区切られた複数のイベントタイプやオプションの名前空間を指定して、valueにはイベントに対応して呼ばれるハンドラを指定するんだよ。
(※意訳です)
http://api.jquery.com/on/

つまりこういうことですかね?

(function($){
    var eventMap = {
        "click":function(){
                    $('body').append("<div>クリックで追加!</div>"); //★
                },
        "mouseover mouseout":function(){
                    $('body').append("<div>マウマアウトやオーバーで追加!</div>");
                },
        "click.testA":function(){
                    alert("1回目だけ呼ばれたらここの部分はもうoff()する!"); //▲
                    $(document).off("click.testA");
                }
    }

    $(function(){
        $(document).on(eventMap,"div");
    });

})(jQuery);


eventMapは、イベント名と関数のセットになっているオブジェクトです。
イベント名はスペースで区切れば複数のイベントタイプに1つの関数を紐付けることもできます。

しかも、"click.testA"みたいにイベント名に独自の名前空間をつけることもできるから、
主にoff()する関数を特定する時に便利!
(1回目のクリックでは★も▲も呼ばれるけど、2回目以降は★しか呼ばれない)

これはコードがスッキリするわー!


まとめ
これからjQueryを始める人は、on()とoff()だけ知ってればいいっぽいので、
今までよりずっとわかりやすくなりましたね!

何より、
on()とoff()って名前がわかりやすい。笑

無名関数で書いても、
$('div').on("click",function(){
    //hoge
  })
になるわけじゃないですか。もうほとんど"onclick"ですよね。


そんなわけで、非常に使いたくなる今回のバージョンアップのお話でした!
誰か手軽にjQueryをバージョンアップする方法を知りませんか・・・・?

iOS5でposition:fixedやoverflow:scrollが効くようになったと聞いて

iOSのアップデートってホントわくわくしますね。
こんにちは、たすくです。

iOS5でposition:fixedやoverflow:scrollが効くようになったと聞いて、久々のブログ。

そんなわけで、OSをアップデートする前にサンプルを作ってやってみました。
端末はiPhone 3GSです。


iOS4.3(ぐらい)

水色の所がposition:fixed。




うん、効かないね!!
普通に上にスクロールされちゃう。


overflow:scrollはこんな感じ。


これは知らない人結構いるんですけど、2本指でスクロールできるんですよねー。





iOS5

さて、アップデート後!!




おおお!fixされた!!

overflow:scrollの所も、1本指でできるようになって、しかも動きもスムーズです。


これ、多分Appleの考えるUIのポリシーでわざと未実装だったんじゃないかとか思ってたんですけど、
実際の所どうなんでしょうね。

ただでさえ狭いディスプレイでfixされたら領域が狭くなっちゃうし、
スクロールだって全体の所でスクロールしたい時に上手くいかないかもしれないし。

経緯はどうあれ、これを実現するためにJSでがんばって無茶するみたいなことよくあったので、
これで大分実装が楽になりそうですね。


ではまた。