2005年12月08日

effects.jsメモ

script.aculo.usのeffects.jsのエフェクトを使うとビジュアル効果のある表示、非表示が非常に手軽に行えるのだが困ったことがある。
Effect.BlindUp,Effect.BlindDownなどでエフェクト処理が終了しないうちに再びエフェクト処理を呼び出すとうまく動かない。
例えば1.5_rc5に同梱のサンプルのようにonclickなどのイベントハンドラで呼び出すサンプルでエフェクトを呼び出すリンクを連続してクリックすると最悪エラーになってしまう。

<div>DEMO:<a href="#" onclick="Effect.BlindUp('demo-div')">BlindUp</a>
<a href="#" onclick="Effect.BlindDown('demo-div')">BlindDown</a></div>
<div id="demo-div" style="float:left">
    要素<br />
    要素<br />
    要素
</div>
<div style="clear:both"> </div>
DEMO:BlindUp BlindDown(連続でクリックするとおかしくなる)
要素
要素
要素
 

エフェクト処理が要素のその時の状態を参照している場合具合が悪い。クリック連打なんてよくあることなので対応してそうなんだけどどうも未対応なので自前でごにょる事に。 思いつく回避策は、簡単な方法だとエフェクト中はイベントを呼び出すボタンやリンクを隠したり無効にする、とかイベントの呼び出し先でfalseを返す、くらいか。 クリックできるものがあるからいけないという安直な考えでイベントを呼び出すリンクを隠すことに。
具体的な方法はどうしようかと考えていると、はてなでscriptaculouについてのエントリ はてな技術発表会日記があるのを思い出し参考に。 コアエフェクトの項にあったエフェクトの開始や実行中、終了時に処理をフックできるオプション『beforeSetupInternal』『afterFinishInternal』が良さげなので オプションで指定してみた。

<div>TEST:<span id="blind_test">
    <a href="#" onclick="Effect.BlindUp('blind-div',{
        beforeStartInternal: function(){
            Element.hide($('blind_test'))
        },
        afterFinishInternal: function() {
            Element.show($('blind_test'))
        }
    });return false">BlindUp</a>
    <a href="#" onclick="Effect.BlindDown('list',{
        beforeStartInternal: function(){
            Element.hide($('blind_test'))
        },
        afterFinishInternal: function() {
            Element.show($('blind_test'))
        }
    });return false">BlindDown</a></span>
</div>
<div id="blind-div" style="float:left">
    要素<br />
    要素<br />
    要素
</div>
<div style="clear:both"> </div>
要素
要素
要素
 

あれ、 BlindUpがうまくいかない・・・。複合エフェクトには使えないのかとeffects.jsの中をあらためて見るとEffect.BlindDownは予めafterFinishInternalがセットしてあり、呼び出す際にafterFinishInternalを上書きしていてうまくいかなかった。 複合エフェクト側で既にフックされているオプションや処理をセットする時は同じものもセットする必要があるか。なのでEffect.BlindUpの処理から必要なトコを持ってきて

<div>TEST2:<span id="blind_test2">
    <a href="#" onclick="Effect.BlindUp('blind-div2',{
        beforeStartInternal: function(){
            Element.hide($('blind_test2'));
        },
        afterFinishInternal: function(effect) {
            Element.hide(effect.element);
            Element.undoClipping(effect.element);
            Element.show($('blind_test2'));
        }
    });return false">BlindUp</a>
    <a href="#" onclick="Effect.BlindDown('blind-div2',{
        beforeStartInternal: function(effect){
            Element.hide($('blind_test2'));
        },
        afterFinishInternal: function(effect) {
            Element.undoClipping(effect.element);
            effect.element.style.height = $('blind-div2').style.height;
            Element.show($('blind_test2'));
        }
    });return false">BlindDown</a></span>
<div id="blind-div2" style="float:left">
    要素<br />
    要素<br />
    要素
</div>
<div style="clear:both"> </div>
要素
要素
要素
 

として無事動作。
せっかくなのでBlindDown<=>BlindUpを一つのイベントハンドラで切り替えられるようにEffect.BlindUpとEffect.BlindDownの処理を1つに合体したエフェクトを作りました。

Effect.toggleBlind = function(element,button) {
    var element = $(element);
    var button = Object.extend({before:false,after:false},button || {});
    if (button.before && !button.after)
        button.after = button.before;
    if (!button.before && button.after)
        button.before = button.after;
    if (document.layers?element.clip.height:(element.offsetHeight||element.style.pixelHeight||0)) {
        Element.makeClipping(element);
        return new Effect.Scale(element, 0, 
            Object.extend({ scaleContent: false, 
                scaleX: false, 
                restoreAfterFinish: true,
                beforeStartInternal: function(effect){
                    if (button.before)
                        Element.hide(button.before);
                },
                afterFinishInternal: function(effect) { 
                    Element.hide(effect.element);
                    Element.undoClipping(effect.element);
                    if (button.after)
                        Element.show(button.after);
                } 
            }, arguments[2] || {})
        );
    }
    else {
        var oldHeight = element.style.height;
        var elementDimensions = Element.getDimensions(element);
        return new Effect.Scale(element, 100, 
            Object.extend({ scaleContent: false, 
                scaleX: false,
                scaleFrom: 0,
                scaleMode: {originalHeight: elementDimensions.height,
                	originalWidth: elementDimensions.width},
                restoreAfterFinish: true,
                beforeStartInternal: function(effect){
                    if (button.after)
                        Element.hide(button.after);
                },
                afterSetup: function(effect) {
                    Element.makeClipping(effect.element);
                    effect.element.style.height = "0px";
                    Element.show(effect.element); 
                },
                afterFinishInternal: function(effect) {
                    Element.undoClipping(effect.element);
                    effect.element.style.height = oldHeight;
                    if (button.before)
                        Element.show(button.before);
                }
            }, arguments[2] || {})
        );
    }
}
<div>Effect.toggleBlind:<a href="#" onclick="Effect.toggleBlind('blind-div3',{
    before:'toggle_up',
    after:'toggle_down'
},{duration:0.3}); return false"><span id="toggle_up">toggleBlindUp</span>
<span id="toggle_down" style="display:none">toggleBlindDown</span></a></div>
<div id="blind-div3" style="float:left">
    要素<br />
    要素<br />
    要素
</div>
<div style="clear:both"> </div>
要素
要素
要素
 

これだとエフェクト中は何も表示されませんがエフェクト中にもフックさせることができるので、それを利用してエフェクト中にも何か表示させることもできます。他の複合エフェクトでもオプションを設定すればかなり自由度の高い事をさせられそう。
script.aculo.us素晴らしい。

posted by q at 23:45 | Comment(17) | TrackBack(1) | 日記

トラックバック

この記事のトラックバックURL

切替Blindエフェクト その2
切替Blindエフェクト その2
from 僕のメモ帳 at 2005-12-26 23:46

コメント

qが、ネットでコアエフェクトなど持ってきて
最悪を対応しなかった。


Posted by BlogPetの生茶 at 2005年12月13日 09:09
おお、これはいいですね。

でも、クリックするところが消えてしまうのは勿体無い・・・。onclickイベントを一時的に消すというのはどうでしょう?
Posted by ぺぺっと at 2005年12月25日 23:32
k3g5udo0pqbn8wsx
gjtdc fcejrfcf
http://mincjwq.com
sdnbtnw nyxgdpe
http://kodrpnb.com
nbiukz jhpu
http://yrisgjmt.com
owucq blniw
http://oivuvtagxn.com
paiuz abuxugno
http://qmuboxexsv.com
rkpfrw seebbm
http://zanedpj.com
ktkziq itnc
http://jwffcckp.com
yrlmqjr egunm
http://buoxqjgzbkhg.com
mwjoua nbrkj
http://mfphwbdgzcm.com
bmtkvsu lvayr
http://ijvtsclwujx.com
mtllkl ofofpvhj
http://hwaaeke.com
obvig hzecwpup
http://keaylomcj.com
pngrmh jruhad
http://tgqhvl.com
mudjhdg rjkocmo
http://sxcfyjwmoqrm.com
budirh htbkpk
http://ckamjba.com
npvkk mtzsyn
http://xbnlgu.com
kkamad jzom
http://cruedjfolvr.com
kydzo ocop
http://ecipbb.com
gpydmze hcujirn
http://nvgzgk.com
jvrnxzh dzxln
http://bdvbbdisr.com
bfgnf tswzwg
http://jgwptjspls.com
ipghjb pehspmq
http://ctetjwichvdj.com
zyptqy ytrxo
http://eolrqhoei.com
dzvmsrv oeyqrusa
http://jwpnindryym.com
epfgv moptbc
http://xfqcyimyb.com
oquvk cteeh
http://rmfmvvu.com
wbcprlo xbaqajcw
http://kqsfxrajg.com
eenhxyb bunw
http://owbzgzsnuduw.com
vgxaf aqbyfok
http://liukkcxb.com
rowlcsc esvpjlkg
http://gtbhlxwq.com
ukvtyb otwkpdsr
http://ukxebo.com
stjzjp qiyqicqb
http://admcuhfln.com
qowiola wfbspgj
http://ersfsr.com
muiwou zsugusrm
http://jbsatcnmnbu.com
iejcl pzhmxmk
http://tfntcjn.com
ydqqjfz msszi
http://chtzosbhmeku.com
mgffv wdffpls
http://ojzinfcffv.com
nfslwm hdbp
http://ietmkfnlmb.com
mcixd ynocavjl
http://eacondwelm.com
oxyky sujp
http://zyzdpkmwn.com
ycycunt ldztf
http://lgjjrgnwsxn.com
xsdfg svlrkq
http://pkihvibl.com
mbveu oibai
http://ffcrixbqay.com
giletw oqmfp
http://goijbvve.com
wezvua frqzt
http://ooiupwcf.com
tdqicta thnjxv
http://bxhtzqguk.com
szqpo dqrodnv
http://henssybjytey.com
hoprss jtnty
http://fnabex.com
dvetzmt xomqp
http://lehmcjxi.com
czzghok uwxsse
http://vnvouvh.com
ldanfs ljkb
http://ngrzyncff.com
atacbb saitv
http://vzjxvtanyobs.com
lbujcf zskswws
http://hhqwkn.com
jahodj vehngpmy
http://owymeplpjaeb.com
ilqaami psnx
http://divkgzamild.com
doktju fhqqanz
http://elepbeipiaah.com
swiadwq nads
http://hkydia.com
shjuuq xkiqspko
http://vaamruld.com
agdcqyh kuipghhl
http://rbzrxewbrw.com
qwponlb mvrh
http://emsurokvv.com

僕のメモ帳
Posted by Joanne Walls at 2009年04月23日 04:37
今月もうすでに3人のお姉たまに買われた!
どのマOOコもみんなヌメヌメできもちーし!!

この調子だと今月60萬いくぞ!!
http://mlstarn.com/ornturn/
Posted by バラ組一代目 at 2010年08月13日 03:55
いくら10万だすって言われてもなぁ。
みなさんはストローでマン汁を飲めますか?

小生、今人生で一番悩んでおります。
http://quitblue.com/en/
Posted by ジョイ君 at 2010年08月24日 04:56
顔面騎乗入りました! 夢のマソコマスク(爆笑)

もうビラビラの感触でイキそうだったし(* ´Д`*)
まさか俺の童帝が売れるとわな。大切にとっとくもんだな(笑)
http://subekarazu.com/mkstktrz/
Posted by チロル君 at 2010年09月10日 05:06
ヌルンヌルンのマソチョに泡つけて挿入してみろって!

もう腰がとまんねぇし まじカオス!!

この一回で5万貰えるんだから二度カオスだな(爆笑)
Posted by ホイス at 2010年09月14日 13:14
ション便ぶっかけたり、顔面にティソポこすりつけたりしとけば
喜んで札束だしてくれるよww

勝手にイッテくれるしソープ君はやめれんな( -ω-)
Posted by 手羽先さん at 2010年09月14日 13:15
職なし道貞の俺が一夜で20萬ゲトったぞ(*・∀・)

要望通りにティヌポくわえさせてヴァイ_ブぶっ込んであげたら
痙攣してたよ(笑)とりあえず今月もこれでニート決定だわ( -ω-)
Posted by マカオの虫 at 2010年09月17日 15:49
こないだの奥様なんて俺にT−バック穿かしてさ、
はみ出た息子をチュぺチュペいわせて吸いまくってたよ(爆笑)

変 * 態 プレーの時はハブリいいしお勧めだぞww
ttp://mdern.net/en/
Posted by はめ八君 at 2010年09月21日 09:06
巨^^乳 ちゃんのパイオツに泡つけてパイ&ズリしたら、何発でもイケますな!
http://gorioyaji.net/so/
これで報酬頂いたら風=俗はありえないでしょ!
Posted by のりすけ at 2010年09月24日 16:03
あのベロ使いは腰くだけるかと思ったな!
ガン謝して報酬まで貰ってオレ最強でしょ!!
http://koreikura.net/beg/
Posted by つく丸 at 2010年09月28日 07:43
いっぱいクソニとか手マソやったら報酬 + 焼肉ゴチってくれたし!!!
正直働いてらんねぇわwww
http://mlstarn.com/ornturn/
Posted by つぶのり at 2010年10月01日 08:59
言われた通りに手とかマイサン突っ込むだけで7萬くれたし!!
もう無理。。もう2度と会社行きません!!
http://pupipo.net/deku/
Posted by ポンチョ at 2010年10月10日 15:55
7マソ払うからって剃られたし!!
しっかしデビュー戦でいきなりパイパソかよ!!
http://koreikura.net/beg/
Posted by オインゴ at 2010年10月14日 18:49
お風呂一緒に入るとガッツリ距離縮まんよ!!
ベット行った頃にはすでにカップル気分だもん!!
http://sersai.com/sntk/ajkrvll/
まっ彼女できた事ねぇけどな(爆笑)
Posted by 乱ボー at 2010年10月18日 14:23
しっかし金貰ってセレブとしまくってると、
金持ってそうな女はみんな変" "態に見えてくるなwww
http://sersai.com/en/
Posted by パスコ at 2010年10月23日 13:30

コメントを書く

お名前:

メールアドレス:

ホームページアドレス:

コメント: