【CSS】input type='range' のカスタマイズ
input rangeを自作しました。
::-webkit-slider-thumb
は非推奨のようなので、スライダーの"ポチ"も自作。
https://developer.mozilla.org/ja/docs/Web/CSS/::-webkit-slider-thumb
〇コード
<style>
.range_wrapper {
width:70%;
position:relative;
margin:20px;
}
.sub_wrapper {
display: block;
width: 100%;
height:50px;
padding: 0px;
text-decoration: none;
background: ;
}
.range_balloon {
position: absolute;
display: none;
text-align:center;
padding: 0 2px;
background-color: rgba(82, 82, 82, 0.5);
color:#fff;
width:40px;
left : 47%;
bottom : 100%;
margin-bottom : 5px;
font-size:;
border-radius:7px;
}
.range_wrapper:hover .range_balloon {
display:block;
}
.range_thumb {
position: absolute;
display: block;
text-align:center;
background-color: #c1ffea;
width:25px;
height:25px;
left : 50%;
top : -3%;
border-radius:50%;
box-shadow: 0px 2px 4px 0px rgba(0, 0, 0, 0.2);
cursor:pointer;
}
input[type="range"] {
-webkit-appearance: none;
appearance: none;
cursor: pointer;
outline: none;
height: 14px;
width: 100%;
border: solid 2px #C6FFFF;
border-radius:10px;
content:"";
padding:0;
}
/* ブラウザによってポチが見えるので、ブログではwidth:0; height:0;にしています。*/
/*
input[type="range"]::-webkit-slider-thumb {
-webkit-appearance: none; ;
background: #adffff;
width: 20px;
height: 20px;
border-radius: 50%;
content:"";
}
input[type="range"]::-moz-range-thumb {
background:#adffff;
width: 20px;
height: 20px;
border-radius: 50%;
box-shadow: 0px 2px 4px 0px rgba(0, 0, 0, 0.2);
border: none;
content:"";
}
input[type="range"]::-moz-focus-outer {
border: 0;
content:"";
}
input[type="range"]:active::-webkit-slider-thumb {
box-shadow: 0px 5px 10px -2px rgba(0, 0, 0, 0.3);
content:"";
}
*/
</style>
<div class="range_wrapper">
<span id="range_balloon" class="range_balloon"></span>
<div id="sub_wrapper" class="sub_wrapper">
//range_thumb で本来のポチを隠しています。
<span id="range_thumb" class="range_thumb"></span>
<input id="range" type="range" value="50" min="0" max="100">
</div>
</div>
<script>
const range = document.getElementById("range"),
text = document.getElementById("range_balloon"),
thumb = document.getElementById("range_thumb"),
sub_wrapper = document.getElementById("sub_wrapper");
let value;
let mousePosition;
let x = 0;
let rect;
let mouseFlag = false;
// あとで、スライダーのポチの位置を設定する際に rate を掛けます。
// これがないと、スライダーのポチがはみ出してしまいます。rate = 1;で確認できます。
const rate = Math.round(range.clientWidth / ( range.clientWidth + thumb.clientWidth) * 100) / 100;
let start = (e) =>{
e.preventDefault();
mouseFlag = true;
rect = range.getBoundingClientRect();
if (e.touches && e.touches[0]) {
x = (e.touches[0].clientX - window.pageXOffset - rect.left)
} else if (e.clientX && e.clientY) {
x = (e.clientX - window.pageXOffset - rect.left) //e.offsetX;
}
range.value = Math.round( x / range.clientWidth * 100 );
range.style.background = `linear-gradient(to right, #ffffe0 0%, #ffffb2 ${range.value}%, #fff ${range.value}%, #fff 100%)`
thumb.style.left = range.value * rate + "%";
}
let move = (e) => {
e.preventDefault();
rect = range.getBoundingClientRect();
if (e.touches && e.touches[0]) {
x = (e.touches[0].clientX - window.pageXOffset - rect.left)
} else if (e.clientX && e.clientY) {
x = (e.clientX - window.pageXOffset - rect.left) //e.offsetX;
}
if ( x < 0 ){
mousePosition = 0
} else if ( x > range.clientWidth){
mousePosition = 100
} else {
mousePosition = Math.round(x / range.clientWidth * 100);
}
text.style.left = mousePosition + "%"
text.innerText = mousePosition;
range.style.background = `linear-gradient(to right, #ffffe0 0%, #ffffb2 ${range.value}%, #ffffb2 ${mousePosition}%, #fff ${mousePosition}%, #fff 100%)`
if (mouseFlag){
range.value = mousePosition;
thumb.style.left = mousePosition * rate + "%";
}
}
let end = (e) => {
e.preventDefault();
mouseFlag = false;
range.style.background = `linear-gradient(to right, #ffffe0 0%, #ffffb2 ${range.value}%, #fff ${range.value}%, #fff 100%)`
}
let range_input = (e) => {
e.preventDefault();
mouseFlag = false;
range.style.background = `linear-gradient(to right, #ffffe0 0%, #ffffb2 ${range.value}%, #fff ${range.value}%, #fff 100%)`
text.style.left = range.value + "%";
text.innerText = range.value;
thumb.style.left = range.value * rate + "%";
}
sub_wrapper.ontouchstart =
sub_wrapper.onmousedown = start;
sub_wrapper.onmouseenter =
sub_wrapper.ontouchmove =
sub_wrapper.onmousemove = move;
sub_wrapper.ontouchend =
sub_wrapper.ontouchcancel =
sub_wrapper.onmouseleave = end;
sub_wrapper.onclick =
sub_wrapper.onmouseup =
range.oninput =
range.onchange = range_input;
range.style.background = `linear-gradient(to right, #ffffe0 0%, #ffffb2 ${range.value}%, #fff ${range.value}%, #fff 100%)`
thumb.style.left = range.value * rate + "%";
</script>
スライダーを縦方向にする方法。
Chrome, Opera, Safari の場合
input[type="range"] { -webkit-appearance:slider-vertical; }
IE, Edge の場合
input[type="range"] { writing-mode: bt-lr; }
Firefox の場合 orient 属性に vertical を指定します。
<input type="range" name="range" orient="vertical">
<input type="range" name="range" min="0" max="100" value="50" orient="vertical"> <style type="text/css"> input[type="range"] { -webkit-appearance:slider-vertical; writing-mode: bt-lr; height:50px; } </style>
〇 Javascriptのメモ
〇mouseleave イベントは、ポインティングデバイス (ふつうはマウス) のカーソルが要素 (Element) の外に移動したときに発行される。
- バブリングなし
- キャンセル不可
mouseleave
はバブリングしないのに対して、mouseout
はバブリングする。
〇mouseover イベントは、ポインティングデバイス (マウスやトラックパッドなど) のカーソルが要素またはその子要素のうちの一つの上を移動したときに、その要素 (Element) に発行される。
- バブリングあり
- キャンセル可
〇mouseenter イベントは、ポインティングデバイス (通常はマウス) のホットスポットが最初にイベントが発行された要素の中に移動したときにその要素 (Element) に発行される。
- バブリングなし
- キャンセル不可
〇タッチされた画面の位置取得
const rect = event.target.getBoundingClientRect() const offsetX = (event.touches[0].clientX - window.pageXOffset - rect.left) const offsetY = (event.touches[0].clientY - window.pageYOffset - rect.top)
let x = 0, y = 0; if (e.touches && e.touches[0]) { x = e.touches[0].clientX; y = e.touches[0].clientY; } else if (e.clientX && e.clientY) { x = e.clientX; y = e.clientY; }
お薦め
神様のために個性・才能を磨きたいと願うなら、神様はどこまでも私たちに力を与えてくださる(十二弟子・ミナさんの証)https://t.co/vbfjO4Qaty
— RAPT理論+α (@Rapt_plusalpha) January 5, 2023
純粋に神様を愛する人は、どんなことも問題なく行うことができると悟った感動的な体験(十二弟子・NANAさんの証)https://t.co/zw073Jl7qS
— RAPT理論+α (@Rapt_plusalpha) January 3, 2023
RAPTブログとの出会いによって、食べる時間すら神様の恵みを感じられる祝福の時間となった(十二弟子・KAWATAさんの証)https://t.co/ZvSvbDNbqy
— RAPT理論+α (@Rapt_plusalpha) January 2, 2023
RAPTブログに出会い、漫画を描く使命を頂き、大きく成長することができた今年1年(十二弟子・サキさんの証)https://t.co/imAYRuKg6m
— RAPT理論+α (@Rapt_plusalpha) December 31, 2022
驚くべき聖霊の力!! 御言葉に従うことで聖霊を受け、心身共に健康になり、猫背まで治って姿勢が改善された!!(十二弟子・ミナさんの証)https://t.co/NREhNrAGOd
— RAPT理論+α (@Rapt_plusalpha) December 30, 2022