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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/28311631/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-28 08:45:43  来源:igfitidea点击:

Determine click position on progress bar?

javascripthtmlprogress

提问by bobbyrne01

Is it possible to determine the value/position of a user's click on a progress bar using plain javascript?

是否可以使用普通的 javascript 确定用户在进度条上单击的值/位置?

Currently, I can detect a click on the element but can only get the current position of the bar, not related to the user's click.

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

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

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

HTML

HTML

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

JS

JS

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

回答by Josh Crozier

You can get the coordinates of where you clicked inside of the element like this:

您可以获得在元素内部单击的位置的坐标,如下所示:

Just subtract the offset position of the element from the coordinate of where the page was clicked.

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

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);
});

If you want to determine whether the click event occurred within the value range, you would have to compare the clicked value (in relation to the element's width), with the the value attribute set on the progress element:

如果要确定单击事件是否发生在值范围内,则必须将单击的值(相对于元素的宽度)与在 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>

回答by Siên

$(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>

回答by Hugo Sousa

If you want the value clicked for a generic maxvalue (a value between 0 and 1 in this case), you just need some simple math.

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

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

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

});

Fiddle

小提琴

回答by Yeti82

I tested your project, try this solution:

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

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>

  • I set your progress bar width to 300px (you can change it)
  • Get position x in progress bar
  • Convert x position range from [0,300] to [0,1]
  • Change value inside progress bar
  • 我将您的进度条宽度设置为 300px(您可以更改它)
  • 在进度条中获取位置 x
  • 将 x 位置范围从 [0,300] 转换为 [0,1]
  • 更改进度条内的值

Outputs:

输出:

  • Start Position
  • Current Position and Value (after click)
  • Real click value (not rounded up)
  • Value set in progressbar (rounded up)
  • 开始位置
  • 当前位置和值(点击后)
  • 实际点击值(未四舍五入)
  • 进度条中设置的值(向上取整)

Working demo: http://jsfiddle.net/Yeti82/c0qfumbL

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

Thanks to bobbyrne01for update corrections!

感谢bobbyrne01的更新更正!

回答by MatthewG

The clickevent actually takes a parameter that includes event information including the click position information. You can use this to determine where in the progress bar the click occured.

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>

回答by user2962911

The top voted answer is not actually going to work universally. This is because the you have to consider all the offsetLeft of all the offsetParents. Here is an improved answer. I hope it helps.

投票最高的答案实际上并不会普遍适用。这是因为您必须考虑所有 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)
      })
    },