過去記事更新

2015年3月31日 
 
■モバイル版で見る

JavaScript「日替わりランダムリンク」を作ってみたよ!!!!

DAILY RANDOM LINK with Java Script

 ローペースながら記事数も増えてきたので、以前から考えていた「日替わりランダムリンク」を作ってみました。
 その名の通り用意したURL集団の中から、毎日ランダムな1つを選ぶというものです(日替わり画像にも使用可能です)。
  →探してみると、意外にそういう機能が見つからない。

 簡単に実装できるかと思いきやいろいろと難関があったりもしましたが、これについて詳しく書いていきます。
 一応Bloggerのユーザ向けですが、特に難しいことはしていないためJava Scriptさえ使えれば他のブログ等でも問題なく使えるはずです。
  ※勝手に使っていいよ!



*もくじ:
▼特徴~概要(↓)

▼実装例@Blogger

▼実装例@汎用日替わり画像の設定例)

▼検証スクリプト(精度検証/結果予測用)

▼原理

(追記)
▼日替わり背景を設定してみたよ@2019年7月


»関連記事:
■解説記事いろいろ■Bloggerカスタマイズ



Daily Random Link (Java Script)


◇特徴 ▲目次
(機能面)
・毎日飛び先が変わる
・その日のうちは同じ飛び先になる
・飛び先は任意の個数を指定できる(十でも千でもいい)
・後述の検証スクリプトにより1年分の結果を予測可能

(実装面)
・ブラウザ上で「ショートカットをコピー」してもどこに飛ぶかは分からない(ようにした)
・スクリプトが無効の環境でも特定ページに飛ばせる
・遷移方法をテキストリンクやボタンにもできる(当然か)
・「日替わりランダム画像」(→クリックで特定記事へリンク)とかも可能


◇概要 ▲目次
・日付から一意の鍵数字を生成
・振幅1の鋸歯状波により0~1レンジに変換
・対象総数で増幅し、鍵数字に対応する番号を決定する
(わざと小難しくしてみた)



◇実装例@Blogger ▲目次

 ※Blogger以外の汎用版▼下のほうで。

 ソースはこちら(だいたい調整済)。
<b:if cond='data:blog.url == data:blog.homepageUrl'>

 <div style='border:1px solid magenta;line-height:1.3em;width:80%;padding:5px 5px 5px 1em;margin-left:2em;'>

 <form>
   <input onclick='MOVE()' type='button' value='DAILY RANDOM LINK'/>
  </form>

 <A onclick='MOVE(); return false;'
   expr:href='data:blog.homepageUrl'
   style='font-size:x-large; color:magenta;'>■日替わりランダムリンクだよ!</A>(Daily Random Link)

 </div>


 <script type='text/javascript'>
  URL_GROUP = [
   '15/01/sample1','15/02/sample2','15/03/sample3','15/04/sample4',
   '11/01/sample5','12/02/sample6','13/03/sample7','14/04/sample8'
  ];

  date = new Date();
  DAILY_KEY = ( Math.sqrt(date.getMonth()+0.1) + Math.sqrt(date.getDate()-0.1) ) * 1.94;
  DAILY_TARGET = Math.floor( DAILY_KEY % 1 * URL_GROUP.length );
  DAILY_URL = '<data:blog.canonicalHomepageUrl/>20' + URL_GROUP[DAILY_TARGET] + '.html';

  function MOVE(event){
   location.href = DAILY_URL;
  }

 </script>

</b:if>

»HTMLテストサンプル(Download用)@2019.7
https://drive.google.com/open?id=1eGljN1cNUm4smCcnbVnsaWdYcZAzN7y9

 実行イメージはこんな感じ。
  →実際の動作は▼下のほうで。
 とりあえずフォーム(リンクボタン)とテキストリンクを用意したので、好みで適当にいじってください。


*Blogger構文について
 ソースのうち、この色の文字Blogger専用の独自構文です。
 なんとなく分かると思いますが、この場合はトップページにだけ表示する<b:if>で囲っています(サンプルファイルでは外しています)。

 ブラウザで上記サンプルを表示してリンクをクリックしてみると、だいたい以下のようなページに飛ぶはずです。
file:///~~^/<data:blog.canonicalHomepageUrl/>2015/01/sample1.html

 これは、URL_GROUPから選ばれたものに対して、先頭に固有のブログアドレス + 数字で「20」、末尾に「.html」が足されたものです。
 ちなみにBloggerの記事URLは「ブログごとのアドレス/年/月/記事ごとのアドレス.html」という形式です。
 なんとなくURL集団は1文字でも少ないほうがよかろうと思ったので、上記の例では年の下2ケタ~記事ごとのアドレスを整形するやり方にしています。

 これを実際にBlogger上のテンプレートに書いた場合は、以下のような完全なURLにリンクされます。
http://(自分のブログID).blogspot.com/2015/01/sample1.html

 ちなみにマウスでリンクをポイントした時点では、ブラウザのステータスバーに表示されるリンク先がトップページになっているというのがささやかなドヤポイントです。



 当初は基本動作を抑止するというpreventDefault()というのを使っていましたが、どうも環境によって(?)うまく動作しなかったので外しました。
 とりあえず return false; と書いてあれば、デフォルトのhref(スクリプト無効環境用)を無視しつつの onclick=安定しているようなのでこちらのほうがいいかなと。
  ※動けばいいんだよ!


(追記)
 当初、飛び先URLとして<data:blog.homepageUrl/>を使っていましたが、これだとURL末尾に?m=1が付くモバイル版で問題になることが分かったため、正規URL(canonical URL)である<data:blog.canonicalHomepageUrl/>に修正しました。
  →参考:http://www.kuribo.info/2012/03/blogger-blogspotjp.html
 ついでに、モバイル版ではウィジェットにmobile='yes'を付けておかないと表示されないことを忘れていましたが、現在は表示されるはずです(手元で確認済)。
 まったく同じミスをFC2拍手(解説は未投稿)の実装時にもやっていたので、まったく成長していない……と思いきや気づいてすぐ修正できたのでよかったなと。

 
◇実装例@汎用 ▲目次
 上記の例から、Blogger構文や装飾を排除して汎用化したものがこちら。
 ブログ等のJavaスクリプトが動く箇所に貼り付けるだけで動作します。
Bloggerなら「レイアウト」のHTML/JavaScriptガジェットとか)

 あとはこの色の部分を自分用に書き換えてください。
<div>

  <form><input onclick='MOVE()' type='button' value='DAILY RANDOM LINK'/></form>

 <a href='http://--Default-Link--.com/' onclick='MOVE(); return false;'>■日替わりランダムリンクだよ!</a>

 <IMG id='DRL_IMG'
   src='https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgqNIl4aYl-tNdgguk0ksRzRGO3RT_DZOMJzWQwo0WIcd6B91FhIy3mqah3qK4CHG9uJgJGOHR7hV3kDDvJNhzq4JO_5HEBVy71fjC2o4_5RDQ3MnA3j91ldjFy8bfLl32-LhAmEUsEmfo/s220/20131026-thum.jpg' />

</div>


<script type='text/javascript'>
 URL_GROUP = [
//(例)
//  'http://--Your-Blog-Address--/sample1.html',
//  'http://--Your-Blog-Address--/sample2.html',
//  'http://--Your-Blog-Address--/sample3.html',

  'https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiGFNZ7lc7yH-RFDCOb2MAbpaoH768Fq6zPCs1HlfN2DSRYUDa6n7NkqaJfZu-Nn6d_MrTakjmDGV00rW0zljvBhPtjUMItxNcIoEm1yvUI1C_4uaQRlot9Nc8I56M4QpS44KW78uM2CdaU/s300/20150331+Daily+Random+Link.jpg',
  'https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiX__hWEWtaSmDniZ3wpy1nthYblK4TXjF0ToIeBfNyMgEanzpuZRxL_YdyN4AwS3TRInFR_TAPFUY_c6MFLet_AC8ggpF2gh0NsK79NVcuRMofsxXXs_RM-tSIVzJYpexuQBeilaGXgie7/s300/20140711_PS3(80G)cleaning_a9a_Done.jpg',
  'https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj_lVXnNlfVfr23wjbSaSZKXZ6xBjj8pfJKMKwADF0GFM04mvxuEngSMWC9pWx5KmRfdDq9FXo49zuEvKENre3_J4gxrTzg_CTatluEVZf2jWM_dXP4cFPddNeRA9TB2YXalOoo7wccoBk/s300/DARK_SOULS_Platinum.jpg'

 ];

 date = new Date();
 DAILY_KEY = ( Math.sqrt(date.getMonth()+0.1) + Math.sqrt(date.getDate()-0.1) ) * 1.94;
 DAILY_TARGET = Math.floor( DAILY_KEY % 1 * URL_GROUP.length );
 DAILY_URL = URL_GROUP[DAILY_TARGET];

 function MOVE(event){
  location.href = DAILY_URL;
 }

 document.getElementById('DRL_IMG').setAttribute('src', DAILY_URL);

</script>

»HTMLテストサンプル(Download用)@2019.7
https://drive.google.com/open?id=1CMB6szOTzpFTgS2iwxe-VvkTd6Cq8Hz3

微調整@2019/7/20(Blogger版も同様):
・変数名が簡素すぎたのを調整、ついでにvar宣言に変更
・変数の中身が分かるようにした
・サンプル画像や奥付のURLをhttpsに変更

 ここでは、別パターンとして日替わりランダム画像も表示させています。
 この例では、IMGタグの中で……
  http://~~/20131026-thum.jpg
 ……の画像を指定していますが、実際にはURL_GROUP内のいずれかが表示されます。
 なおページ読み込み中は最初に指定した画像がわずかに表示されるため、最初からsrcを指定せずに <IMG id='DRL_IMG' /> と書いてしまっても構いません。
 一応、src= に指定してあるほうはスクリプトが動かない環境で表示するためのデフォ画像という意味合いがありますが、まああっても無くても動くので好みで変えてみてください。

 また、この例では対象URLはベタ打ちにしています。
 URLに共通部分が少ないとか、外部リンク等で飛び先アドレスが不統一のケースではこうなるかなと。
 その他の細かい最適化については、Blogger向けの例のように各ブログ等の独自タグも使うといいでしょう。

 なおBloggerであっても、レイアウト>ガジェットを追加>HTML/JavaScriptのスペースでは独自タグが動作しない(っぽい)ので、上記の汎用版のような書き方にする必要があります。
 テンプレートの編集であれば独自タグを使ってより柔軟に記述できますが、不用意に書き換えると最悪、ブログが再起不能になりかねないので注意してください。
  ※無理しないほうがいいよ!

 
*実際の動作:
»ボタン

»リンク
■日替わりランダムリンクだよ!
onclickなので、長押しメニュー/右クリックメニューだと動作しない可能性があります

»そのまま表示

(本日の画像)



 上記のサンプルHTMLからURL_GROUPのみを十種の画像URLに書き換えて実際に動作させています。
 再読込しても画像/飛び先は変わりませんが、翌日以降は十種類の中から再抽選されます。
 Java ScriptがOFFの環境ではトップページへのリンク(画像はファビコンの米印)となるはずです。(たぶん)

*検証スクリプトによる予測:
(←押すと表示)


▲CLOSE
 こちらも▼下記の検証スクリプトの内容をそのまま動作させています。
 同じくURL_GROUPを書き換えていますが、URLは短縮してファイル名のみにしています。
(個数と順番が同じであればURLを削っても同じ結果になります)

 ここで一番上のURL(きょうの分)と、動作イメージのリンク先/表示されている画像が一致していれば正常動作です。
 自分も毎日見るみたいな徹底的な検証はしていませんが、この出力を見ることで明日以降の結果予測が可能になります。

 この例では十種類の画像を対象としているため、単純に考えれば十分の一だし10日に一度くらいは重複があってもおかしくはないはずですが、ざっと見たところ2日続けて同じものが選ばれている箇所がほぼ無いようだし精度的にも問題無さそうです。




verifying script


◇検証スクリプト ▲目次
 「日替わり」ということは、つまり1日ごとに結果が変わるということなので実装後のテストが困難です。
 そこで、予めどの日付に何が出るかを予測する検証スクリプトを作っておきました。

 実際の出力例▲上記の動作イメージで確認できます。

 ダウンロードはこちらから。
◇Daily Random Link Checker
https://drive.google.com/file/d/0B2cIp72eMMBUVmxaczFvNlYxd3c/view?usp=sharing
(リンク共有@Googleドライブ)

 とりあえず、これをそのままブラウザで開くと1/1~12/31の結果が表示されます。
  →2/30とか6/31とかあるけど気にしてはいけない。
 動作イメージはこんな感じ。


 動作が確認できたら、上記ファイルをテキストエディタ等で開いて適宜書き換えてみてください。

*要点
・デフォルトではtest0.html ~ test499.html500件が対象(訂正)
・日付(左列)は1月1日=101、12月31日=1231(MMDD)で表示
・表の一番上にはきょうの分が表示される
IDが内部的な番号で、URLが実際の飛び先
・Excel等にテキスト形式で貼り付けて使用可能


*書き換えポイント
MAX=500;の数字を変えると最大数が変わる
i=0;の後のfor文が計算部分
document.write以降が表示部分
良かれと思って月初に見出しを入れているけど、ジャマなら// 月毎整形の後のdocument.writeを消すかコメントアウトすればOK
 *
参考用として正弦波版もあり(コメントアウトされています)
key=Math.floor あたりが核心部なので、いじってみるのも一興


 よく分からないという方は、とりあえず15行目 // 実際の入力例付近にある/**/を消して保存し、ブラウザを再読み込みしてみてください。
 すると結果がtest1.htmltest8.htmlのみになるはずです。
 あとは、サンプルを参考にtest1.htmlの部分を書き換えるだけです。

 一応基本だけ書いておきます。
URL_GROUP = [ ]; の内側に対象のアドレスを入れる
・半角スペース(全角はだめ)、タブ、改行は自由に入れていい
・アドレスの両端は半角の ' (シングルクォート)または " (ダブルクォート)で囲む
・囲んだ文字は , (カンマ)で区切る
"……","……","……"と繋げていった最後はカンマを入れなくていい
 →ただ、最後にカンマがあってもエラーにはならない(?)みたい。
・正しく書き換えて保存してからブラウザで見ると「対象URL ◆件」の部分に総数が出る

 ここでうまく行っているようなら、書き換えた対象URLをそのまま上記スクリプトにコピーし、ローカルやサイト上でも同じ結果になっているか確認してみてください。
 なお注意点として、こういったスクリプトは構文エラーを察知しづらいため、ほんのちょっとしたミスでスクリプト全体がまったく動かなくなることが多々あります。
 このため正常動作しているバックアップを用意したり、わずかでも書き換えたらすぐ動作確認するのがコツです。



 とりあえず今のところ、ローカルでの予測結果と◆トップページからのリンク先が一☆致していたのでまあ信用できるかなと思います。
 ただ、実際の運用では定期的に対象URLを追加していく(というか、したくなる)かと思います。
 対象の総数が変われば予測結果も激変するので、その際にも参考になるはず。


(余談)
 この検証スクリプトの真の目的は、結果予測そのものではなく精度の検証です。
 現行のものになるまでいろいろ試しましたが、当初はひどいものでした。
 初期段階ではkeyの部分に101~1231をそのまま使用していたのですが、これだと1月と11月、2月と12月の結果がまったく同じだとか、3ヶ月くらいの周期で同じ内容が繰り返されているというケースがありました。


(アカン)

 これは、ブラウザ上で任意の対象URLをCtrl+Fでページ内検索し、Enterを連打してみると分かります(伝わるかな)。
 興味のある方は、for文の中にあるsin版のコメントを外し、その前の行に key=days[i]; を入れてみてください。
 一見そこそこ数字がバラけていますが、よく見ると1/1~1/21と8/11~8/31の結果が完全に一致しているのが分かるはずです。
 これではよろしくないぞということで振幅だけではなく横軸の取り方も複雑にすることで対応してみたのですが、そのあたりは次項で。

 そもそも365日程度の想定な上に定期的な対象URL追加がある(だろう)ことも考えると超高精度な乱数は必要ないのですが、たとえば鍵数字の生成に「年」も加える等でいろいろアレンジしてみるのも面白いかと思います。



◇原理/解説 ▲目次
 簡潔に言うと、このスクリプトは「日付ごとに異なる鍵数字でグループから呼び出す」ものです。
 ソースで言うとkey鍵数字で、これを元に選ばれたものがDAILY_TARGETになります。
  →サンプルのほうではkey→DAILY_KEYに名前を変えました。
 さほどJava Scriptにも詳しくないしおそらく後で自分が見返しても分からないということもあるため、動作原理について詳しく書いておきます。
 ちょっと横道(余談)もありますが、そのあたりも参考までに。


*自力でランダム関数を作る
 最初にネットを色々見て回ったところ、Java Scriptによる簡易的なランダムリンクは、ほとんどでMath.random()関数が使われていました。
 これはランダムな0~1(正確には1に非常に近い1未満まで)の数字を返す非常に高精度なもので、これに対象URLの総数を掛ける(+端数を切り捨てる)ことで簡単にランダムリンクを作ることができます。
 ただし、この関数では実行ごとにランダムな値を返すため、「日替わり」という用途には向かないことが分かりました。
 まあクリックごとにランダムに飛ばす……というのもシンプルでいいんですがそれだとなんか飽きそうというのと、ぶっちゃけて言うと「日替わり」のほうが集客が望めそう……かなあ、という狙いがありました。


 そんなわけで、どうやら一意な日付キーを0~1の範囲に変換すればよさそうだと考えて、最初に思いついたのが正弦波(サイン波)でした。
 y = sin(x)は波状の曲線なので、にどんな数字を入れようが必ず-1~1を返します。
 この式について振幅を半分にして半分ずらすと、0~1の範囲になるため扱いやすくなります。
  →波の上から下までのタテの長さが振幅。
 これを数式で書くと y = 0.5 * sin(x) + 0.5 となります。

 実際には0~1ではなく0~対象URLの総数にしたいので一般化する必要があります。
 といっても簡単で、ずらす長さを変えればいいだけです。
 「対象URLの総数」lengthとすると、求める式は
   y = length / 2 * sin(x) + length / 2
 となります。
 対象総数が100であれば、 y = 50 * sin(x) + 50 です。


 これをにするとこんな感じ。
正弦波(サイン波)@日替わりランダムリンク

 横軸がx(日付ごとに異なるキー)で、それぞれにy(0~100の数字)が選ばれていることが分かります。
 なおMath.floorというのは端数を切り捨てて整数にする関数です。

 上記の検証スクリプトではコメントアウトされていますが、ここまでの流れをスクリプトで書くとこうなります。
DAILY_TARGET[i] = Math.floor( Math.sin(key) * URL_GROUP.length/2 + URL_GROUP.length/2 );


 この時点でよーしできたーと思いましたが、いろいろ検証していくと精度的な問題が見えてきました。
 これは正弦波が波型であるためで、どうしても波の頂上部と底部に出力が集まりやすいのです。
 上記の例で言えば0付近、100付近は非常に出やすいものの50付近が極端に少ないという結果が見られました。
 これは根本的な問題で、二乗してみたりの取り方を工夫してみたりしても解消することができませんでした。

 そこで思い出したのが、 はるか昔に 学校で習った三角波でした。


*ノコギリ波を応用する
 三角波というのは、文字通り三角形のような波形を描くもので、曲線である正弦波を直線にしたようなものです。
 代表的なものは /\/\/\/ ……というのようなジグザグ直線ですね。

 今回のスクリプトは、より使い勝手が良さそうなのこぎり波を採用しました。
  ※三角波の一種だよ!
 これは /|/|/|/ ……という形の直線で、その名の通りのこぎりのような形です。
  →◆wikipedia「のこぎり波」
 この波形はムラが無いため、さえうまく取れば結果が偏りにくくなることが期待できます。

 なお、こういった三角波を通常の数式で表すのはとんでもなく難しい(収束する近似式で表される)のですが、実際には「~~が偶数の場合は~~、奇数なら~~」のような条件文を許容すればかなり簡単に記述できます。
 具体的には、振幅1、周期1ののこぎり波「 y は x を 1 で割った余り」と表現できます。
 これはプログラム的に y = x % 1 と書くだけで実現できます。
 この式もやはりにどんな数字を入れようが0~約1の範囲になります。

 あとは、先ほどの正弦波と同じように振幅に総数を掛けるだけです。
 これをスクリプトで書いているのがこの部分。
DAILY_TARGET = Math.floor( key % 1 * URL_GROUP.length );


 この増幅のこぎり波を実際に計算し、結果をグラフ化したのがこちら。
鋸歯状波(のこぎり波)@日替わりランダムリンク

 この例では(横軸)を1~100としてテストしています。
 パッと見ても正弦波に比べて偏りが無くなっているのが分かるかなと。

 ここでに当たる部分が i * 0.194 となっているのは周期調整を行っているためです。
 見た目で言うとのこぎりの刃1つごとの長さ(横幅)を変えています。
 実際に y = x % 1 のままで0~100を代入すれば必ず1で割りきれる=すべてゼロになるだけなので、微妙に余りが出るようにずらす必要があるわけです。

 「1」からズレてさえいれば1.1でも0.3でも大丈夫ですが194なのはまあ落款みたいなものです。
  ※いくよってことだよ!
 ここは好きな数字に変えても問題ありませんが、当然0.5のようなキリの良い数字、百以上のような大きすぎる数字なんかではあまり意味がありません。
 もっと言えば、小数点以下を2ケタ(かそれ以上)程度にしたほうが精度が期待できるかなと思います。
 なお最終的な採用案は1.94としていますが、これは下記の横軸対策も考慮して決定したものです。


*日付キーを複雑かつ狭い範囲に取る
 いろいろやって判明したのが、ある周期で似た結果になりがちという問題でした。
 これは▲検証スクリプトにも書いた通りで、実際に1年間の結果を出してみて初めて分かったことでした。

 原因としては、日付キーの元になる数字がMMDDの3~4ケタだったためです。
 この場合、日付ごとに101(1/1)から1231(12/31)となり十倍以上の差がありました。
 せっかくのこぎりの傾きを0.01みたいな繊細さで調整しているのに、そこに100~1000のような大きすぎる数字を掛けあわせれば台無しになるのも当然だったわけです。
 そんなわけで、M(月)、D(日)という2つの数字からできるだけ複雑で、かつ短い範囲にまとまるキーを生成するという方向で考えていきました。

 いろいろ試した結果、行き着いたのが「”月+0.1”の平方根と”日-0.1”の平方根の和」です。
  ※自信作だよ!
 スクリプトではこの部分です。
DAILY_KEY = ( Math.sqrt( date.getMonth()+0.1)
+ Math.sqrt( date.getDate()-0.1) ) * 1.94;


 まず適当に数字を小さくするために平方根を使いつつ、1、4、9で自然数にならないように0.1だけずらしています。
 ついでに11月1日と1月11日のようなパターンも考慮して月はプラス、日はマイナスとしました。
 ちなみに、Java ScriptDate変数において月は0~11(日は1~31)なので、意図的に月はマイナスではなくプラスのほうにしています。



 以上のように振幅/周期/キーを設定した結果、今のところ満足できる精度になったかなと思います。
 改めて初期のものと比較するとこのくらい違います。(ドヤァ……)

 試しに使って頂くか、あるいは何かを作る際の参考になれば幸いです。



◇日替わり背景について ▲目次
 ちょっとした応用例として、日替わりランダム背景スクリプトを制作してみました。
 こちらは2019年7月より当ブログに設定しています。
 今のところ百種類くらいの画像(いずれもフリー素材)が毎日ランダムで抽選されるようになっています。

 ソースはこんな感じで、基本動作は上記のものと変わりません。
<body style="bgcolor:lightgray;background-repeat:repeat-x;">

<script type='text/javascript'>
 var URL_GROUP = [
  // 'BG1'
  "gachi4.blogspot.com/--URL--/BG1_image-1.jpg",
  "gachi4.blogspot.com/--URL--/BG1_image-2.jpg",
  "gachi4.blogspot.com/--URL--/BG1_image-3.jpg",
  "gachi4.blogspot.com/--URL--/BG1_image-4.jpg",

  // 'BG2'
  "gachi4.blogspot.com/--URL--/BG2_image-5.jpg",
  "gachi4.blogspot.com/--URL--/BG2_image-6.jpg",
  "gachi4.blogspot.com/--URL--/BG2_image-7.jpg",
  "gachi4.blogspot.com/--URL--/BG2_image-8.jpg",

  // 'BG3'
  "gachi4.blogspot.com/--URL--/BG3_image-9.jpg",
  "gachi4.blogspot.com/--URL--/BG3_image-A.jpg",
 ];

 var date = new Date();
 var key = ( Math.sqrt(date.getMonth()+0.1) + Math.sqrt(date.getDate()-0.1) ) * 1.94;
 var DAILY_TARGET = Math.floor( key % 1 * URL_GROUP.length );
 BG_URL = 'https://' + URL_GROUP[DAILY_TARGET];

 document.getElementsByTagName("body")[0].background = BG_URL;
</script>

 ここでは<body>タグに背景設定を仕込んで、その直下にスクリプトを埋め込む形式としました。
 とりあえず上記の枠内から<script ~ </script>をコピーして、スクリプトが動作する箇所に貼り付ければすぐ使えるはずです。
 一応書き換えポイントも少しだけ。

»繰り返しパターン
 自分の好みで、最上部から右方向に並べて表示するようにしています。
 repeat-xの部分をrepeat-yにすると下方向に、repeatだと画面全体にループする表示になります。
 画面の左上に一回だけ表示する場合はno-repeatです。

 ついでにlightgrayは背景色を仮設定しているだけなので、好みでblackwhite等に変更できます。
(真っ白な背景は目が痛くなりがちなのでおすすめしない)
 詳しいことは正直よく分かりませんが、CSS側でbackground-colorを設定するとスクリプトが上手く動作しないことがあったためこのような強引な記述にしています。
 ちなみにbackground-repeatはCSSで設定しても問題ありませんでしたが、細かい挙動は環境によって異なるかもしれません。

»URLグループ
 表示したい背景画像は予め用意する必要があります。
 どっかのサイトにある画像を直リンクして……とかやると後々とんでもないことになるかもしれないため、自分のアカウントからアップロードした画像、それもフリー素材と明記してあるものを使うのが無難です。
  ※そういうの大切だよ!

 今回は整形例として、https://を省いて後から付け足す動作にしています。
 URLを削るのが面倒だとかいう場合は'https://' + を消せばURL_GROUP[]に貼り付けた中身がそのまま使用されます。
(近年の様子だと//~で始まるURL指定もクールかな?)

 なんならgachi4.blogspot.com/のような部分も削ってしまえばリスト的にはすっきりするので限界まで短くしてみるのもアリです。
 ただ、どんなサービスでもいつ仕様が変わるかは分からないし、まったく別のURLから持ってきたくなることもあるかもしれないので長期的に使うことも考えて決めてみてください。


*「作者はこちらです」リンク
 なんとなく意地で実装した仕様として、その日に使用している背景画像について画像の名前(ファイル名)、製作元のサイト名とリンクを表示できるようにしておきました。
  →実際の動作は◆トップページ最近のメモの上)にて。
 画像を用意する時点からいろいろ仕込んでおくような手間も必要なので、ここからは参考程度にご覧下さい。
<script type='text/javascript'>
if(BG_URL!='')
{
 var BG_SRC_LIST = [
 'BG1=Gachide','https://gachi4.blogspot.com/',
 'BG2=Ikuyo',  'https://gachi4.blogspot.jp/',
 'BG3=k.Head', 'http://gachi4.blogspot.com/',
 ];

 var BG_FILENAME =BG_URL.substring(BG_URL.lastIndexOf("/")+1);

 if (BG_FILENAME.indexOf("%") != -1){
  BG_FILENAME = BG_FILENAME.substring(0,BG_FILENAME.indexOf("%") );
 } else {
  BG_FILENAME = BG_FILENAME.substring(0,BG_FILENAME.indexOf("."));
 }

 var TODAYS_BG_SRC = BG_FILENAME.substring(0,BG_FILENAME.indexOf("_"));

 for(i=0;i<BG_SRC_LIST.length;i=i+2) {
  if(TODAYS_BG_SRC == BG_SRC_LIST[i].substring(0,3)){

  document.write('<br />»本日の背景は<A href="'
   +BG_SRC_LIST[i+1]
   +'" target="_blank">◆'+ BG_SRC_LIST[i].substring(4)
   +'</A>様の画像を使用しています。('
   + BG_FILENAME.substring(4) +')');
  break;
  }
 }
}
</script>

 だいぶ回りくどいことをしていますが動けばいいんだよのスタイルです。
 こちらもまあ貼り付ければ動くはずですが、一応から順に解説しておきます。
(いろいろ調べながら作った備忘録でもあります)

»背景設定がないよ
 最初のif(BG_URL!='')の部分で、もしBG_URLの中身が存在しなかった場合はそこで終了です(念のためのエラー処理)。
 今回は日替わり背景を設定する部分サイト全体で動作させて、きょうの背景についての部分はトップページでのみ表示するような配置を想定しています。
(いま現在このブログでそういう動作にしています)

 まあ特に意識する必要も無いはずですが別のスクリプトから持ってきている変数なので、一応スクリプトを配置する順番とかも気をつけたほうがいかも。
 そういった理由で、前述の背景設定部分でBG_URLの宣言にvar(ローカル)とか付けてしまうと動かなくなります。

»ファイル名を抽出するよ
 var BG_FILENAMEの宣言では、BG_URLに対してlastIndexOf("/")を利用してURL末尾のファイル名を抽出しています。
 具体的には最後の/より前の部分をsubstringでカットしています。

»URLに%なんたらとかあるよ
 if (BG_FILENAME.indexOf("%") != -1)は、ファイル名にがあるかどうかの判断です。
 前提としてBloggerやGoogle系の仕様では、URLに含まれる(=といった記号は%2528のようなコードに変換されます。
 このままだと「今日の背景は:%2528Filename%2529」のようなかっこわるいことになります。
 一応、文字コードを複合するdecodeURIdecodeURIComponentも試してみましたがうまく動かなかったため今回は使っていません。

 今回は、あまり深く考えずにファイル名の%以降をカットすることにしました。
 もちろん事前にアウトっぽい記号を使っているファイル名がないか確認は必要ですが、実際のところほとんどのサイトがこういうことを想定しているかのような名前だったため特に苦労しませんでした。
 ちなみに-(ハイフン)や_(アンダーバー)は入っていても問題ありませんでした。

 実際に処理しているのがBG_FILENAME.substring(0,BG_FILENAME.indexOf("%") );あたり。
 else分岐のほうではindexOf(".")にしていますが、これはそのまま使えるファイル名なので拡張子のみカットするということです。

»きょうのソース
 TODAYS_BG_SRCは、使用画像の制作元コードです。
 予めファイル名先頭の識別子_で区切って仕込んでおき、それをindexOf("_")で取り出すようにしています。
 このサイトならBG1、あのサイトはBG2……という感じで、まあ頭の三文字が識別子という前提で作ってありますが、なんとなくアンダーバー区切りで判断するという挙動にしています。

 続いてBG_SRC_LIST製作元情報です。
 ここでは'製作元コード=サイト名','製作元URL',という形式で入力しています。
 これに合わせて、for文ではi++ではなくi=i+2で回しています。

*表示部分
 TODAYS_BG_SRCと、BG_SRC_LIST[i]の先頭3文字が一致した場合、ようやく製作元情報が表示されます。
 これが最後のdocument.write部分です。
 各変数をsubstring(4)(=5文字目以降)にしているのはBG1_部分をカットしているためです。

 長いので改行しているせいか逆にややこしく見えますが、要するに「◆(製作元の名前)」のテキストを製作元URLにリンクさせて、「使用しています。」の後に(ファイル名)と表示しているだけです。
 正常に動作している実際の表示はこんな感じ。

(トップページに仕込んであります)

 明日以降の選択については前述の検証スクリプトによって予測はできますが、「製作元」等の表示まで確認できるようにはしていません。
 いろいろ見た中では、あるサイトに漢字のファイル名のものがあって、これをそのままアップロードした場合はファイル名全体が%だらけになるようなこともあったりして、意外とやってみないと分からない問題が見つかることも多かったです。

 まあとりあえず数週間ほど動作させた限りでは大きな問題も無さそうなので、またこのブログを開いた時におっ、今日の背景ちょっと良いなと思ったら裏側でいろいろ仕込んであることを思い出して頂ければ幸いです。
 日替わりランダム背景については以上です。



  ▲上に戻る
(余談)

 今回のことでいろいろ思い出したのですが、学生時代にはラプラス変換だのフーリエ級数だのを使って電子回路の過渡現象を解析するとかやっていました。
 もはやあんなのは名前だけふんわり覚えている程度なのでどんなに初歩の問題も解けないどころか、今では中学生程度の因数分解すらまともに解けるかあやしいレベルです。
 それでも、波の大きさ(振幅)を変えるのがアンプリチュード・モデュレーション=AM変調で、波の長さ(周期)を変えるのがフレケンシーモデュレーション=FM変調というのがラジオ電波の違いで……みたいな基本的な仕組みくらいは覚えていました。
 そういった経験が、時を経てちょっとだけ役に立ったかなと。

 いわゆる学校で教わることは実生活で役に立たないという話はそれはそれで正しいのですが、これを聞くと自分は「パレートの法則」を連想します。
 何がどこで使えるのかは後にならないと分からないもので……実際のところ大半は無駄ではあるものの、ふとした時に二割程度の役立つ要素に後で気づくことがあります。
 それは学校に限らず、読んだ本や遊んだゲーム、経験したあらゆるものごとについてもおそらく適用可能です。
 ただし、役立つものを役立たせるためには能動的な応用力が必要であって、結局はその人がどこで何を使おうとするかに尽きるのだと思います。

 そして自分は趣味にも意味や役割を持たせたいと思うことがあり、このサイトをその基点にしたいと常々思っています。
 長く続けて、いつかああ、あの時のアレがここで役に立ったなと思えればしめたものです。
 そんなことを思った鋸歯状波を応用した日替わりランダムリンクでした。

 今回は以上です。

»関連記事:
■解説記事いろいろ■Bloggerカスタマイズ


スウェーデンデザイン 折りたたみ式 万能目 ノコギリ 刃渡り 210mm TPR
マンガでわかる電気数学

0 件のコメント:

 ※コメントは管理人の承認後に表示されます。
 (気づかなくて遅れることが多いです)

コメントを投稿