jQuery - plugin layerSlide

jQueryの要素をslideさせるプラグインを作ってみた。

jQueryでスライドさせるのは簡単にできるので、animate のラッパー的な感じで便利に使えたらイイかな。

実験的な意味合いも込めて、「どうしたら使いやすくなるか」という点での反省も含めて今後に活かせたら幸い的なモノです。


関係する要素は3つ。

親要素を指定して、子要素が一つ存在する必要がある。
その第一子要素と引数として第二子要素を渡し、この二つがスライドする対象になる。

Option

使用できるオプションは以下の通り。

  • duration:300, // animate speed
  • easing:'swing', // animate easing
  • bgColor:'#000', //second layer background color
  • opacity:0.8, // second element opacity
  • color:'#eee', // second element color
  • margin:'10px', // second element margin
  • textAlign:'left', // second element text-align
  • height:'original', // second element height
  • width:'original', // second element width
  • bgImage:'none', // second element background-image
  • effect:'down' //default slide animate

面倒なのでソースからコピペしてしまった。
つまり、オプションのデフォルトは以上の通り、ということになる。


動作確認は以下にて。

demo:Fiat 500 photostream

vertical sliding down

Fiat 500

©Blastblog
More...


horizontal sliding left




diagonal sliding bottomRight



vertical sliding partialLeft



vertical sliding secondRaise



diagonal sliding secondBottomRight



diagonal sliding secondBottomLeftFiat 500 Interior

imgのalt属性を取得して表示しています。



alt属性を表示する

alt属性を表示するのも簡単。
以下のようにalt属性を取得して第二引数として渡してやるだけ。
$('.target').layerSlide({
 effect:'secondBottomLeft'
 },$('<p>').text($('img','.target').attr('alt')).get(0));



問題点

window.onloadの後でないと要素のサイズを正しく取得できないので、使用するには一手間必要。

使用例
(function(fn){
 if (window.addEventListener) {
  window.addEventListener('load', fn, false);
 }
 else 
  if (window.attachEvent) {
   window.attachEvent('onload', fn);
  }
})(function(){
 $('#target').layerSlide({effect:'down'},$('#target-desc').get(0));
});
このようにwindowのonloadイベントに登録する形になる。

《 Download:layerSlide



position:absoluteを指定した空要素はhoverイベントが起こらない

jQueryを触っていて、position:absoluteを指定した空の要素のhoverイベントを使用したかったのですが、IEだとhoverイベントが起こらない。

Firefox3とChromeではちゃんとhoverイベントは起こります。
いろいろとイジっていると、background-colorを指定することでhoverイベントが起こるようになった。

こんなこと知らないよ、ふつう…

私は都合上、見えない空要素に対してhoverイベントを起こしたかったのでopacityを0にしたが問題なくイベントは起こってくれる。

background-colorを指定する以外にbackground-imageを指定してもhoverイベントが起こる。
不思議なことに指定する画像は実際に存在する必要がない。

CSSで表すとこんな感じです。

#target{
   position:absolute;
   background-color:#000;
   /*background-image:url('/dummy.png');*/
   width:100px;
   height:100px;
   filter:alpha(opacity=0);
   -moz-opacity:0;
   opacity:0;
}

これで『#target』にカーソルを合わせるとhoverイベントが起こってくれる。

ちなみにrelativeでは問題ないがfixedだとheightがなくなるようなので同じように対処したほうが良いようだ。

Bookmarkletを作ってみた

私は普段、FirefoxとChromeでアンカーテキストを生成するBookmarkletを使っているんですが、試しにIE8にそのBookmarkletを追加して使用してみたらダイアログをブラウザがブロックしちゃうんですね。

そのためだけにそのブロックを解除するのも気が進まない。

普段使っているBookmarklet

javascript:(function(){function%20o(s){prompt('',s)}o('<a href="'+location.href+'" title="'+document.title+'">'+document.title+'</a>');})();

私的にはこれで十分なのだが敢えて、IEでも使えるBookmarkletを作ってみた。

テキストリンクを生成し表示するBookmarklet

javascript:(function(){function a(x,y){x.appendChild(y)}function y(a,b,c,d){with(a.style){color=b;fontSize="16px";background=c;border="1px solid #"+d}}var D=document,i="dlg__",s=c("div"),t=c("input"),b=c("input"),l=D.title,n="20px";if(D.getElementById(i)){return}function r(){D.body.removeChild(D.getElementById(i))}function c(x){return D.createElement(x)}s.id=i;y(s,"#000","#eee","ccc");with(s.style){position="fixed";zIndex="9999";top=n;left=n;textAlign="center";padding=n}with(t){type="text";readOnly=true;value='<a href="'+window.location+'" title="'+l+'">'+l+"</a>";style.width="200px";onclick=function(){this.select()};onkeydown=function(e){var k=e?e.which:event.keyCode;if(k==27||k==13){r()}}}y(t,"#333","#fff","999");b.type="button";b.value="close";y(b,"#eee","#999","666");b.style.marginTop="10px";b.onclick=function(e){r();e?e.stopPropagation():event.cancelBubble=true};a(s,t);a(s,c("br"));a(s,b);a(D.body,s);t.select()})();

たかがBookmarkletなのだが、Closeボタンを設置し、テキストボックスがFocusされるとテキストを選択状態にする。
その他、テキストボックスにフォーカスがある状態でEnterキーかEscキーを押下すると表示されたダイアログもどきが消えるようにしてある。

[Ctrl]+[C]を押してテキストをコピーした後、すぐに[Enter]を押してダイアログもどきを消す流れがイイ感じだと思ったんで実装してみた。


動作確認はIE8,Chrome,Firefox3で行ったが、IEだとGoogle系のページでは何故か意図した場所に表示されないことがあった。

問題としては該当のページに要素を追加することになるのでそのサイトのJavascriptを許可していないとダイアログもどきを閉じることが出来ないということ。

このBookmarkletの総文字数は933文字なので、古いIEだと508文字以上の場合正しく動作しないらしいので対象外となってしまいました。

まあ、そんな古いブラウザ使ってる人がBookmarkletに興味を示すとも思えんが...

Google Page Creatorが閉鎖される日も近いのか?

いよいよ Google Page Creator(以下GPC)が閉鎖される日も近いのだろうか?

GPCを覗くとこんな文字が
Your pages will be moved to Google Sites soon.

私が知らないだけで閉鎖される正確な日時はもうアナウンスされたのだろうか?
と、思ったらこちらでアナウンスされてました。

どうやら6月1日にサービス停止となるらしい。

マズい... 
GPCの代替えとなるサービスをまだ見つけていない。

GPCでサイトを開設している人のために、Redirect させるURLを設定することが[Learn more]で出来る。
また、アップロードしたすべてのファイルをzip形式で落とすことが出来るようになっている。

私の場合、Javascriptを使用した簡単なツールやここでの投稿で使用するサンプルなどをGPCにアップしているので、それらの置き場所を何処に移動させるかが問題。

GoogleはGooge Sitesに移行してほしいようだが、Google SitesはJavascriptを使用できないので代替えとは成り得ない。

SkyDriveにアップロードしたとしても、単なるHTMLファイルなら閲覧可能なファイルと認識してくれるのだが、Javascriptをページ(HTML)に埋め込むとjsファイルと同じ扱いでダウンロードのみ可能、つまりWebページとして閲覧することは出来なくなる。

なんでそんなこと知っているのか?
実際に試したからでございます。

GoogleにこだわるならGoogle App Engineを使用してアップロード & 公開出来ないか? と考えているところ。

出来そうな感じがするだけでまだ試していない。

どちらにしても、結果はまたここで報告します。

と言っても、誰もそんな使い方マネしないか...

IE8 CSS 2.1 対応ガイドがあるよ

microsoft がInternet Explorer 8 CSS 2.1 対応ガイドを配布していたので、配布先を示しておく。

サイトデザインをしてる人は見ておいた方がイイかも。

新しいブラウザが出るたびにCSS Hackネタが増えるけど、これもそのネタのタネになりそうな匂いがする…

サイト:


配布されている資料:

例えば、以下のようなことが書かれている。
以下 Internet Explorer 8 CSS 2.1 対応ガイド より抜粋

誤った CSS 構文に対しての動作について
<style type="text/css">
body{color: green;} /* 通常のセレクター指定 */
body,,p{color: red;} /* カンマが二つある誤った複数セレクター指定 */
body&p,p,body{color: red;} /* アンド記号を利用した誤った複数セレクター指定 */
</style>

Internet Explorer 8 と Internet Explorer 7 は誤った CSS 構文に対して以下のように動作します。

Internet Explorer 8 の処理 Internet Explorer 7 の処理
body {color: green;} body {color: green;} として処理 body {color: green;} として処理
body,,p {color: red;} 無効なセレクター指定として無視 body {color: red;} として処理
body&p,p,body {color: red;} 無効なセレクター指定として無視 body,p {color: red;} として処理
最終的に適用されるプロパティ body {color: green;} body {color: red;}




英語だけどテストページもあった。
「動作確認して下さい」ってことか。

Bloggerのタグの使い方を学んでTagCloudを改造する

Bloggerのテンプレートはその動作を読み取るのに苦労するんですが、少し勉強してタグの書き方を覚えたんで、以前Javascriptを使わずにTag Cloudにする方法を書いたんですが、それをもうちょっと改造してみた。

ちょっと説明すると、「includable」というタグはメソッドみたいなもので、「id='main'」のincludableタグはC#で言うところの「static void main」みたいなもの(厳密には違うけどイメージで)。

各ウィジェットに一つあるはずです。

<b:includable id='main'>
「id」属性をメソッド名のように使用している。

「var」というのは引数にあたる。例えば、
var='i'
なら、この変数を使用して
data:i.title
などのように使用する。

これら main 以外の inculudable タグの処理を「inculude」タグ(incudableじゃないよ)で使用する、という流れになる。

以下に記したものを例にすると、main 以外に「setAnc」という incudable タグがある。
<b:includable id='setAnc' var='label'>
<b:if cond='data:blog.url == data:label.url'>
<data:label.name/>
<b:else/>
<a expr:href='data:label.url' expr:title='data:label.count + " Posts in " + data:label.name'><data:label.name/></a>
</b:if>
</b:includable>

これを main 内の inculude タグで使用している。
<b:include data='label' name='setAnc'/>
name属性で使用するincludable タグのidを指定する。
name='setAnc'

data属性は引数で、ネーミングから分かるようにラベルを渡している。
data='label'

これらのことから
<b:include data='label' name='setAnc'/>
をコードっぽく書くと「setAnc(label)」みたいな。


そんな感じで改造したタグクラウドが以下になります。

Tag Cloud XML Sample

<b:widget id='Label1' locked='false' title='Tag Cloud' type='Label'>
<b:includable id='setAnc' var='label'>
<b:if cond='data:blog.url == data:label.url'>
<data:label.name/>
<b:else/>
<a expr:href='data:label.url' expr:title='data:label.count + " Posts in " + data:label.name'><data:label.name/></a>
</b:if>
</b:includable>
<b:includable id='main'>
<b:if cond='data:title'><h2><data:title/></h2></b:if>
<div class='widget-content'>
<span id='labelCloud'>
<b:loop values='data:labels' var='label'>
<b:if cond='data:label.count > 20'>
<span class='label_xxl'><b:include data='label' name='setAnc'/></span>
<b:else/>
<b:if cond='data:label.count > 12'>
<span class='label_xl'><b:include data='label' name='setAnc'/></span>
<b:else/>
<b:if cond='data:label.count > 7'>
<span class='label_l'><b:include data='label' name='setAnc'/></span>
<b:else/>
<b:if cond='data:label.count > 3'>
<span class='label_m'><b:include data='label' name='setAnc'/></span>
<b:else/>
<b:if cond='data:label.count > 1'>
<span class='label_s'><b:include data='label' name='setAnc'/></span>
<b:else/>
<span class='label_xs'><b:include data='label' name='setAnc'/></span>
</b:if></b:if></b:if></b:if></b:if>
</b:loop>
</span>
</div>
</b:includable>
</b:widget>


一応スタイルも貼っときます。

CSS Sample

#labelCloud span{
  line-height:1.1em;
  padding:1px;
}

.label_xs,
.label_xs a{font-size:10px;}
.label_xs a:link,
.label_xs a:visited{color:#666;}

.label_s,
.label_s a{font-size:12px;}
.label_s a:link,
.label_s a:visited{color:#808080;}

.label_m,
.label_m a{font-size:14px;}
.label_m a:link,
.label_m a:visited{color: #999;}

.label_l,
.label_l a{font-size:16px;}
.label_l a:link,
.label_l a:visited{color:#ccc;}

.label_xl,
.label_xl a{font-size:18px;}
.label_xl a:link,
.label_xl a:visited{color:#ddd;}

.label_xxl,
.label_xxl a{font-size:20px;}
.label_xxl a:link,
.label_xxl a:visited{color:#eee;}

参考:

Blogger - 保存ボタンを押してはいけません

Blogger レイアウト画面にて、Followers(読者)ウィジェットを追加したときの話。

このウィジェットを最初に知った時は「新手のスパム」ぐらいにしか思ってなくて放置していたんですが、素直に考えると、読者になってもらえるというのは嬉しいもので、読者が増えるとやりがいも増すのかな?と前向きに捉えてみた。

で、ブログに追加してみたんですが、デフォルトのままだと見た目がよろしくなかったので設定で色を変えてみることにしたんですが、色を変えて「これでOK」と、保存ボタンを押して確認のためにブログを表示するとあら不思議! 設定したはずの色が全てデフォルトの色に戻っているじゃあ~りませんか!

何故こうなるのか分からず、Cookieを保存しないようにしているのがマズイのか?とか、いろいろ調べいたらどうやらレイアウト画面右上辺りにある[保存]ボタンを押すと設定した色がリセットされてしまうようだ。

理由なんて分かりませ~ん。

というより、[保存]ボタンを押さなくても各ウィジェットの設定は各ウィジェットごとに保存されているので押す必要はないと。

そういう仕様なのは理解できた。

でも、ホントにレイアウトを変更したときには[保存]ボタンを押さないといけないワケで、その都度再設定することになるんですけど...

やっぱりウザい。これってやっぱりバグでしょ!

値型と参照型、ボックス化とボックス化解除 [C#]

基本的なことを今一度確認する。

値型(スタック)

  • 基本の組み込みデータ型
  • ユーザー定義の構造体を使用して変数が宣言されている場合
例:
int x = 10;

スタックの使用は効率的ですが、値型の有効期間は限られているため、複数のクラス間におけるデータ共有には適していません。


参照型(ヒープ)

  • クラス インスタンスや配列など
  • string データ型

例:
int[] num = new int[10]; // int型 10の配列

ガベージ コレクションが不要であると判断した時点でクリアされます。
参照型の宣言ではオーバーヘッドが大きくなりますが、他のクラスからアクセスできるという利点があります。




ボックス化とボックス化解除

ボックス化とは、値型を参照型に変換する処理をいいます。
つまり、ヒープ → スタック

例:boxing
int i = 123;
object o = (object)i;  // boxing
object o = i;  // Implicit boxing
string s = i.ToString(); // boxing


例:unboxing
object o = 123;
int i = (int)o;  // unboxing

ArrayList list = ArrayList();
int n = 123;  // n is a value type
list.Add(n); // n is boxing
n = (int)list[0]; // list[0] is unboxing


引用:値型と参照型 (Visual C# Express)より
簡単な代入と比べて、ボックス化およびボックス化解除は負荷の大きいプロセスです。値型をボックス化するときは、新しいオブジェクトを割り当てて構築する必要があります。ボックス化ほどではありませんが、ボックス化解除に必要なキャストも大きな負荷がかかります。


パフォーマンス
引用:パフォーマンス (C# プログラミング ガイド)より
System.Collections.ArrayList などの非ジェネリック コレクション クラスで、頻繁に値型をボックス化する必要がある状況では、値型の使用を回避するのが最も適しています。System.Collections.Generic.List<(Of <(T>)>) などのジェネリックコレクションを使用することで、値型のボックス化を回避できます。ボックス化とボックス化解除は、負荷の大きい処理です。値型をボックス化するときは、完全に新しいオブジェクトを作成する必要があります。これには、単純な参照割り当てと比較して最大 20 倍もの時間がかかることがあります。また、ボックス化を解除するときは、キャストのプロセスで代入の 4 倍の時間がかかることがあります。



参考:

IE8を使ってみた

IE8の正式版がダウンロードできるようになっていたので使ってみた。

Google、Yahooともに、対応の速さにびっくり。
どちらのサイトからもそれぞれのツールバーを付加するなどの最適化が施されたものがダウンロードできるようになっていた。

例えば、GoogleはこちらからIE8をダウンロード出来る。

Yahooもサイトに行けばすぐに見つけられる。

やはり、ポータルサイトにとって、IEへの対応が自サービスの利用状況に大きな影響を及ぼすのだろうと容易に推測できる。


microsoft によると、

引用:
テスト用のベンチマークの結果ではなく 、「実際のあなたがいつも見ているページをどれだけ速く表示することができるか。」

だそうで…
確かにそれが大事なことなんですが… 実際どうよ。

体感速度はIE7に比べれば確かに速くはなったが、Firefox3やChromeに比べれば、後出しのはずのIE8が優っているとは感じられなかった。

それでもIE7を使うぐらいなら、8 にした方がイイのは確かです。

InPrivate という Chorme で言うところの「シークレット・モード」のようなものや開発者ツールという Firebug もどき、さらに Windows Live Toolbar などというものがあったりと、いかにも「後出しです」的な要素が満載。

気になったのはアンカーテキストのアンダーラインの位置が何やらおかしい。これは表示が崩れる原因になるのでページデザインを行っている人にとってはまた、ウザいネタが増えることになってしまった。

ついでに「Office Live」も使用してみたが、これもGoogle Docs の対抗サービスか?というものなんですが、とりあえず IE8上で問題なく動作した。

結局、各サービスでしのぎを削っていることを体感した、ということになったが、それはユーザーにとっては結構なことではあるかもしれないが、これらに振り廻されないようにしたいと改めて感じた。

Google App Engine のWeb アプリのアップロードも Aptana ならボタン一発で出来る

以前、Google App Engine のWeb アプリ開発を Aptana で行う方法を書いたんですが、じゃあアップロードも出来るだろうと思い、ちょっとイジったら出来ちゃったんで書いときます。


まず、基本メニュー[実行] - [起動構成の実行]を選択し、実行ダイアログを表示します。

新しい起動構成を作成し、メインタブの「プロジェクト」と「メインモジュール」を以下のように書き換えます。
プロジェクト名は自身の環境に併せて適宜置き換えて下さい。



次に引数タブに切り替えて、引数を以下のように設定します。


これで起動構成の設定は終了。

作成した起動構成で実行すると、コンソールに以下のようにEmailとパスワードを求められるので入力します。


これでアップロード完了!

次回からは「.appcfg_cookies」に入力した情報が保存されるので、入力する必要はありません。

これからはボタン一発でアップロードもできちゃう。便利だねぇ。

Java project with Google App Engine

GAEでJavaが使えるようになった。


こんなリアルタイムでドキュメントが追加されるのを目撃した人も少ないだろう。


ドキュメント


GWT の存在は知っていたが、Google がここまで Java 好きとは知らんかった。いや、ニーズがあったってことか?

GAEを触りながらPythonを勉強中の私にとっては微妙なニュース。

今さら Java に乗り換えるか?

どっちがイイか誰か教えて... いや、決めてくれません? とか言ってみる。

C#をサポートしてくれないかな?
でももし次、サポートされるとしたら Ruby 辺りかな...

エイプリルフールのネタとして FORTRAN を新しくサポートしたってやってたのはイイね!



GAEのDashboardを開くと
Accept New Terms of Service(サービスの新しい利用規約に同意する?)
などと聞いてくる。


まあ、これは同意することにした。

「Interested in trying our new Java language support?」
これに関しては、とりあえずは無視した。

jQuery Color プラグインを拡張

個人的によく使う「jquery.color.js」に汎用性のあるメソッドを追加してリニューアルさせました。

内部的な動作は同じなので jquery.color.js と置き換えることが可能です。

Google App EngineのWebアプリ開発をAptanaで

Aptanaを使っているならそれを使わない手はないだろうと、AptanaでGAEのライブラリを参照したり出来ないかと自力で試行錯誤していたが上手くいかず…
webで情報収集したらあるじゃないですか!

たまにはやるねぇ、Google!
http://code.google.com/intl/ja/appengine/articles/eclipse.html

せっかくなので日本語でそのやり方を書いときます。
PythonのインストールとAptanaのプラグインであるPyDevが入っていることを前提に話を進めます。

Pydevプロジェクトの新規作成

まず、新規 Pydevプロジェクトを作成します。



Pythonのバージョンを 2.5 にします。



PYTHONPATH の設定

作成したプロジェクトのフォルダを右クリックすると表示される「プロパティー」を選択します。



ここで表示されるダイアログの「Pydev - PYTHONPATH」を選択します。


リストに以下の四つのフォルダパスを追加します。
  • C:\google_appengine
  • C:\google_appengine\lib\django
  • C:\google_appengine\lib\webob
  • C:\google_appengine\lib\yaml\lib
「google_appengine」フォルダまでのパスは適宜置き換えて下さい。




起動構成の設定

メニュー [実行] - [起動構成の実行]を選択し、ダイアログを表示する。



まず、新規の起動構成を作成する。
プロジェクト => helloworld(プロジェクト名)
メイン・モジュール => C:\google_appengine\dev_appserver.py
(dev_appserver.pyのフルパス)



引数の設定。
${project_loc}/src
--port=8080
プロジェクトフォルダ直下にファイルを置くなら「/src」の部分は削除して下さい。

これで設定は終了。


動作確認

とりあえず動けば何でもイイので「google_appengine」フォルダ直下にある「new_project_template」フォルダ内の以下の三つを「src」フォルダにコピーする。
  • app.yaml
  • main.py
  • index.yaml

app.yamlの中身を書き換える
application: helloworld(プロジェクト[フォルダ]名)
version: 1
runtime: python
api_version: 1

handlers:
- url: .*
script: main.py

後は設定した起動構成で実行。

http://localhost:8080/を開いて「Hello world!」と表示されれば成功!

GAEを使いたいのでPythonを一から学ぶ

現在の環境では出来ることに限界を感じてきて Googe App Engine (以下 GAE)を使ってみることにした。

GAE はサービス開始当初の熱が冷めた頃を見計らって一度は触ってみたいと思っていたので個人的には丁度いいサービスをチョイスしたかな?

この GAE をを使用するために Python を勉強することにした。

初めの一歩

まず、文法を学ぶために web から情報収集。
大して参考になるサイトはないので適当に「python」と検索して出てくるサイトから必要最低限の知識を得ることにする。
  • from,import
  • def、class
  • if文、for文
  • 配列、連想配列、タプル
取りあえず、この辺りを IDLE(Python GUI)を使って実際に触りながら動作の確認をする。

2~3時間も勉強すればソースを見ても「何やってるか全く分からん」ということはなくなるはず。

単なる「勉強」では退屈なので、それ以上の知識は実際にコードを書きながら学んでいくことにする。

ひたすらサンプルを眺める

実際のソースを見て学ぶ方が近道なので、見つけたサンプルをいくつか挙げる。

GAE Samples or Cook Book
google-app-engine-samples
http://code.google.com/p/google-app-engine-samples/



Google Cookbook - Google App Engine
http://appengine-cookbook.appspot.com/



GAEユーザー以外の方にも
Python Programming - Wikibooks
http://en.wikibooks.org/wiki/Python_Programming#Learning_to_program_in_Python



Python Recipes « ActiveState Code
http://code.activestate.com/recipes/langs/python/



Useless Python
http://www.uselesspython.com/



The Python Tutorial
http://docs.python.org/tutorial/index.html



自分で探すという人に
Google Directory
http://directory.google.com/Top/Computers/Programming/Languages/Python/FAQs,_Help,_and_Tutorials/



おまけ
The Standard Python Library
http://www.effbot.org/zone/librarybook-index.htm


実際に目を通すのはほんの一部に過ぎないでしょうが、これらを情報の一つとして蓄えておくことに損はないはず。

jQueryのdurationについて。normal なんて存在しない

jQueryのソースを見ていたらEffectで設定するspeed(duration)はこうなっていた。

jQuery:
speeds:{
 slow: 600,
 fast: 200,
 // Default speed
 _default: 400
}

jQuery内部ではこんな感じで使われている。
jQuery:
opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration :
   jQuery.fx.speeds[opt.duration] || jQuery.fx.speeds._default;

つまり、そもそも「normal」なんて存在しない
「fast」か「slow」以外の文字列を渡したらデフォルトに設定された 400 になるんじゃないか!

なんか騙された気分...

調べたついでにイジっておこう。
(function($) {
  $.extend($.fx.speeds, {
    fastest: 100,
    normal:450,
    latest: 1000
  });
})(jQuery);

「normal」を 450 にしたのは、ささやかな抵抗だよ。

Recent Posts