最低限文化的な階調機能付きスライダー
404 Blog Not Found:DHTML - 最低限文化的なスライダーの実装
http://trackback.blogsys.jp/livedoor/dankogai/51733122
で記述されてたスライダーに、階調機能をつけた。
なんかIE7で動かないような気がするけど気のせいかな。
動作デモはこちら。
<!DOCTYPE HTML> <html lang="ja"> <head> <meta charset="UTF-8"> <title></title> <style> .slider { -webkit-user-select: none; -webkit-tap-highlight-color: transparent; border:inset 1px; height: 2em; } .slider > div { height:100%; } #status > dt { border-top: 2px solid #909090; margin-top: 5px; } </style> </head> <body> <div style="border:outset 1px; padding:0.5em"> <dl> <dt>Red</dt> <dd><div id="rslider" class="slider"><div style="background-color:#f00;"> </div></div></dd> <dt>Green</dt> <dd><div id="gslider" class="slider"><div style="background-color:#0f0;"> </div></div></dd> <dt>Blue</dt> <dd><div id="bslider" class="slider"><div style="background-color:#00f;"> </div></div></dd> <dt>RGB</dt> <dd> <div id="rgb" class="slider"></div> </dd> </dl> </div> <script> // 各種設定。 var setting = { tone : 5, // スライドの階調:falseまたは任意の正の数 initial: { red : "100%", green : "80%", blue : "20%" } }; // 数字をゼロ埋めする。 // 参考 : http://saboten009.blogspot.com/2009/04/javascript0.html function formatNum(keta, num) { var src = new String(num); var cnt = keta - src.length; if (cnt <= 0) return src; while (cnt-- > 0) src = "0" + src; return src; } // IE〜8でxEventListenerが使えない仕様の回避。 var eventListener = { add: (function(w){ return w.addEventListener ? function(obj, evt, func, bool) { obj.addEventListener(evt, func, bool) } : w.attachEvent ? function(obj, evt, func, bool) { obj.attachEvent("on"+evt, func) } : function(obj, evt, func, bool) { obj["on"+evt] = func }; })(window), remove: (function(w) { return w.removeEventListener ? function(obj, evt, func, bool) { obj.removeEventListener(evt, func, bool) } : w.detachEvent ? function(obj, evt, func, bool) { obj.detachEvent("on"+evt, func) } : function(obj, evt, func, bool) { delete pbj["on"+evt] }; })(window) }; // IEでgetBoundingClientRectの値がずれる,widthがない等を修正。 // 参考 : http://d.hatena.ne.jp/terurou/20080223/1203705170 var getRect = (function(elem) { var rect = elem.getBoundingClientRect(); var pageBorderLeft = document.body.scrollLeft || document.documentElement.scrollLeft; var pageBorderTop = document.body.scrollTop || document.documentElement.scrollTop; return { left : rect.left - pageBorderLeft, top : rect.top - pageBorderTop, right : rect.right - pageBorderLeft, bottom: rect.bottom - pageBorderTop, width : rect.right - rect.left, height: rect.bottom - rect.top } }); (function(d){ var addSliderEvents = function(me, cb){ var move, mdown, mmove, mup, tstart, tmove, tend; move = function(clientX, rect){ var width = clientX - rect.left unit_with = rect.width / setting.tone; if (width<0) width = "0%"; else if(rect.width<width) width = "100%"; else { if (!setting.tone && setting.tone==0) { width = width/rect.width*100 +"%"; } else { width = ( Math.floor(width/unit_with) * unit_with ) / rect.width * 100 + "%"; } } me.firstChild.style.width = width; cb(); }; mdown = function(ev){ eventListener.add(d, 'mousemove', mmove, false); eventListener.add(d, 'mouseup', mup, false); mmove(ev); }; mmove = function(ev){ move(ev.clientX, getRect(me)); }; mup = function(ev){ eventListener.remove(d, 'mousemove', mmove, false); eventListener.remove(d, 'mousedown', mup, false); }; eventListener.add(me, 'mousedown', mdown, false); tstart = function(ev){ eventListener.add(d, 'touchmove', tmove, false); eventListener.add(d, 'touchend', tend, false); tmove(ev); } tmove = function(ev){ ev.preventDefault(); move(ev.touches[0].clientX, me.getBoundingClientRect()); }; tend = function(ev){ eventListener.remove(d, 'touchmove', tmove, false); eventListener.remove(d, 'touchend', tend, false); }; eventListener.add(me, 'touchstart', tstart, false); }; var changecolor = function() { var rgb = d.getElementById('rgb'); var bgcolor = (function(bg) { for(var i=0,rgb=['r','g','b']; i<rgb.length; i++ ) { bg+= Math.round( document.getElementById(rgb[i]+'slider') .firstChild.style.width.replace(/%/,'') / 100 * 255 ) + ','; } return ('rgb('+bg.replace(/,$/,')')); })(''); rgb.style.backgroundColor = rgb.innerHTML = bgcolor; }; for(var i=0, rgb=['r','g','b']; i < rgb.length; i++ ) { addSliderEvents(d.getElementById(rgb[i] + 'slider'), changecolor); } // 初期化。 window.onload = function() { if (setting.initial.red) document.getElementById("rslider").firstChild.style.width = setting.initial.red; if (setting.initial.green) document.getElementById("gslider").firstChild.style.width = setting.initial.green; if (setting.initial.blue) document.getElementById("bslider").firstChild.style.width = setting.initial.blue; changecolor(); }; })(document); </script> </body> </html>