単語帳のブログパーツを作ってみた
英語の記事が増えてきたので単語帳のブログパーツを作ってみました。画像は使わずCSSとJavaScriptだけで作っています。
いわゆるカードレイアウトで複数のコンテンツを表示していて、中身のデータやレイアウトを修正すれば他の用途にも使えます。(※Chromeでしか動作確認はしていません)
一度に5つのコンテンツをランダムに表示していて、更新ボタンをクリックすると再度ランダムに5つ選んで表示するようになっています。
ちなみにコンテンツはハードコーディングで用意しています。
サンプル
画面右の「単語帳」というパーツになります。
以下ソースコードです。(変にこだわってしまった部分もあり若干肥大化してます・・・)
JavaScript
!function(){ var active = 0; var cardSize = 5; // カードのコンテンツリスト var cardList = [ {"term": "Where was I?", "mean": "何話してましたっけ?", "url": "http://wbhappy.hatenablog.jp/entry/2014/11/12/120000"}, {"term": "Are you serious?", "mean": "本気?", "url": "http://wbhappy.hatenablog.jp/entry/2014/11/14/220000"}, {"term": "I don't care", "mean": "気にしない、どうでもいい", "url": "http://wbhappy.hatenablog.jp/entry/2014/11/16/213000"}, {"term": "Awesome", "mean": "すげー。ヤバイ", "url": "http://wbhappy.hatenablog.jp/entry/2014/11/17/220000"}, {"term": "I'm bored", "mean": "飽きた", "url": "http://wbhappy.hatenablog.jp/entry/2014/11/18/220000"}, {"term": "Do it yourself", "mean": "自分でやってよ", "url": "http://wbhappy.hatenablog.jp/entry/2014/11/21/210000"}, {"term": "I'm stuck", "mean": "困ったなぁ", "url": "http://wbhappy.hatenablog.jp/entry/2014/11/22/210000"}, {"term": "I'm happy to help", "mean": "お役に立てて嬉しいです", "url": "http://wbhappy.hatenablog.jp/entry/2014/11/23/210533"}, {"term": "Can it wait?", "mean": "後でいい?", "url": "http://wbhappy.hatenablog.jp/entry/2014/11/24/213000"}, {"term": "I told you", "mean": "言ったじゃん", "url": "http://wbhappy.hatenablog.jp/entry/2014/11/27/213745"} ] var empty = function(el){ while (el.firstChild) { el.removeChild(el.firstChild); } } var getRandomList = function(array, size){ var indexArray = []; var cardLen = array.length; if(cardLen < size){ return array; } while(indexArray.length < size){ var index = ~~(Math.random()*(cardLen)) if(indexArray.indexOf(index) < 0){ indexArray.push(index); } } var list = []; for(var i=0,len=indexArray.length; i<len; i++){ var index = indexArray[i]; list.push(array[index]); } return list; } var updateCard = function(){ var list = getRandomList(cardList, cardSize); var wrap = document.getElementById("wb_card_center").children[0]; empty(wrap); var buf = []; for(var i=0, len=list.length; i<len; i++){ var card = list[i]; // カードの中身のレイアウト var el = [ "<div class=\\"wb-card\\">", "<div class=\\"wb-card-inner\\">", "<a class=\\"term\\" href=\\"", card.url, "\\">", card.term, "</a>", "<hr><span class=\\"mean\\">", card.mean, "</span>", "</div>", "</div>" ]; buf.push(el.join("")) } wrap.innerHTML = buf.join(""); } var init = function(){ updateCard(); var onclick = function(num){ active += num; if(active < 0){ active = cardSize-1; }else if(active > cardSize-1){ active = 0; } var radio = document.getElementById("wb_slide" + (active+1)); radio.checked = true; } var left = document.getElementById("wb_card_left"); var right = document.getElementById("wb_card_right"); left.addEventListener("click", function(){ onclick(-1); }, false); right.addEventListener("click", function(){ onclick(1) }, false); var reload = document.getElementById("wb_reload"); reload.addEventListener("click", function(){ updateCard(); }, false); } window.addEventListener("load", init, false); }();
html
<div id="wb_card_widget"> <input type="radio" name="slider" id="wb_slide1" checked/> <input type="radio" name="slider" id="wb_slide2" /> <input type="radio" name="slider" id="wb_slide3" /> <input type="radio" name="slider" id="wb_slide4" /> <input type="radio" name="slider" id="wb_slide5" /> <div id="wb_active"> <label for="wb_slide1"></label> <label for="wb_slide2"></label> <label for="wb_slide3"></label> <label for="wb_slide4"></label> <label for="wb_slide5"></label> </div> <div id="wb_reload" class="wb-icon" title="更新"> <div class="reload"></div> </div> <div id="wb_help"><a href="http://wbhappy.hatenablog.jp/entry/2015/01/18/153853" title="このパーツの作り方" target="_blank">?</a></div> <div id="wb_card_center"> <div class="inner"> <div class="wb-card"> <div class="wb-card-inner">JavaScriptを有効にしてください。</div> </div> </div> </div> <div id="wb_card_left"><</div> <div id="wb_card_right">></div> </div>
CSS
幅300pxで最適化しています。サイズを変更する場合は「パーツの幅」と「コンテンツの幅」の2箇所を修正。あとはボタンの位置等の細かい微調整が必要かも・・・。
#wb_card_widget { border: 1px solid rgb(255, 237, 237); position: relative; height: 100px; width: 300px; /* パーツの幅 */ border-radius: 6px; line-height: 1; } #wb_card_center { overflow: hidden; } #wb_card_left, #wb_card_right { -webkit-transition: all 0.1s; -moz-transition: all 0.1s; -ms-transition: all 0.1s; -o-transition: all 0.1s; transition: all 0.1s; display: inline-block; line-height: 100px; height: 100px; width: 16px; vertical-align: middle; text-align: center; cursor: pointer; font-size: 16pt; font-weight: bold; background-color: #FF8181; color: white; position: absolute; top: 0px; } #wb_card_left { border-radius: 6px 0px 0px 6px; left: 0px; } #wb_card_right{ border-radius: 0px 6px 6px 0px; right: 0px; } #wb_card_left:hover, #wb_card_right:hover{ background-color: #FCB7B7; color: #E07070; } #wb_card_widget .inner { width: 500%; padding: 5px 22px; -webkit-transform: translateZ(0); -webkit-transition: all 600ms cubic-bezier(0.770, 0.000, 0.175, 1.000); -moz-transition: all 600ms cubic-bezier(0.770, 0.000, 0.175, 1.000); -ms-transition: all 600ms cubic-bezier(0.770, 0.000, 0.175, 1.000); -o-transition: all 600ms cubic-bezier(0.770, 0.000, 0.175, 1.000); transition: all 600ms cubic-bezier(0.770, 0.000, 0.175, 1.000); -webkit-transition-timing-function: cubic-bezier(0.770, 0.000, 0.175, 1.000); -moz-transition-timing-function: cubic-bezier(0.770, 0.000, 0.175, 1.000); -ms-transition-timing-function: cubic-bezier(0.770, 0.000, 0.175, 1.000); -o-transition-timing-function: cubic-bezier(0.770, 0.000, 0.175, 1.000); transition-timing-function: cubic-bezier(0.770, 0.000, 0.175, 1.000); } #wb_card_widget input{ display: none; } #wb_active { position: absolute; bottom: 3px; left: 115px; text-align: center; } #wb_active label { -webkit-border-radius: 5px; -moz-border-radius: 5px; border-radius: 5px; display: inline-block; width: 7px; height: 7px; background: #bbb; cursor: pointer; margin-left: 2px; margin-right: 2px; } #wb_active label:hover { background: #ccc; border-color: #777; } #wb_slide1:checked ~ #wb_card_center .inner { margin-left:0; } #wb_slide2:checked ~ #wb_card_center .inner { margin-left:-100%; } #wb_slide3:checked ~ #wb_card_center .inner { margin-left:-200%; } #wb_slide4:checked ~ #wb_card_center .inner { margin-left:-300%; } #wb_slide5:checked ~ #wb_card_center .inner { margin-left:-400%; } #wb_slide1:checked ~ #wb_active label:nth-child(1), #wb_slide2:checked ~ #wb_active label:nth-child(2), #wb_slide3:checked ~ #wb_active label:nth-child(3), #wb_slide4:checked ~ #wb_active label:nth-child(4), #wb_slide5:checked ~ #wb_active label:nth-child(5) { background: #333; border-color: #333; } #wb_card_widget .wb-card { width: 20%; float: left; } #wb_card_widget .wb-card-inner{ width: 256px; /* カードのコンテンツの幅 */ word-wrap: break-word; } #wb_card_widget .wb-card hr { border: 1px dashed #ccc; background: none; height: 0px; } #wb_card_widget .wb-card .mean { font-size: 10pt; } #wb_help { position: absolute; right: 26px; bottom: 3px; } #wb_help a{ text-decoration: none; font-weight: bold; color: #aaa; } #wb_help a:hover { color: #333; } /* ############# 更新ボタン ############# */ div.wb-icon { height: 24px; width: 24px; position: absolute; overflow: hidden; display: inline-block; right: 30px; bottom: 3px; } div.wb-icon div.reload { width: 6px; height: 3px; border-style: solid; border-width: 0px 2px 2px 2px; border-color: #aaa; -webkit-border-radius: 0 0 50px 50px; -moz-border-radius: 0 0 50px 50px; border-radius: 0 0 50px 50px; position: absolute; top: 18px; left: 2px; cursor: pointer; } div.wb-icon div.reload:before { content: ''; position: absolute; width: 0; height: 0; border-style: solid; border-width: 3px; border-color: transparent transparent transparent #aaa; bottom: 4px; left: 3px; cursor: pointer; } div.wb-icon div.reload:after { content: ''; width: 3px; height: 3px; border-style: solid; border-width: 2px 0 0 2px; border-color: #aaa; -webkit-border-radius: 50px 0 0 0; -moz-border-radius: 50px 0 0 0; border-radius: 50px 0 0 0; position: absolute; left: -2px; bottom: 3px; cursor: pointer; } div.wb-icon:hover div.reload, div.wb-icon:hover div.reload:after { border-color: #333; } div.wb-icon:hover div.reload:before { border-color: transparent transparent transparent #333; }