- ベストアンサー
imgとaudioをセットで重複なくランダム切替え
- HTMLのページにランダムに切り替える画像とMP3をセットで配置したいです。
- 画像をクリックするたびに、重複しないようにランダムに別の画像とMP3に切り替えたいです。
- 現在の方法では、切り替えまではできるものの、同じ画像やMP3が続いてしまうことがあります。
- みんなの回答 (8)
- 専門家の回答
質問者が選んだベストアンサー
<html> <スクリプト> $(function(){ var q9741487=function(img,snd,max) { this.id_img=img; this.id_snd=snd; this.table=new Array(max); this.maxNum=max; this.index=0; this.ctor(); } q9741487.prototype.listner=function(event) { event.data.update(); } q9741487.prototype.ctor=function() { /* デバッグ(不要なら削除を)*/ console.log("ctor"); for (var i=0;i<this.maxNum;i++) { this.table[i]=i+1; } // this.index=0; this.shuffle(-1); this.update(); $('#randomShow').click(this,this.listner); } q9741487.prototype.shuffle=function(first) { while(1) { for (var i=0;i<this.maxNum;i++) { var s=Math.floor(Math.random()*(this.maxNum)); var t=Math.floor(Math.random()*(this.maxNum)); var tmp=this.table[s];this.table[s]=this.table[t];this.table[t]=tmp; } /* 今現在再生中物が先頭に来たら、やり直す */ if (this.table[0]!=first) break; } /* デバッグ(不要なら削除を)*/ for (var i=0,out="";i<this.maxNum;i++) out+=this.table[i]+" ";console.log("shuffle="+out); } q9741487.prototype.update=function() { /* デバッグ(不要なら削除を)*/ console.log("index=" + this.index + " set=" + this.table[this.index]); $('#randomShow').attr('src', 'image/cat' + this.table[this.index] + '.png'); $('#randomSound').attr('src', 'sound/cat' + this.table[this.index] + '.mp3'); this.index++; if (this.index>this.maxNum-1) { this.shuffle(this.table[this.maxNum-1]); this.index=0; } } /* パラメタには、IMGと、AUDIOにつけたIDと、最大個数を書いてください */ var obj=new q9741487("randomShow","randomSound",9); }); </スクリプト> <body> <!-- 末尾のonclickはもはや、いりません --> <img src="image/cat1.png" id="randomShow"> <audio src="sound/cat1.mp3" id="randomSound" controls></audio> </body> </html> ------------------ scriptがOKWAVEの禁止ワードになることがあるので、 "スクリプト"って書いてますのでそこは、割愛してください。 また、他の表示物より先にこれが、実行されるとまずい場合は、 ロード完了後に、 var obj=new q9741487("randomShow","randomSound",9); こいつを実体化させればOKです。
その他の回答 (7)
- AsarKingChang
- ベストアンサー率46% (3467/7474)
- AsarKingChang
- ベストアンサー率46% (3467/7474)
>画像をクリックして次の画像・音のセットに切り替えるのが >いろいろとやってみたのですがうまくいきませんでした。。 onclick="location.reload(true);" だからです。リロードせず、自己書き換えにすればOKですよ。 それと、2セット目の先頭が、1セット目の最後と同じにならないようにする パッチも意味があるので、そこも、忘れないようになれば、 完成じゃないかとは思います。 ついでに言えば、再生をフックして再生が終わったら次に自動遷移? もありかもですが、そこまでは、今回言われてないので、 拡張してみてください。 あとで、自己書き換えのフック式で作りますので、お待ちを! "#ID" ←これ自体にクリックリスナーを入れればリロードしなくても 行けますんで。
- AsarKingChang
- ベストアンサー率46% (3467/7474)
ともあれ、やってみて、問題があれば、対応できるものは、 回答できると思うので、実際やってみて、問題点を 書いてもらえたらと思います!。 気楽にいきましょ!
- asciiz
- ベストアンサー率70% (6803/9674)
>同じものが続いてしまったりします。 それも含めて「乱数」というものですからねえ。 もし、「同じ数字が続かない乱数」というものがあったとすると、「サイコロの目(1~6)を当てる」というゲームで、1が出た場合、次は1以外に賭けると、1/5の確率で当てられることになります(本来は1/6であるはず)。 >9個終わったら、また最初からランダムに その方式では、1セット目「123456789」と2セット目「987654321」となった時に、同じ番号が続いてしまったりします。別の方法を考えなければいけません。 そしてそもそも大きく変えなければいけないのが、「前回(以前)の状態を記録しなければいけない」というところです。 現在は、毎回乱数で決めて終わり、なので何も記録する必要はありませんが、 HTTPでは前回の表示と今回の表示、そして次の表示の間に関連性はなく、リロードしたらJavaScript変数はすべて初期化されてしまいます。 データをサーバで保持するかクライアントで保持するか、というところなのですが、今回はクライアント側、すなわちブラウザのCookieを使ってみます。 生のCookieを扱うのは、次のページの通り少々面倒なのですが、 >サイトの情報を自由に処理! JavaScriptでcookieを扱う方法を徹底解説 >https://www.sejuku.net/blog/28696 ご質問にjqueryという文字も見えるので、jQuery.cookieを使ってみましょう。 >jQueryプラグイン「jquery.cookie.js」でcookieを簡単に扱う >https://www.tam-tam.co.jp/tipsnote/javascript/post3109.html 方式としては、超単純に、「前回とかぶったら乱数を引き直す」としてみました。 引けた乱数を クッキー'RDM'の値として保存し、次回に使います。 ということで、こんな感じになりました。 あ、Cookieはサーバ通信しないと更新されないので、ローカルhtml表示ではテストにならないことにご注意を。 ----以下HTML---- <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html lang="ja"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <script type="text/javascript" src="jquery.js"></script> <script type="text/javascript" src="jquery.cookie.js"></script> <script> $(function(){ var maxNum = 9; // 最大枚数 var prev = Number($.cookie('RDM')); // Cookie取り出し※Cookieは文字列 if (isNaN(prev)) prev = 0; // RDMが未定義または数字以外だったときNaNになる var rdm = prev; while (rdm == prev) {rdm = Math.floor(Math.random()*(maxNum))+1}; $.cookie('RDM', String(rdm)); // Cookie保存 $('#randomShow').attr('src', 'image/cat' + rdm + '.png'); $('#randomSound').attr('src', 'sound/cat' + rdm + '.mp3'); }); </script> </head> <body> <img src="image/cat1.png" id="randomShow" onclick="location.reload(true);"> <audio src="sound/cat1.mp3" id="randomSound" controls></audio> </body> </html>
- AsarKingChang
- ベストアンサー率46% (3467/7474)
onclick="location.reload(true);" ↑これだと、初期化されるので、 今のままのATTR書き換えメソッドのままで 関数にしてそれを呼ぶように変更してください。
補足
教えてもらったソースで最初の表示の時にランダムに変わるようにはできました。 画像をクリックして次の画像・音のセットに切り替えるのが いろいろとやってみたのですがうまくいきませんでした。。 ちゃんとした知識がなく作っているので基本的な質問かもしれませんが 教えていただけますでしょうか。
- AsarKingChang
- ベストアンサー率46% (3467/7474)
>9個ランダムに切り替わるまでは重複無しで >9個終わったら、また最初からランダムに並び変えるようにしたいです。 この時の「2セット目」では、配列番号8を維持させてください。 例として、 12345678 が初期配置だったとします。 2回目に再シャッフル後 81234567 が初期配置になったとすると、 「最後の番号が次のシャッフル時の先頭に来てしまうため、重複となる」 為です。 なので、2度目のシャッフル時に最後の位置をキープすることで 「それ以外をソートするため、希望の処理になる」 という具合です。
- AsarKingChang
- ベストアンサー率46% (3467/7474)
var maxNum = 9; // 最大枚数 var table=new Array(maxNum); for (var i=0;i<maxNum;i++) { table[i]=i+1; } for (var i=0;i<maxNum;i++) { var s=Math.floor(Math.random()*(maxNum)); var t=Math.floor(Math.random()*(maxNum)); var tmp=table[s];table[s]=table[t];table[t]=tmp; } /* 試しに画面に表示 */ for (var i=0;i<maxNum;i++) { document.write(table[i]); } ほい! 2種類くらいアルゴリズムはありますが、 シンプルなのはこの辺かな。。
お礼
ご丁寧な回答ありがとうございました。 すごく助かりました!!