Matt
Matt

Reputation: 843

Vue range slider manual change overridden by incremental change event?

I'm using a BootstrapVue range slider in a custom media player component, representing the playback position of the media. The slider is v-model bound to playbackPosition, which is incrementally updated by an event listener as the media plays, causing the slider handle to predictably creep along. (The event is emitted by a 3rd party library.)

When I manually adjust the range slider, it sets the playbackPosition, and everything works fine - as long as the media isn't already playing.

If it's already playing, the incremental event continuously updates the playbackPosition, which forces my range slider handle to go where I don't want it, before I have a chance to release the handle. And, of course, I can't replace the change listener with an input listener, because the incremental update is recognized as an input, which causes the playback to go haywire.

How can I make the range slider move on its own to reflect the playback position, but also allow setting the position manually by sliding the handle?

Upvotes: 3

Views: 901

Answers (1)

Tomhah
Tomhah

Reputation: 386

Is it practical for the position of the slider should be controlled entirely by your third party library? As you drag the slider, tell the library to update its position in the track but don't manually update the slider position, which will in turn cause the library to emit a new position event which will then your slider position.

There is the possibility however that if the position events are not emmitted (relatively) immediately upon the position changing, that the slider would appear to lag behind the position you are dragging to. In this case you could maintain one data property which holds the position from your 3rd party library, and a second data property which holds the position the user is dragging the slider to, and use a computed property to control the actual position of your slider. Something like this:

data() {
  return {
    trackPosition: 0,
    userPosition: null,
  }
},
computed: {
  sliderPosition() {
    return this.userPosition !== null ? this.userPosition : this.trackPosition;
  }
}

Now when you begin manually moving the slider around, set a value for userPosition, and sliderPosition will match the new position instead of the current track position. When you are done moving the slider around and perhaps instructing the third party library to change track position, set userPosition to null, and sliderPosition will now go back to matching the position given by your third party library.

Upvotes: 1

Related Questions