Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Determine click position on progress bar?

Is it possible to determine the value/position of a user's click on a progress bar using plain 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/

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);
});
like image 200
bobbyrne01 Avatar asked Feb 04 '15 00:02

bobbyrne01


5 Answers

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:

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>
like image 69
Josh Crozier Avatar answered Nov 20 '22 20:11

Josh Crozier


I found a simple solution with pure javascript.

using getBoundingClientRect() there are all properties to calculate the percentage.

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);
});
like image 29
Lucas Argate Avatar answered Sep 20 '22 15:09

Lucas Argate


$(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>
like image 3
Siên Avatar answered Nov 20 '22 20:11

Siên


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

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

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

});

Fiddle

like image 1
Hugo Sousa Avatar answered Nov 20 '22 20:11

Hugo Sousa


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

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

Thanks to bobbyrne01 for update corrections!

like image 1
Yeti82 Avatar answered Nov 20 '22 22:11

Yeti82