jQuery:Inside Scroll

ページ内リンクをスムーズスクロールするjQueryプラグイン(Inside Scroll)を使わせていただいています。
ページ内リンクをクリックすると、シュルシュルとスムーズにスクロースする、アレです。
この機能はもちろん大変ありがたいですが、このページは、jQuery Easing Plugin のエフェクトの確認として秀逸です。
アレどうやって動くんだっけと疑問になったときは、ここで確認です。

ページ内リンクをスムーズスクロールするjQueryプラグイン(Inside Scroll)を使わせていただいています。
ページ内リンクをクリックすると、シュルシュルとスムーズにスクロースする、アレです。
この機能はもちろん大変ありがたいですが、このページは、jQuery Easing Plugin のエフェクトの確認として秀逸です。
アレどうやって動くんだっけと疑問になったときは、ここで確認です。

可変グリッドレイアウトjQueryプラグイン(jquery.vgrid.js)を某プロジェクトで使わせていただいています。
用途としては、固定幅のコンテンツなんで可変である必要はないんですが、リロードするたびにランダムに並び順が変わるという効果として使っています。
こういう固定幅のコンテンツの場合、再描画で各画像のポジション計算が狂って上の方に重なって表示される場合があります。(easingのパラメータの調整で出にくくすることもできますが、完全に出ないわけではありません)
たぶん、ウィンドウサイズが変わった場合の再描画では問題がないのでしょうから、ウィンドウサイズが変わらないような状況で使っている方が悪いのですが、たまにでも、画像が上の方に重なるといろいろ不都合が。(「表示上の問題なんです、F5キーを押してください」と言いたいところですが、見た目、いかにもなにか重大なバグが発生したように見えて、結構厳しいです)
初期化のあと、すぐ vgrefresh() してみたり、vgsort() してみたり、あと、一緒に動く JSがあるとそうなる頻度が上がるので、後ろの方にずらしてみたりしたんですが、なかなかこれといった対策もなく。
外そうかなと思った瞬間、パッと思いつきました。
#grid-content {
display:none;
display:block\9; /* IE7, IE8 */
overflow:hidden;
height:0;
margin-left:-1px;
}
「最初は消しときゃええやん」と。これでばっちりです。IEだけは消しとくとほんとに出てこなくなりましたので、出しときました。
作者さま、ありがとうございました。
追記:これだとページ内ジャンプのとき、やっぱり表示できないケースがありました。なので、上のIE対応は止めて、基本表示しないで別のタイミング(他のJSが動くとき)、これ(↓)を入れることにしました。
$("#grid-content").css('display', 'block');なんか泥縄式になっているような気がするのは気のせい?
再追記:これでもうまくいかないことがあったので、更に vgrefresh() を足しました。いよいよ泥縄(泥船)です。$("#grid-content").css('display', 'block'); $("#grid-content").vgrefresh();
ちなみにランダムの方は上流(コンテンツを準備する側)でやることにしました。
query_posts('category_name=top&posts_per_page=-1&orderby=rand');
posts_per_page=-1 は無制限、orderby=rand が並び順ランダムです。

長年の懸案だった、Thickboxが IEでうまく動かない件がやっと解決しました。それも自力で。エライね>自分。
懸案事項は次の2点。
本来は、どのような状況でもウィンドウは画面中央にきて、スクロールは背面の画面がスクロールするだけでウィンドウの位置は変わらないというのが正しい挙動です。もちろん、オフィシャルサイトのデモはそういう動きをしています。
それがどうしておかしくなるかというと、DOCTYPEの「標準モード」と「互換モード」の違いでした。
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
上が互換モードで、下が標準モードです。
Thickboxを互換モードで動かそうとすると、IEに限って、上のような現象に遭遇します。Firefoxとか Chromeは大丈夫なのが現象をわかりづらくしてますね。

PHPで複数ファイルのアップロードをなるべくスマートにやる方法はないかなぁと探し回ってたどり着いたのが、コレ。
自分的にはベストな解答です、たぶん。
詳しい使い方は「Ajax風にファイルをアップロードするjQueryプラグイン「Uploadify」の使い方」が超詳しいので、こちらを参照のこと。
以下は自分的にポイントとなったところ。
<script type="text/javascript">
$(document).ready(function() {
$("#uploadify").uploadify({
'uploader' : '<!--{$TPL_DIR}-->js/uploadify/uploadify.swf',
'script' : '<!--{$TPL_DIR}-->js/uploadify/uploadify.php?rand_no=<!--{$rndNo}-->',
'cancelImg' : '<!--{$TPL_DIR}-->js/uploadify/cancel.png',
'folder' : '<!--{$smarty.const.IMAGE_TEMP_URL}-->',
'queueID' : 'fileQueue',
'auto' : false,
'buttonText' : 'Select Files...',
'multi' : true
});
});
</script>
<div id="upload" style="display:none;">
<p style="margin:0;">画像ファイルを選択して、Uploadしてください。</p>
<div id="fileQueue"></div>
<input type="file" name="uploadify" id="uploadify" />
<div style="float:right;"><a href="javascript:fnModeSubmit('upload_image','image_key','sub_image'); tb_remove();">Close Window</a></p></div>
<p><a href="javascript:$('#uploadify').uploadifyUpload();">Upload Files</a> <a href="javascript:jQuery('#uploadify').uploadifyClearQueue()">Cancel All Uploads</a></p>
</div>
ちょっと見慣れない細工コードが入っているのは無視無視。たったこれだけでアップローダ定義完了。
<a href="#TB_inline?height=430&width=405&inlineId=upload&modal=true" title="Uploadify" class="thickbox">Uploadify</a>
こうすると本体のHTMLを汚さなくて済むからいいよね。で、Close Windowのとき、fnModeSubmit()といういままでアップロードボタンに割りつけていた関数を呼んでフックをかけると。
if (!empty($_FILES)) {
$tempFile = $_FILES['Filedata']['tmp_name'];
$targetPath = str_replace('//','/', $_SERVER['DOCUMENT_ROOT'] . $_REQUEST['folder'] . '/');
$targetFile = $targetPath . $_FILES['Filedata']['name'];
move_uploaded_file($tempFile,$targetFile);
$_FILES['Filedata']['tmp_name'] = $targetFile;
$fp = fopen($targetPath.$_REQUEST['rand_no'], "a");
fputs($fp, serialize($_FILES['Filedata'])."\n");
fclose($fp);
echo "1";
}
複数ファイルをまとめてアップロードすると、この PHPが回数分呼ばれることになる。
やってることは、渡されたファイルをフォルダに移して、なんのファイルを移したかファイルに記録しておくだけ。
このときのファイル名に例のランダム文字列を使ってる。
$no = 0;
$buf = @file(IMAGE_TEMP_DIR . $this->rndNo);
if ($buf) {
foreach ($buf as $e) {
$no++;
$key = "sub_image".$no;
$_FILES[$key] = unserialize($e);
$this->arrErr[$key] = $this->objUpFile->makeTempFile($key, IMAGE_RENAME);
}
@unlink(IMAGE_TEMP_DIR . $this->rndNo);
unset($_POST['rand_no']);
unset($this->rndNo);
}
EC-CUBEのコードにがっつり入り込んでいるのでわかりにくいけど、シリアライズされたファイルを読んで、アンシリアライズしたものを $_FILESにセットして、処理を継続しているだけ。終わったら、後始末しておく。
こんな感じで活用させていただいてます。ありがとう、Uploadify。

いつもお世話になっている Thickboxですが、画像の拡大表示くらいしか使っていなかったんですけど、よんどころない事情でインライン表示を使うことになって、いまさらながらのポイントもわかり、きっとあとで見ると思うので、メモメモ。
<a href="#TB_inline?height=xxx&width=xxx&inlineId=divID" class="thickbox">EXAMPLE</a> <a href="#TB_inline?height=xxx&width=xxx&inlineId=divID&modal=true" class="thickbox">EXAMPLE</a> <a href="http://url.com?keepThis=true&TB_iframe=true&height=xxx&width=xxx" title="xxx" class="thickbox">EXAMPLE</a> <a href="http://url.com?placeValuesBeforeTB_=savedValues&TB_iframe=true&height=xxx&width=xxx&modal=true" title="xxx" class="thickbox">EXAMPLE</a>
keepThis や placeValuesBeforeTB_ はなくてもへっちゃらみたいです。

例の CrossSlide がウザいから1回で止めてくれと、お客様じゃなくて社内から声が。あんたが入れろって言ったんじゃんか!と喉元まで出かかった言葉を呑み込んで、ハイハイと素直に答える優しい技術者。
でも、ソースを読んでも、止める方法が書いてない。
$.fn.crossSlideFreeze = function()
{
this.find('img').stop();
}
crossSlideFreezeという関数を呼べば止まるみたいだけど、どうやって呼べばいいんだ?
スライドに飽きたら[Stop]ボタンをユーザに押してもらうか。そんなバカな。
ということで、ある程度時間が経ったら止めることにしました。
(function($) {
$.fn.later = function(arg, fn) {
var self = this;
var timer = setTimeout(function() {
clearTimeout(timer);
self.each(fn);
}, arg);
return self;
};
})(jQuery);
こういうのを外部ファイル(例えば、jquery.later.js)に置いておいて、こんな風にします。
<script type="text/javascript" src="<?php echo $tmp; ?>/js/jquery.later.js"></script>
<script type="text/javascript">
jQuery(function($) {
$('#gallery1').later(80000, function() {
$(this).find('img').stop();
});
});
</script>
80秒経ったら、gallery1のすべての imgを止めてしまえ、です。フェードの途中でも有無を言わさず止まってしまって面白いです。

LavaLampと書いてもピンときませんよね。
グローバル・ナビゲーションで、マウスをもっていくと、ビヨーンと背景ブロックが追っかけてくるやつです。
こう書いてもきっとわかりませんね。

こんなやつです。使い方。
頭で指定しておくのはお決まり。ULにメニューを書いていきます。
下の例は、ULの背景にメニュー画像を置いて、その上を透過パネル(少し斜がかかったもの)が移動するようにしたものです。
メニュー画像を載せられればわかりやすいんだけど、今制作中のお客様のやつなんでね。
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
<script type="text/javascript" src="<?php echo $tmp; ?>/js/jquery.lavalamp.js"></script>
<script type="text/javascript" src="<?php echo $tmp; ?>/js/jquery.easing.1.1.js"></script>
<script type="text/javascript">
jQuery(function($) {
$("#nav1").lavaLamp(
{
fx: "backout",
speed: 700
}
);
});
</script>
<ul class="lavaLampNoImage" id="nav1">
<li id="nav1l1" class="current"><a href="#">MENU</a></li>
<li id="nav1l2"><a href="/party/">PARTY PLAN</a></li>
<li id="nav1l5"><a href="/access/">ACCESS</a></li>
<li id="nav1l6"><a href="/contact">CONTACT</a></li>
</ul>
.lavaLampNoImage {
background:#fff url(images/top-menu.png) no-repeat;
width: 898px;
height: 78px;
position: relative;
overflow: hidden;
padding:1px;
margin: 0;
border: none;
}
.lavaLampNoImage li {
margin:0;
padding:0;
float: left;
list-style: none;
}
.lavaLampNoImage li.back {
position: absolute;
z-index: 8;
height: 76px;
background-color:#fff;
opacity:0.2;
filter:alpha(opacity=20);
-ms-filter:"alpha( opacity=20 )";
}
.lavaLampNoImage li a {
position: relative;
z-index:10;
display:block;
overflow: hidden;
float: left;
height: 76px;
font-size:8px;
color:#C1955C !important;
text-decoration:none;
}
.lavaLampNoImage li a:hover, .lavaLampNoImage li a:active, .lavaLampNoImage li a:visited {
border:none;
}
#nav1l1, #nav1l1 a { width:152px; }
#nav1l2, #nav1l2 a { width:197px; margin-left:2px; }
#nav1l5, #nav1l5 a { width:121px; margin-left:2px; }
#nav1l6, #nav1l6 a { width:123px; margin-left:2px; }

大きな画像を上下左右にスライドさせて表示するプラグイン。
Ken Burns effectみたいにグイングインさせるのではなく、up、downにゆるゆると動かしてフェードみたいな感じが使いたくて。
使い方は割と簡単。
注意点は、jquery.js?ver=1.2.6 だと動かなかったこと。jQuery.isEmptyObject()を使っているので、1.4 over じゃないとダメみたいね。
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
<script type="text/javascript" src="<?php echo $tmp; ?>/js/jquery.cross-slide.js"></script>
<script type="text/javascript">
jQuery(function($) {
$('#gallery1').crossSlide(
{
speed: 15, //in px/sec
fade: 4 //in sec
},
[
{ src: '<?php echo $img; ?>/tops-1.jpg', dir: 'up' },
{ src: '<?php echo $img; ?>/tops-2.jpg', dir: 'down' },
{ src: '<?php echo $img; ?>/tops-3.jpg', dir: 'up' }
]
);
});
</script>
$tmp、$imgはそれぞれのディレクトリを適宜セットすること。
使いたいところに、#gallery1 を書いて、cssは width と height だけ指定しておけば、OK。
<div id="gallery1">Now Loading ...</div>
#gallery1 {
width:900px;
height:388px;
}
ウィンドウサイズより画像の方が小さかったり、fadeを大きくすると、すぐエラーで怒られたりするので、使い方がちょっと難しいけど、まぁ、お手軽です。

Nivo Slider はすばらしいライブラリなんですが、IE8(or IE7)で使うと、タイミングによってたまに『 ‘undefined’は null またはオブジェクトではありません。』というエラーが出ることがあります。
たまにというのはずいぶんと控えめな表現で、リロードしたりページ切替えしたりしていると、2、3回に1回くらいの頻度でこのエラーが出て、画像が切り替わらないということになります。(私の環境では)
FirefoxやChromeでは相当激しくそうやってもならないので、「IEってバカなのね」で済ましてもいいんですが、まだまだ50%以上のシェアをもつブラウザを無視すると、あとで痛い目にあうのはこっちなので、なんとか対処しなければ。
エラーが発生するのは、http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js の中なので、これを見てみるとって、パックされたソースを見るのは嫌!ということで、http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.js に置き変えてみたところ、ピタッとエラーが止まりました。
そういうことなんですね。

Nivo Slider という、jQueryを使ったかっちょいいスライダーです。
サムネイル画像の上にマウスをもっていくと(マウスオーバー)、メインの画像が切り替わるというのはよくやることですよね。
あれはただ、onMouseOver = “jQuery(’#main-img”).attr(’src’, ’sub-img-02.jpg’);” みたいなことをしてるだけで、切替え効果などは特に考えていないわけなんですが、このハデハデ GUI全盛の折にそれでいいのか、ということです。(ボクはシンプルな方が好きなんですけど)
で、Nivo Slider の出番です。
こんなわがままな要望をかなえてくれます。
実際に使うときの注意点は、こんなところ。
