なんでもかんでもオブジェクト化すればいいってもんじゃないな。反省!

これは、先日の記事「JavaScriptの無名関数とクラス」の続きです。

外から呼び出せないなら、中でやればいいじゃない!

今しがた、他の事をしていたら突然に閃いた。すごい思い込みで無駄な事をしていた。こないだ書いた記事、あれオブジェクト化する必要はなかったんだ。

自分がやりたかった事は、ボタンをonclickしたら、setCookie関数を走らせたかっただけで、そのために無名関数の中のfunctionをprototypeにするということを考えた。なぜなら、無名関数の中の関数はonclickで呼び出せないから。

記事の中で、ボタンのないバージョンと、あるバージョンの2つを走らせたいという考えもあった。「2つ走らせるならオブジェクト」という発想が先行した。

でも、そうじゃなかった。「無名関数の中の関数はonclickで呼び出せない」のなら、「無名関数の中でonclickのコールバックを書き込めばいい」だけだったんだ!

つまり、元のソースの終盤の部分を、少し書き換えるだけでよかった。

 if( !targetDay ) {
   targetDay = addDay( LIMIT_DAY ).getTime();
   setCookie( COOKIE_NAME, targetDay + '', SHELF_LIFE );
 }

 (function () {
  var text = '次回まで約';
  var s = (targetDay - (new Date).getTime()) / 1000 |0;

  if (s < 0)
   text = TIMEOUT_MESS;

  else {
   text += padding( s % 86400 / 3600 |0) + '時間' +
    padding( s % 3600 / 60 |0) + '分' +
    padding( s % 60 |0) + '秒です。';
    setTimeout (arguments.callee, 1000);
  }

  node.firstChild.nodeValue = text;
 })();

上のソースは、下のように書き換えても同じ。

 function reset(){
   targetDay = addDay( LIMIT_DAY ).getTime();
   setCookie( COOKIE_NAME, targetDay + '', SHELF_LIFE );
 }

 function load() {
  var text = '次回まで約';
  var s = (targetDay - (new Date).getTime()) / 1000 |0;

  if (s < 0)
   text = TIMEOUT_MESS;

  else {
   text += padding( s % 86400 / 3600 |0) + '時間' +
    padding( s % 3600 / 60 |0) + '分' +
    padding( s % 60 |0) + '秒です。';
    setTimeout (load, 1000);
  }

  node.firstChild.nodeValue = text;
 }

  if( !targetDay ) {
    reset();
  }

  load();

あとは、<input type=”button” id=”messBtn” value=”リセット” /> とでもして、次のcallbackを無名関数の中から書き込むだけで事足りた。

 document.getElementById('messBtn').onclick=function(){
    reset();
    load();
  };

これで実際に動いている。

次回

タイマーを

これなら前回、global宣言したvar countdownも必要ない。出来る限りglobalではなくlocalで宣言は済ませたい。

もし、2つ走らせたいなら、無名関数をやめて、関数に名前をつければいい。その時、表示領域のidを引数に加えるだけでよかった。ただし、prototypeと違って無駄なメモリーを食うけれど。そのメモリー消費も微々たるもの。ブログのたったひとつの記事のためにオブジェクトにするのが効率的かどうかという話だな。実際、今やってみたら、この書き換え作業は2~3分で出来た。前回はthisをつけるのに数分要している。

今回は元のソースを書いたbabu_babu_babooさんにやんわりと指摘を受けていた。けど、その真意を理解できないでいた。ずっと頭の中で気になっていたんだけど、突然に閃いた。こういうことだったんだ。なんでもかんでもオブジェクトにすればいいってもんじゃないな。

これはプログラミングに限らず言えることだけど、自分一人で考えていると、ひとりよがりの結論になりがちだ。指摘をされるまで気がつかない事というものはある。せっかくブログがあるんだから情報は表に出して、いろいろな意見を聞いた方がいいのかもしれない。と、今回は思いました。

最終的なソースコード

前回のコードでも動作は問題ないので、前回のソースを使っているマスクドライダー17号さんが下のソースに書き換える必要はありません。(書き換えてもいいけど、同じ事です)

<style type="text/css">
p#mess{ font-size:200%; }
</style>

<p id="mess">次回</p>
タイマーを<input type="button" id="messBtn" value="リセット" />

<script type="text/javascript">
<!--
(function (doc) {

 function addDay ( day, date ) {
  if( 'number' !== typeof day ) day = 0;
  if( 'object' !== typeof date ) date = new Date;
  date.setDate( date.getDate() + day );
  return date;
 }

 function getCookie ( name ) {
  name = encodeURIComponent( name ).replace( /([.*()]) /g, '\\$1' );
  var value = doc.cookie.match( RegExp( name + '\\s*=\\s*(.*?)(?:[\\s;,]|$)' ) );
  return value ? decodeURIComponent( value[1] ): '';
 }

 function setCookie ( name, value, day, path, domain ) {
  return doc.cookie = encodeURIComponent (name) + '=' + encodeURIComponent (value) +
   '; ' + 'expires=' + ( addDay(day) ).toUTCString () + '; ' + (path ? 'path=' + encodeURI (path) + '; ': '') +
   (domain ? 'domain=' + encodeURI (domain) + '; ': '');
 }
 function padding ( n ) { return n < 10 ? '0' + n: n; }
  var COOKIE_NAME = 'myCount';
 var LIMIT_DAY = 1;
 var SHELF_LIFE = 10;
 var TIMEOUT_MESS = '24時間以上経過しました!!';
 var node = doc.getElementById( 'mess' );
 var targetDay = parseInt( getCookie( COOKIE_NAME ) );

 function reset(){
   targetDay = addDay( LIMIT_DAY ).getTime();
   setCookie( COOKIE_NAME, targetDay + '', SHELF_LIFE );
 }

 function load() {
  var text = '次回まで約';
  var s = (targetDay - (new Date).getTime()) / 1000 |0;

  if (s < 0)
   text = TIMEOUT_MESS;

  else {
   text += padding( s % 86400 / 3600 |0) + '時間' +
    padding( s % 3600 / 60 |0) + '分' +
    padding( s % 60 |0) + '秒です。';
   setTimeout (load, 1000);
  }

  node.firstChild.nodeValue = text;
 }

  if( !targetDay ) {
    reset();
  }

  load();

  document.getElementById('messBtn').onclick=function(){
    reset();
    load();
  };
})(this.document);

//-->
</script>

“なんでもかんでもオブジェクト化すればいいってもんじゃないな。反省!”の続きを読む

JavaScriptの無名関数とクラス

2013年5月3日追記
この記事の反省をふまえた続編もあります。この記事で私の書き換えたソースは、非常に無駄な事をしていますので、この記事だけだと恥ずかしいから、そちらもお読み頂ければ幸いです。

なんでもかんでもオブジェクト化すればいいってもんじゃないな。反省!

経過時間を計算してくれるタイマー

マスクドライダー17号さんが、彼のブログで面白いことをやっていて、最初にそのページを開いてからカウントダウンをはじめて、24時間経過したかどうか、残り時間を教えてくれるというスクリプトを走らせています。

その記事によると「教えて!gooにて回答されていた、babu_babooさんのScriptを参考にしました」ということで、babu_babu_babooさんのスクリプトをアレンジしたそうです。

教えて!gooの内容は、期限が来たかどうかカウントしたいだけなので、そのスクリプトは必要な目的を達成しています。

現在、マスクドライダー17号さんが使っているスクリプトは、おそらく24時間で正しく止まると思います。(止まるという表現は正確でないですがわかりやすく言っています)ただ、それを彼のブログで使う場合は不足している機能があります。それは、リセット機能です。

クッキーにデータが残っている

そのスクリプトは、クッキー(cookie)を使って、実現されています。ブラウザを閉じても、最初の時間をクッキーが記憶しているので、もう一度ブログにアクセスした時に、最初の時間からの残りを計算できます。そして、残り時間がなくなると「24時間以上経過しました!!」と表示して終了します。

カウントダウンが1度だけなら、今のままで、まったく問題ないのですが、マスクドライダー17号さんの場合は、そのタイマーを24時間経過する度に、リセットして使いまわしたいのだと思います。でも、今のままだと、最初の24時間が過ぎると「24時間以上経過しました!!」と表示されて、そのまま動かなくなります。その後、もう一度使おうとしても、24時間たってしまったので動きません。

繰り返しますが、教えて!gooの場合は、これで目的を達成出来ているので問題ありません。

現在、マスクドライダー17号さんは、クッキーの有効期限を10日にしているので、止まってから、さらに9日経てば、またスクリプトは使えるようになりますが、かといって、有効期限を短くすると、ブログを開いたときにスクリプトがリセットされてしまい、24時間経ったのかどうか、わからなくなります。ですから「24時間以上経過しました!!」という表示を読むまでは、リセットしたくありません。読み終わったら、ボタンを押して、リセット(カウントダウンの再スタート)をさせるのが、いちばんいいと思います。

元のソースコード

出来れば、動いている今のソースコードをそのまま流用したいです。ありがたいことに、機能ごとに、細かく関数に分けてくれています。この中のsetCookie関数を使えばクッキーはリセット出来ます。

<style type="text/css">
p#mess{ font-size:200%; }
</style>

<p id="mess">次回</p>

<script type="text/javascript">
<!--
(function (doc) {

 function addDay ( day, date ) {
  if( 'number' !== typeof day ) day = 0;
  if( 'object' !== typeof date ) date = new Date;
  date.setDate( date.getDate() + day );
  return date;
 }

 function getCookie ( name ) {
  name = encodeURIComponent( name ).replace( /([.*()]) /g, '\\$1' );
  var value = doc.cookie.match( RegExp( name + '\\s*=\\s*(.*?)(?:[\\s;,]|$)' ) );
  return value ? decodeURIComponent( value[1] ): '';
 }

 function setCookie ( name, value, day, path, domain ) {
  return doc.cookie = encodeURIComponent (name) + '=' + encodeURIComponent (value) +
   '; ' + 'expires=' + ( addDay(day) ).toUTCString () + '; ' + (path ? 'path=' + encodeURI (path) + '; ': '') +
   (domain ? 'domain=' + encodeURI (domain) + '; ': '');
 }
 function padding ( n ) { return n < 10 ? '0' + n: n; }
  var COOKIE_NAME = 'myCount';
 var LIMIT_DAY = 1;
 var SHELF_LIFE = 10;
 var TIMEOUT_MESS = '24時間以上経過しました!!';
 var node = doc.getElementById( 'mess' );
 var targetDay = parseInt( getCookie( COOKIE_NAME ) );

 if( !targetDay ) {
   targetDay = addDay( LIMIT_DAY ).getTime();
   setCookie( COOKIE_NAME, targetDay + '', SHELF_LIFE );
 }

 (function () {
  var text = '次回まで約';
  var s = (targetDay - (new Date).getTime()) / 1000 |0;

  if (s < 0)
   text = TIMEOUT_MESS;

  else {
   text += padding( s % 86400 / 3600 |0) + '時間' +
    padding( s % 3600 / 60 |0) + '分' +
    padding( s % 60 |0) + '秒です。';
   setTimeout (arguments.callee, 1000);
  }

  node.firstChild.nodeValue = text;
 })();
})(this.document);

//-->
</script>

しかし、弱ったことにソースは無名関数で括られているので、setCookie関数を使えません。無名関数の外に出してもいいのですが、この際、オブジェクト(クラス)化して、無名関数内のfunctionを、クラスのprototypeに移動させる事にします。

オブジェクト指向で書き換えたコード

関数の中身は、ほとんどいじっていませんし、スクリプトのロジックは一緒です。

<style type="text/css">
p#mess{ font-size:200%; }
</style>

<p id="mess"></p>
タイマーを<input type="button" onclick="countdown.reset();" value="リセット" />

<script type="text/javascript">
<!--
var timerCookie=function(id){
 this.id=id;
 this.COOKIE_NAME = 'myCount'+id;
 this.LIMIT_DAY = 1;
 this.SHELF_LIFE = 10;
 this.TIMEOUT_MESS = '24時間以上経過しました!!';
 this.targetDay = parseInt( this.getCookie( this.COOKIE_NAME ) );

 if( !this.targetDay ) {
   this.reset();
 }else{
   this.load();
 }
};

timerCookie.prototype.addDay=function( day, date ){
  if( 'number' !== typeof day ) day = 0;
  if( 'object' !== typeof date ) date = new Date;
  date.setDate( date.getDate() + day );
  return date;
};

timerCookie.prototype.getCookie=function( name ){
  name = encodeURIComponent( name ).replace( /([.*()]) /g, '\\$1' );
  var value = document.cookie.match( RegExp( name + '\\s*=\\s*(.*?)(?:[\\s;,]|$)' ) );
  return value ? decodeURIComponent( value[1] ): '';
};

timerCookie.prototype.setCookie=function( name, value, day, path, domain ){
  return document.cookie = encodeURIComponent (name) + '=' + encodeURIComponent (value) +
   '; ' + 'expires=' + ( this.addDay(day) ).toUTCString () + '; ' + (path ? 'path=' + encodeURI (path) + '; ': '') +
   (domain ? 'domain=' + encodeURI (domain) + '; ': '');
};

timerCookie.prototype.padding=function( n ){ return n < 10 ? '0' + n: n; }

timerCookie.prototype.reset=function(){
   this.targetDay = this.addDay( this.LIMIT_DAY ).getTime();
   this.setCookie( this.COOKIE_NAME, this.targetDay + '', this.SHELF_LIFE );
   this.load();
};

timerCookie.prototype.load=function () {
  var text = '次回まで約';
  var s = (this.targetDay - (new Date).getTime()) / 1000 |0;

  if (s < 0)
   text = this.TIMEOUT_MESS;

  else {
   text += this.padding( s % 86400 / 3600 |0) + '時間' +
    this.padding( s % 3600 / 60 |0) + '分' +
    this.padding( s % 60 |0) + '秒です。';
   (function(obj){
	setTimeout (function(){ obj.load(); }, 1000);
   })(this);
  }

  document.getElementById( this.id ).innerHTML = text;
};

var countdown=new timerCookie('mess');
//-->
</script>

これで、setCookie関数を使えるようになりました。setCookie関数を使って作ったのが、上のprototypeにあるreset関数です。元のコードは本来、例文として作られたものですし、1回しか使わないという前提に立ったものです。そういう場合は無名関数で括ってしまうのが便利ですし、使いまわす時はオブジェクト化が便利だと思います。

ちなみに、オブジェクトは表示領域のidを引数にとるようにしています。これで、同じページで時間の違う、複数のタイマーを走らせることも出来ます。

タイマーを

“JavaScriptの無名関数とクラス”の続きを読む

スマホとPCでレイアウトを切り替える – レスポンシブデザイン

これからのブログはスマートフォンで見やすくする必要がある

最近はスマホアクセスが増加

最近はスマートフォンでのアクセスが増えています。特に一時的なアクセス急増の場合は、Twitterでツイートされたりした時なので、尚更モバイルからのアクセスの割合が増えます。

このキャプチャは実際に、このブログの記事がツイートされた時のアクセスログですが、71%が携帯電話からのアクセスでした。

IE6が消えたと思ったら、スマホなんて面倒なもの作りやがって!と怒っても仕方ありません。頑張って対応したいと思います。

レスポンシブデザイン

先にお断りしておきますが、私はレスポンシブデザインの勉強はまったくしていないので、この記事の内容は自己流です。一般的な流儀に判している可能性もありますことを、ご承知おきください。

最近、こんなコメントを頂きました。

TOMさんのブログをスマホ(iphone)で拝見すると、両サイドがメインの記事の下に来るようになっていますが、裏技でしょうか?
私のブログはそのようにならないのですが・・・

このブログはパソコンで見たときとスマートフォンで見た時はルックスが変わるようにしてあります。下は左がパソコンで見た場合、右がスマホで見た場合の表示のされ方です。ただし、Tomさんはスマホを持っていないので、右はエミュレーションで表示させたものです。実際にスマホで見た時は、もっと崩れていると思います。

PCレイアウト    スマホレイアウト

パソコンの方は、ブラウザのサイズによっても見え方が、変わります。下はヘッダの部分だけを切り取った画像ですが、画面が広い時と、狭い時で横に並ぶ個数が変わっています。

画面が広い時のヘッダ    画面が狭い時のヘッダ

こういう風に状況によってレイアウトが変わるものをレスポンシブデザインと呼ぶそうです。

レスポンシブデザインを実現する方法は、いろいろあると思います。このブログの場合は、主にスタイルシートで作り、スタイルシートだけでやるのが難しいところにJavaScriptを使いました。ただし、何も見ないで作ったので自己流です。一般的な流儀に反しているかもしれません。

3カラムの構造

下は、このブログを書いているファンブログの3カラムスキンの構造です。ファンブログ以外でも、ほぼこれに近い形が多いと思います。

下のスキンは、記事部分が500px(500ピクセル)、左サイドバーが200px、右サイドバーが160pxです。

このブログのスキンは完全オリジナルなので、下のとは違います。

id=”container”

ヘッダ
id=”header”
id=”main”

id=”wrapper”
700px

左サイドバー
id=”sidebarLeft”
200px
記事部分
id=”content”
500px

右サイドバー
id=”sidebarRight”
160px

フッタ
id=”footer”

これをスマホの時だけ、下の構造にします。こうすれば両サイドがメインの記事の下に来ます。下の図は見やすくするために左右に余白がついていますが、この余白をなくせば、スマホの横幅いっぱいで表示されます。

これはスタイルシートを切り替えるだけで実現できます。

id=”container”

ヘッダ
id=”header”
id=”main”

id=”wrapper”

記事部分
id=”content”
左サイドバー
id=”sidebarLeft”
右サイドバー
id=”sidebarRight”
フッタ
id=”footer”

サイドバーを下に落とす

右のサイドバーを下にするには、どうしたらいいでしょうか。それには、パソコンで見る時は700pxあるwrapperの横幅を100%にすればいいです。wrapperの横幅が左右いっぱいに広がれば、右サイドバーは収まりきらないので、下に落ちます。

次に左サイドバーを、記事の下に落とします。これも同じように、記事の部分、idがcontentの部分の横幅を100%に変更します。これで、収まりきらない左サイドバーは記事の下に落ちます。

最後は下に落ちた左右サイドバーの横幅も100%に変更します。そうすれば、スマホで見たときは、上から記事、左サイドバー、右サイドバーの順に横幅いっぱいで表示されます。

つまり、wrapper、content、sidebarLeft、sidebarRightの横幅を、すべて100%にすればいいということです。

ただし、それをやるにはmainの中のHTMLが、下のようになっている必要があります。最初に記事、次に左サイドバー、その次に右サイドバーの順番です。

<div id="main">
	<div id="wrapper">
		<div id="content"></div>
		<div id="sidebarLeft"></div>
	</div>
	<div id="sidebarRight"></div>
</div>

先にある記事が横幅100%になったことで、残りは入りきらずに下に落ちますが、先にサイドバーがあれば、記事が下に落ちます。

どうやってスタイルシートを切り替えるか

スタイルシートを切り替える方法ですが、このブログではbodyタグのidを変更しています。パソコンで見たときにはidなし、スマホで見たときにはidが”sp”となるようにしています。

その実現方法として、JavaScriptを使っています。ユーザーエージェントを見て、スマホブラウザの時に、idをつけるという方法です。ソースコードは下の通りです。

<script type="text/javascript"><!--
(function(){
	if(0<=navigator.userAgent.indexOf('Android')){
		document.body.id='sp';
	}else if(0<=navigator.userAgent.indexOf('iPhone')){
		if(-1==navigator.userAgent.indexOf('iPad')){
			document.body.id='sp';
		}
	}else if(0<=navigator.userAgent.indexOf('iPod')){
		document.body.id='sp';
	}
})();//-->
</script>

このブログで使っているスクリプトから、該当箇所だけ抜き出しました。もし正しく動作しなければご連絡ください。

このスクリプトをコピーして、bodyの開始タグ(<body>)の直後に張り付ければ、スマホの時はidが切り替わるようになります。貼り付ける場所は必ず<body>の直後にしてください。

後は、body#spに対応したスタイルシートを、下のように追加すれば、スマホ用レイアウトで表示されます。

body#sp wrapper,body#sp content,
body#sp sidebarLeft,body#sp sidebarRight{
  width:100%;
}

スマホでだけ表示させたいもの、あるいはスマホでだけ表示させたくないものは、スタイルシートの display で切り替えます。

このブログのヘッダのカテゴリーメニューのように横幅で並ぶ個数を切り替えたいなら、別の記事「横幅に合わせ並ぶ個数を自動調整するスタイルシート」をご覧ください。

画像の大きさを自動調整したいときの参考記事は「絶対はみ出さない画像!自動でサイズ調節するスタイルシート」です。そちらを参考にしてください。


このブログでは、スキンのheadに次のmetaタグを書き込んでいますが、説明は省略します。これを書かなくても、サイドバーを下に落とす目的は達成できます。

<meta name="viewport" content="width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no" />

ボタンでYouTubeの動画を表示させる

YouTubeは自分も好きですが、ブログの中にたくさん貼ると重いです。ひとつのページにいくつもあると、そのページを開くのが大変です。

本当は、数を少なくするのがイチバンなんですが、どうしてもたくさん貼りたいというときに、ビデオではなくボタンにしたらどうだろう?ボタンを押したものだけ、そのビデオを表示するようにすれば少しは軽くなるのではないか?ということで作ってみました。

これはファンブログだけでなく、どのブログでも使えます。ただ、ビデオが表示されているから、見てみたくなるというのはあると思うので、使わない方がいい場合が多いとは思います。と、身も蓋もないことを言ってみる。

サンプル

船橋市の梨の妖精ふなっしー♪
2000年に一度だけ、この世に現れる、愛の戦士。
今日も元気に、梨汁ブシャー:;.,*+
こころを込めて踊ります♪

ふなっしーのcall me maybeを見る!

使い方

まずはYouTubeへ行き、通常のソースを取ってきます。最初に「共有」をクリック。そして「埋め込みコード」をクリックします。動画のサイズなどの設定をお好みに合わせたら、表示されている「埋め込みコード」をコピーします。

YouTube

埋め込みコード」を取ってきたら、この下の枠に、その「埋め込みコード」を張り付けてください。取ってきたのが正しいコードなら、貼り付け終わると、ボタンにするために「独自に生成されたコード」が表示されます。あとは、それをコピーして自分のブログの表示させたい場所に貼り付ければ完了です。

この下に表示したいYoutubeのソースを張り付けてください。

どなたでも、ご自由にお使いいただいて構いませんが、使ったらコメント欄に「使った」とだけ書いておいてください。

ソースコード

この下は、興味のある方だけご覧ください。生成されるソースコードは次のようになります。

<script type="text/javascript" src="http://api.dwm.me/js/youtube_show.js" charset="utf-8"></script>
<script type="text/javascript">youtube.button(640,480,'http:\/\/www.youtube.com/embed/RI6svNFmRAQ');</script>

1行目のスクリプトで、外部の.jsファイルを読み込んでいます。その中身は以下のとおりです。

var youtube_class=function(){
	this.count=0;
};

youtube_class.prototype.show=function(id,width,height,src){
	document.getElementById(id).innerHTML='<iframe width="'
		+width+'" height="'+height+'" src="'+src
		+'" frameborder="0" allowfullscreen></iframe>';
};

youtube_class.prototype.button=function(width,height,src){
	document.write('<input type="button" value="youtubeを表示" '
		+'onclick="youtube.show(\'youtube_'+this.count+'\','
		+width+','+height+',\''+src+'\');" /><br /><br />'
		+'<div id="youtube_'+(this.count++)+'"></div>');
};

var youtube=youtube?youtube:new youtube_class();

本当は外部ファイルにせずに、そのままコピペしてもらいたいんですが、少し長いだけでヒルんでしまう方がいるので、貼り付けるソースを短くしたかった。それで外部ファイルにしています。

“ボタンでYouTubeの動画を表示させる”の続きを読む

マウスが乗った写真を拡大表示する商品レイアウト

ファンブログにアップロードした画像URLの調べ方は「ファンブログでアップロードした画像の場所」に書いてあります。

Amazonなんかでやっている商品レイアウトで小さな写真を並べておいて、どれかにマウスを乗せると、その写真の拡大図を表示するという手法があります。その実現方法です。この下に6つ並んだダースベイダーのどれかにマウスを合わせると、その写真が下に大きく表示されます。






レゴ (LEGO) スターウォーズ ダースベイダー Star Wars Darth Vader Alarm Clock 目覚まし時計 9002113

LEGOとスターウォーズがコラボレーションしたアラームクロック

  • 手足が可動式なのでお気に入りのスタイルで飾れます。
  • 頭の部分を押してアラームストップ&ライト点灯。
  • デスクサイド、ベッドサイドを演出してくれるクロックです。
【メーカー名】LEGO
【品番・型番】9002113

サイズ:(約)前長23cm、幅15cm / 重量:(約)535g
材質:プラスチック / 生産国:中国
スペック:アラーム(スヌーズ機能付き)ライト付き
     単4乾電池×2本使用(付属)
箱・保証書:有り(6ヶ月)
特記事項:実際の商品とは若干異なる場合がございます。
     予めご了承ください。

3,675円(税抜:3,500円)

送料525円(お買い上げ金額合計8,000円以上で送料無料)

レゴ (LEGO) スターウォーズ ダースベイダー Star Wars Darth Vader Alarm Clock 目覚まし時計 9002113  レゴ (LEGO) スターウォーズ ダースベイダー Star Wars Darth Vader Alarm Clock 目覚まし時計 9002113をカートに入れる

ちなみにこれは「カートに入れる」と本当に買うことができます

え!欲しいですか?困ったなぁ。そんなつもりじゃなくて、ただのサンプルなんだけど!いやぁ困った!でも仕方がない。どうしても欲しい方は レゴ (LEGO) スターウォーズ ダースベイダー Star Wars Darth Vader Alarm Clock 目覚まし時計 9002113をカートに入れる をクリックしてお買い上げください。

ソースコード

今回説明するのは、左上のダースベーダーの写真だけのブロックです。その右の「説明文」や「カートに入れる」ボタンがあるブロックと、写真の下の「ストーム・トルーパー」や「Amazon」「楽天」等へのリンクがまとまっているブロック、この2つは説明には含めません。

先にソースだけをまとめて書きます。これをまるごとブログの記事にコピペして、画像URL1から6に表示したい画像のURLを入れるだけでも上のようになります。ただし、編集画面のオプションで改行を有効にしていると動かないと思います。改行を有効にしていても動くソースは記事の最後です。

“マウスが乗った写真を拡大表示する商品レイアウト”の続きを読む