Luka Mis
Luka Mis

Reputation: 573

Prevent mousedown event on input range html element and still let user drag slider

So is there a way to disable mousedown and / or click event on input range element but at the same time let user drag slider around and still fire on change event?

Disable clicking on line but still enable slider to be dragged around. I would like to prevent users to jump (with mousedown / click) in the middle of slider but I wanna let them drag it so value changes.

<input id="slider" name="slider" type="range" value="-1" min="-1" max="30" step="1" />

This does not help as on change for range gets called and messes up numbers.

$slider.on('mousedown', function(event) {
    //event.preventDefault();
    this.value = -1;
    /* Act on the event */
    console.log("mousedown");
});
 $slider.on('click', function(event) {
    event.preventDefault();
    this.value = -1;
    /* Act on the event */
    console.log("click");
});

If I call event.preventDefault(); on mousedown slider does not work and can not be dragged around. Is there a way around that.

I am trying to recreate this effect in html is there any jQuery effect for this kind a zoom?

Upvotes: 15

Views: 11785

Answers (5)

Unmitigated
Unmitigated

Reputation: 89294

You can use CSS pseudos-classes to give the thumb of the input pointer-events:auto (allow mouse events) and give the rest of the range input pointer-events: none (do not allow mouse events).

See: pointer-events

input[type=range]{
  pointer-events: none;
}
input[type=range]::-webkit-slider-thumb{/*Webkit Browsers like Chrome and Safari*/
  pointer-events: auto;
}
input[type=range]::-moz-range-thumb{/*Firefox*/
  pointer-events: auto;
}
input[type=range]::-ms-thumb{/*Internet Explorer*/
  pointer-events: auto;
}
<input type="range" value="0" min="0" max="100"/>

Upvotes: 22

Jax Teller
Jax Teller

Reputation: 1467

Here is my try:

//First block control click + move event
var current_value = $("#slider").val();
$("#slider").on('mousedown', function(event) {
    $("#slider").on("mousemove", function (e) {
    if ($("#slider").val() == parseInt(current_value)+1
    || $("#slider").val() == parseInt(current_value)-1) {
      current_value = $(this).val();
    } else {
      $("#slider").val(current_value);
    }
    })
});

//Second block control click on line
$("#slider").on("mouseup", function() {
      if ($("#slider").val() == parseInt(current_value)+1
    || $("#slider").val() == parseInt(current_value)-1) {
      current_value = $(this).val();
    } else {
      $("#slider").val(current_value);
    }
})

NB : if you move to fast the slider, it will jump step, and then back to initial position.

JSFiddle : https://jsfiddle.net/xpvt214o/674502/

Upvotes: 0

Roy Scheffers
Roy Scheffers

Reputation: 3908

Here's a pure CSS solution

You can control parts of the range with CSS and in that way disable the pointer events for all of those parts them except the thumb of the slider. In this way, click events are only registered when the button of the slider is clicked.

pointer-events: none;          // disable all event on the range

Use the pseudo-class selectors to target the thumb and cover all major browsers like this.

input[type=range]::-webkit-slider-thumb {   // support webkit (e.g. Chrome/Safari)
input[type=range]::-moz-range-thumb {       // support for Firefox
input[type=range]::-ms-thumb                // support for IE 

Here's how that would look in action.

$("#slider").on('mousedown', function(event) {
  console.log('Mouse-down: only fired when thumb of the range is clicked');
});
$("#slider").on('mouseup', function(event) {
  console.log('Mouse-up: only fired when thumb of the range is clicked');
});
input[type=range] {
  pointer-events: none;
}

input[type=range]::-webkit-slider-thumb {
  pointer-events: auto;
}

input[type=range]::-moz-range-thumb {
  pointer-events: auto;
}

input[type=range]::-ms-thumb {
  pointer-events: auto;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input id="slider" name="slider" type="range" value="-1" min="-1" max="30" step="1" />

More information on pointer-events can be found in the MDN docs.

Upvotes: 6

Grant
Grant

Reputation: 6329

You could use pure CSS

#slider {
    pointer-events: none;
}

Upvotes: 0

C. S.
C. S.

Reputation: 813

Why not use "mouseup" instead of "click"?

$("#slider").on('mousedown', function(event) {
    //event.preventDefault();
    /* Act on the event */
    console.log("mousedown", this.value);
});
 $("#slider").on('mouseup', function(event) {
    //event.preventDefault();
    /* Act on the event */
    console.log("mouseup", this.value);
});

Is this what you are trying to accomplish? Experiment with the fiddle if you'd like. :-)

Upvotes: -1

Related Questions