确定进度条上的点击位置?

Determine click position on progress bar?

是否可以使用普通 javascript 确定用户点击进度条的 value/position?

目前,我可以检测到对元素的点击,但只能获取栏的当前位置,与用户的点击无关。

http://jsfiddle.net/bobbyrne01/r9pm5Lzw/

HTML

<progress id="progressBar" value="0.5" max="1"></progress>

JS

document.getElementById('progressBar').addEventListener('click', function () {
    alert('Current position: ' + document.getElementById('progressBar').position);
    alert('Current value: ' + document.getElementById('progressBar').value);
});

您可以像这样获取在元素内部单击位置的坐标:

只需从点击页面的坐标中减去元素的偏移位置即可。

Updated Example

document.getElementById('progressBar').addEventListener('click', function (e) {
    var x = e.pageX - this.offsetLeft, // or e.offsetX (less support, though)
        y = e.pageY - this.offsetTop,  // or e.offsetY
        clickedValue = x * this.max / this.offsetWidth;

    console.log(x, y);
});

如果要判断点击事件是否发生在值范围内,则需要将点击的值(相对于元素的宽度)与progress元素上设置的value属性进行比较:

Example Here

document.getElementById('progressBar').addEventListener('click', function (e) {
    var x = e.pageX - this.offsetLeft, // or e.offsetX (less support, though)
        y = e.pageY - this.offsetTop,  // or e.offsetY
        clickedValue = x * this.max / this.offsetWidth,
        isClicked = clickedValue <= this.value;
    
    if (isClicked) {
        alert('You clicked within the value range at: ' + clickedValue);
    }
});
<p>Click within the grey range</p>
<progress id="progressBar" value="5" max="10"></progress>

click事件实际上是带了一个参数,这个参数包含事件信息,包括点击位置信息。您可以使用它来确定进度条中发生点击的位置。

document.getElementById('progressBar').addEventListener('click', function (event) {

    document.getElementById('result').innerHTML = ('Current position: ' + document.getElementById('progressBar').position + "<br/>");
        document.getElementById('result').innerHTML += ('Current value: ' + document.getElementById('progressBar').value + "<br/>");
        document.getElementById('result').innerHTML += ('Mouse click (absolute): ' + event.offsetX + ", " + event.offsetY + "<br/>");
});
<progress id="progressBar" value="0.5" max="1"></progress>
<div id="result"></div>

如果您想要单击的值获得通用 max 值(在本例中为 0 到 1 之间的值),您只需要一些简单的数学运算。

document.getElementById('progressBar').addEventListener('click', function (e) {

    var value_clicked = e.offsetX * this.max / this.offsetWidth;
    alert(value_clicked);

});

Fiddle

我测试了你的项目,试试这个解决方案:

document.getElementById('progressBar').addEventListener('click', function (e) {
    var x = e.pageX - this.offsetLeft;
    
    //Uncomment the following line to activate alert
    //alert('Current position: ' + document.getElementById('progressBar').position);
    
    //Save position before the click
    var startPos = document.getElementById('progressBar').position;
    
    //Convert x value to progress range [0 1]
    
    var xconvert = x/300; //cause width is 300px and you need a value in [0,1] range
    var finalx = (xconvert).toFixed(1); //round up to one digit after coma
    
    //Uncomment the following line to activate alert
    //alert('Click value: ' + finalx);
  
    //If you don't want change progress bar value after click comment the following line
    document.getElementById('progressBar').value = finalx;
    
    document.getElementById('result').innerHTML = ('Start position: ' + startPos + "<br/><br/>");
    document.getElementById('result').innerHTML += ('Current position: ' + document.getElementById('progressBar').position + "<br/>");
    document.getElementById('result').innerHTML += ('Current value: ' + document.getElementById('progressBar').value + "<br/></br/>");
    document.getElementById('result').innerHTML += ('Real click value: ' + xconvert + "<br/>");
    document.getElementById('result').innerHTML += ('Current value set in progressbar: ' + finalx + "<br/>");
});
#progressBar {
    width:300px;
}
<progress id="progressBar" value="0.5" max="1"></progress>
<div id="result"></div>

  • 我把你的进度条宽度设置为300px(你可以改)
  • 获取进度条中的位置x
  • 将 x 位置范围从 [0,300] 转换为 [0,1]
  • 更改进度条内的值

输出:

  • 起始位置
  • 当前位置和价值(点击后)
  • 实际点击价值(未四舍五入)
  • 进度条中设置的值(四舍五入)

工作演示: http://jsfiddle.net/Yeti82/c0qfumbL

感谢bobbyrne01更新更正!

$(document).ready(function() {

  $(".media-progress").on("click", function(e) {

    var max = $(this).width(); //Get width element
    var pos = e.pageX - $(this).offset().left; //Position cursor
    var dual = Math.round(pos / max * 100); // Round %


    if (dual > 100) {
      var dual = 100;
    }


    $(this).val(dual);
    $("#progress-value").text(dual);

  });
  
  
  });
.media-progress {
  /*BG*/
  position: relative;
  width: 75%;
  display: inline-block;
  cursor: pointer;
  height: 14px;
  background: gray;
  border: none;
  vertical-align: middle;
}

.media-progress::-webkit-progress-bar {
  /*Chrome-Safari BG*/
  background: gray;
  border: none
}

.media-progress::-webkit-progress-value {
  /*Chrome-Safari value*/
  background: #17BAB3;
  border: none
}

.media-progress::-moz-progress-bar {
  /*Firefox value*/
  background: #17BAB3;
  border: none
}

.media-progress::-ms-fill {
  /*IE-MS value*/
  background: #17BAB3;
  border: none
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<progress value="5" max="100" class="media-progress"></progress>
<div id="progress-value"></div>

投票最高的答案实际上并不能普遍适用。 这是因为您必须考虑所有 offsetParents 的所有 offsetLeft。 这是一个改进的答案。希望对你有帮助。

__addProgressBarListener () {
      document.getElementById('video-player-progress-bar').addEventListener('click', function (e) {
        let totalOffset = this.offsetLeft
        let parent = this.offsetParent
        const maximumLoop = 10
        let counter = 0
        while (document.body !== parent && counter < maximumLoop) {
          counter += 1
          totalOffset += parent.offsetLeft
          parent = parent.offsetParent
        }
        const x = e.pageX - totalOffset // or e.offsetX (less support, though)
        const clickedValue = x / this.offsetWidth
        console.log('x: ', x)
        console.log('clickedValue: ', clickedValue)
      })
    },

对于那些愿意使用滑块而不是进度条的人来说,获取该值会容易得多:

HTML

<input type="range" min="0" max="100" value="50" id="slider">

JavaScript

const slider = document.getElementById('slider');
slider.onclick = () => alert('Current value: ' + slider.value);

我找到了一个简单的纯 javascript 解决方案。

使用 getBoundingClientRect() 所有属性都可以计算百分比。

document.getElementById('progressBar').addEventListener('click', function (e) {
    var bounds = this.getBoundingClientRect();
    var max = bounds.width //Get width element
    var pos = e.pageX - bounds.left; //Position cursor
    var dual = Math.round(pos / max * 100); // Round %

    console.log('percentage:', dual);
});