我目前正在开发一个涉及使用输入范围元素的 HTML 界面。在电子音乐制作中,通常能够使用 Alt 或 Shift 等特殊键微调控制值。根据我的理解,纯 HTML 输入范围似乎不太可能默认支持此功能。然而,在深入研究使用 Vue.js 这样的框架寻找解决方案之前,我想确认是否可以在纯 HTML 中实现此功能。
此外,我希望避免涉及使用 HTML canvas 元素的次优解决方案。虽然我知道这可能是一个潜在的解决方案,但我想首先探索其他可能性。
任何人都可以提供在纯 HTML 输入范围内实现微调功能的指导、建议或见解吗?在开始使用 Vue.js 特定的解决方案之前,我希望知道是否可行。谢谢!
您可以自己处理鼠标事件:
const prop = Object.getOwnPropertyDescriptor(Object.getPrototypeOf($range), 'value');
const _set = prop.set;
prop.set = function(val){
if(val < $range.min){
val = $range.min;
}else if(val > $range.max){
val = $range.max;
}
$value.textContent = val;
_set.call($range, val);
};
Object.defineProperty($range, 'value', prop);
let control = false;
document.addEventListener('keydown', e => {
e.key = 'Control' && !e.repeat && start && (control = true) && setStart(event);
});
document.addEventListener('keyup', e => {
e.key = 'Control' && (control = false);
});
$range.value = 0;
const width = $range.offsetWidth;
let start, startVal;
let event;
const setStart = e => {
start = e.pageX;
const rect = $range.getBoundingClientRect();
const val = (start - rect.left) / rect.width * 1000;
$range.value = startVal = val;
}
$container.addEventListener('mousedown', setStart);
document.addEventListener('mousemove', e => {
event = e;
if(!start){
return;
}
let delta = e.pageX - start;
if(control){
delta = delta/10;
}
const rect = $range.getBoundingClientRect();
delta = delta / rect.width * 1000;
$range.value = startVal + delta;
});
document.addEventListener('mouseup', e => {
start = null;
});
input{
pointer-events: none;
}
<p>Audio settings:</p>
<div>
<div id="$container" style="display:inline-block">
<input id="$range" type="range" id="volume" name="volume"
min="0" max="1000">
</div>
<label for="volume">Volume</label>
<div id="$value"></div>
</div>