スライドショーにフェイドイン+フェイドアウト
「スライドショー」で作成したスライドショーの機能。
画像を次々と見たい場合は余計なエフェクトなど必要無いと思うのですが、スライドショーにおいてはただ切り替わるだけではなんとなく味気ないように思えてきました。
そこで、fadeout + fadein のエフェクトを加える事に。
以前作ったサイトでは同様の効果を得るのに、prototype.js + scriptaculous.jsのライブラリを使っていました。
まだjqueryがあまり一般的ではなかった頃の事です。
fadeout + fadein は prototype.js + scriptaculous.jsを使えば簡単に実装することができたのです。
今回も移植するだけのことなので再びそれらのお世話になろうと思ったら、なんとwordpress3.5からはデフォルトのjsのライブラリからは除かれてしまったとのこと。
時代おくれなんですねぇ。今はjqueryというなにせ便利なものがあるし。
確かにjqueryを使えば簡単に出来ることなのですが、fadeout + fadeinぐらいならわざわざjqueryを読み込まなくとも自分でjavascriptを書けばいいかなと。
と、作った関数は以下のよう。
var fadei=100;
/*↑fadeoutする時の度合い、slideimg関数で参照するのでグローバル変数*/
function fadeout(target,num){
var opanum;
var doc=document;
var valinterv=parseInt(num);
var fadeId=setInterval(function(){
if(fadei>=0){
if(doc.getElementById(target).style.filters){/*IE9*/
doc.getElementById(target).style.filter="alpha(opacity="+fadei+")";
}else{/*Firefox,Chrome,Opera,Safari*/
opanum=fadei/100;
doc.getElementById(target).style.opacity=opanum;
}
fadei-=10;
}else{
fadei=100;
clearInterval(fadeId);
}
},valinterv);
}
function fadein(target,num){
var opanum;
var fadej=0;
var doc=document;
var valinterv=parseInt(num);
var fadeId=setInterval(function(){
if(fadej<=100){
if(doc.getElementById(target).style.filters){
doc.getElementById(target).style.filter="alpha(opacity="+fadej+")";
}else{
opanum=fadej/100;
doc.getElementById(target).style.opacity=opanum;
}
fadej+=10;
}else{
fadej=0;
clearInterval(fadeId);
}
},valinterv);
}
それぞれ引数は2つにしました。
エフェクトの対象の要素のidとfadeの速度。
fadeout関数の方の透明度の変数はslideimg関数から画像の切り替え+fadeinを始めるトリガーとして使うのでグローバル変数にしています。
透明度opacityの操作は、やはりIEだけ特殊で、しかもversionによっても異なります。
IEに関してはver.9以降で動けばいいやという感じです。
slideimg関数においての変更は、
function slideimg(intervalnum){
var doc=document;
var imgsrc;
var timenum=intervalnum;
fadeout("upimage","70");
imgsrc=img01.src;
var waitId=setInterval(function(){
if(fadei===100){
clearInterval(waitId);
/*先読みさせていた画像を表示*/
doc.getElementById("upimage").src =imgsrc;
fadein('upimage','70');
}
},100);
sumnum+=1;
/*切り替えの秒数と画像の情報の表示の更新*/
doc.getElementById("slctdown").innerHTML="last "+timenum+" seconds";
doc.getElementById("slidecount").innerHTML=sumnum+" : "+tarnum+" : "+imgsrc.substring(imgsrc.indexOf("20",20))+" : int."+timenum+" sec";
var ctdownnum=timenum;
var callnum=timenum*1000;
/*次の画像のための番号をつくります*/
var knum=0;
var tarflg;
var knum=0;
var tarflg;
while(knum<3){
tarflg=0;
var nowday=new Date();
var nowsecond=nowday.getSeconds();
/*乱数をよりユニークな数にするために秒数をかけてみました*/
var rand = Math.floor((Math.random()*100000000))*nowsecond;
tarnum=rand % imagesStr.length;
/*一度表示した画像番号にならないように配列tarlistのフラグで検証し、3回まで作り直します*/
if(tarlist[tarnum]==-1){
tarflg=1;
}
if(tarflg==0){break;}
knum+=1;
}
var lastflg=0;
/*3回作っても既出でない番号を作れなかったときはtarlistの中から未使用の番号を最後から順に探し出して使用します。*/
if(tarflg==1){
lastflg=1;
for(var i=tarlist.length-1;i>=0;i--){
if(tarlist[i]!=-1){
tarnum=i;
lastflg=2;
break;
}
}
}
/*それでも無い場合は全ての画像を表示したということなのでtarlistの値を全て1に初期化します*/
if(lastflg==1){
for(var i=0;i<tarlist.length;i++){
tarlist[i]=1;
}
}
tarlist.splice(tarnum,1,-1);
/*次の画像を先読みさせます*/
var tmpimg;
tmpimg=imagesStr[tarnum];
img01.src=tmpimg;
/*戻る表示の時のために表示した画像の番号を配列に格納していきます*/
pastimg.unshift(tarnum);
/*画像の履歴が50以上になったら配列の末から一つづつ削除します*/
if(pastimg.length>50){
var kuzu=pastimg.pop();
}
setTimeout("sldcountdown('"+ctdownnum+"')",1000);
timeId=setTimeout("slideimg('"+timenum+"')",callnum);
}
6~15行目が変更した所。
fadeout関数が終わるのを待って、画像の変更+fadein させるためにsetIntervalにてfadeoutの透明度の変数fadeiを調べさせています。
javascriptを学び始めた頃は、単純に
fadeout("upimage","70");
imgsrc=img01.src;
document.getElementById("upimage").src =imgsrc;
fadein('upimage','70');
のように書き連ねれば1番目の関数が終わったら次の行、その行の処理が終わったらまた次へと順々に処理が進んでいくものと思い込んでいました。
もちろん、それで間違ってはいないのだけど、setTimeoutやsetIntervalが入っていると事情が違ってきます。
始めのころはこれがわからなくて時間も手間も随分かかりました。
私のような他の方と一切情報交換のない、完全な独学状態だと陥りやすい落とし穴なのかもしれません。
setTimeoutで少し遅らせて処理させるとか、方法はいろいろありますがマシンの能力によっても多少処理が前後するようなので、とりあえずいろいろやってみて上のような方法で解決しています。
この点に関しては知らないだけでもっと正当法的な手法があるのかもしれません。
良い方法があれば教えてください。
このfadein + fadeout 機能、見てわかるように対象がID属性なので画像だけのものではありません。
関数として作っているので、ID属性を持つ<div>等のタグ全てに適応できます。
また、getElementById()をbodyに変えれば、それこそサイト全体をフェイドインさせることもできます。
ただし、その場合はcssにおいてvisibilityかopacityであらかじめbodyを消しておく必要があり、それをやるとサイトのSEOにおいて悪い影響が出る可能性があります。
私の場合は、サイドナビに使っています。
Post : 2013/04/07 18:31
Comments feed
Trackback URL : https://strix.main.jp/wp-trackback.php?p=33933