【问题标题】:Get percentage clicked of elements width along the x-axis获取沿 x 轴的元素宽度的点击百分比
【发布时间】:2019-09-22 19:17:30
【问题描述】:

我的页面结构如下图所示。单击#progress 元素中的任意位置时,我想计算被单击的全宽百分比。

如何做到这一点?

< div id="progress" onMouseUp={ e => this._seekTo(e) }></div>

...

_seekTo(event) {
    var progress = document.getElementById('progress');
    console.log((event.clientX - progress.offsetLeft) / progress.offsetWidth * 100)
}

【问题讨论】:

  • 是的,#progress 宽度约为 500 像素,输出数字在 ~150 到 ~300 之间。我没有在元素上启用填充
  • @RolandStarke 谢谢你的解释。它现在很完美!

标签: javascript html width mouseevent percentage


【解决方案1】:

您可以获取元素宽度沿 x 轴的百分比点击位置,例如:

document.getElementById('progress').addEventListener('click', function(e) {
    var bcr = this.getBoundingClientRect();
    console.log('You clicked to ', (e.clientX - bcr.left) / bcr.width);
});

使用e.clientXelement.offsetLeft 计算时的问题在于它们代表两种不同的东西。

element.offsetLeft 是一个整数,表示距离最近的相对定位的父元素向左的偏移量(以像素为单位)。 source

e.clientX 提供应用程序客户区域内发生事件的水平坐标(与页面内的坐标相对)。 source

例如,如果用户垂直滚动,这会导致问题。您可以使用e.pageX,那么两者都基于DOM,但您仍然需要总结来自element 的父级的所有offsetLefts,以便两个位置都相对于整个文档的左边缘。

进度条示例:

function mouseSliderPosition(element, e) {
    var bcr = element.getBoundingClientRect();
    return {
        x: Math.min(Math.max(0, (e.clientX - bcr.left) / bcr.width), 1),
        y: Math.min(Math.max(0, (e.clientY - bcr.top) / bcr.height), 1)
    }
};

function activateSlider(e) {
    if (e.touches && e.touches.length > 1) {
        return;
    }
    e.preventDefault();

    window.activeSlider = this;
    handleSliderMove(e);
}


function handleSliderMove(e) {
    if (e.touches && e.touches.length > 1) {
        return;
    }
    if (window.activeSlider) {
        var progressBar = window.activeSlider.getElementsByClassName('progress-bar')[0];
        var progressFill = window.activeSlider.getElementsByClassName('progress-fill')[0];
        var value = mouseSliderPosition(progressBar, e.touches && e.touches[0] || e).x;
        progressFill.style.transform = 'scaleX(' + value + ')';
    }
}

function deactivateSlider(e) {
    if (e.touches && e.touches.length > 0) {
        return;
    }
    this.activeSlider = null;
}


document.querySelector('.progress-slider').addEventListener('mousedown', activateSlider)
document.querySelector('.progress-slider').addEventListener('touchstart', activateSlider)
window.addEventListener('mousemove', handleSliderMove);
window.addEventListener('mouseup', deactivateSlider);
window.addEventListener('touchmove', handleSliderMove);
window.addEventListener('touchend', deactivateSlider);
window.activeSlider = null;
.progress-slider {
    padding: 10px;
    cursor: pointer;
}

.progress-bar {
    height: 2px;
    background: rgba(100,100,100,0.5);
}

.progress-slider:hover .progress-bar {
    height: 3px;
}

.progress-fill {
    height: 100%;
    background: rgba(255, 0, 0, 0.7);
    transform-origin: 0 50%;
    transform: scaleX(0);
}
<div class="progress-slider">
  <div class="progress-bar"><div class="progress-fill"></div></div>
</div>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-04-22
    • 1970-01-01
    • 2014-06-21
    • 2012-05-24
    • 2018-10-15
    • 2016-10-24
    • 2015-10-16
    • 2012-06-24
    相关资源
    最近更新 更多