获取沿x轴元素宽度的点击百分比

时间:2019-05-04 14:15:41

标签: javascript html width mouseevent percentage

我的页面结构如下图所示。在<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet"/> <label for="your-name"> Your Name (required) <i class="fa fa-users"></i><span class="wpcf7-form-control-wrap your-name"><input type="text" name="your-name" value="" size="40" class="wpcf7-form-control wpcf7-text wpcf7-validates-as-required form-control" id="your-name" aria-required="true" aria-invalid="false"></span> </label>元素中的任意位置单击时,我想计算单击的全角的百分比。

这怎么办?

#progress

...

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

example

1 个答案:

答案 0 :(得分: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,但是您仍然需要对offsetLeft的父代中的所有element进行汇总,以便两个位置都相对于左侧整个文档的边缘。

示例进度栏:

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>

相关问题