A simple slider component

Keywords: Front-end IE Firefox Mobile

Let's take a look at a picture:

There are many ways to achieve this effect, such as directly using < input type = "range" / > to modify the style, or using the following methods to modify style
HTML code:

<div class="slider">
    <button class="slider-track"></button>
    <button class="slider-thumb"></button>
</div>

CSS Style:

.slider {
    padding: 5px 0;
    position: relative;
    margin: 30px 10%;
    --percent: 0;
}

.slider-track {
    display: block;
    width: 100%;
    height: 6px;
    background-color: lightgray;
    border: 0;
    padding: 0;
}

.slider-track::before {
    content: '';
    display: block;
    height: 100%;
    background-color: skyblue;
    width: calc(1% * var(--percent));
}

.slider-thumb {
    position: absolute;
    width: 16px;
    height: 16px;
    border: 0;
    padding: 0;
    background: #fff;
    box-shadow: 0 0 0 1px skyblue;
    border-radius: 50%;
    left: calc(1% * var(--percent));
    top: 0;
    margin: auto -8px;
}`

How to generate a simple slider in the form of a component?

JS code is as follows:

class Slider {
  constructor(opts = {}) {
	this.el = opts.el;
	this.value = opts.value || 0;
	this.slider = null;
	this.render();
	this.bindEvt();
	return {
	  val: (value) => {
		this.val(value);
	  }
	}
  }
  //Render DOM
  render() {
	const container = document.querySelector(this.el);
	const slider = document.createElement('div');
	this.slider = slider;
	// Assigned if there is a default value
	if (this.value) {
	  this.val(this.value);
	}
	slider.className = "slider";
	// Track does not need focus
	slider.innerHTML = (
	  `<button class="slider-track" tabindex="-1"></button>
	  <button class="slider-thumb"></button>`
	);
	if (container) {
	  container.appendChild(slider);
	} else {
	  // If no container is specified, the DOM structure is inserted at the end of the body tag
	  document.body.appendChild(slider);
	}
  }
  // Monitoring events
  bindEvt() {
	const {slider} = this;
	const slider_track = slider.querySelector('.slider-track');
	const slider_thumb = slider.querySelector('.slider-thumb');
	let readymMove = false;
	const startHandle = e => {
	  if (e.target === slider_thumb) {
		e.stopPropagation();
		readymMove = true;
	  }
	}
	const moveHandle = e => {
	  if (readymMove) {
		this.computeVal(e);
	  }
	}
	const endHandle = () => {
	  readymMove = false
	};

	slider.addEventListener('click', e => {
	  if (e.target == slider_track) {
		this.computeVal(e);
	  }
	}, false)
	slider.addEventListener('keydown', evt => {
	  if (document.activeElement === slider_thumb) {
		let value = this.val();
		evt = (evt) ? evt : ((window.event) ? window.event : ""); //Compatible with IE and Firefox to obtain keyBoardEvent object
		var keyCode = evt.keyCode ? evt.keyCode : evt.which; //Compatible with IE and Firefox to obtain the key value of keyBoardEvent object

		switch (keyCode) {
		  //left arrow
		  case 37:
			value--;
			break;
		  //Right arrow
		  case 39:
			value++;
			break;
		}
	  }
	  this.val(value);
	}, false)
	// Start dragging
	slider.addEventListener('touchstart', startHandle);
	slider.addEventListener('mousedown', startHandle);

	// Dragging
	window.addEventListener('touchmove', moveHandle);
	window.addEventListener('mousemove', moveHandle);

	// Drag end
	window.addEventListener('touchend', endHandle);
	window.addEventListener('mouseup', endHandle);
  }
  // Calculate current value
  computeVal(e) {
	const {width, left} = this.slider.getBoundingClientRect();
	let posX = e.pageX;
	if (e.touches) { // Mobile compatible
	  posx = e.touches[0].pageX;
	}
	this.val((posX - left) / width * 100);
  }
  // Assignment & value
  val(value) {
	if (typeof value === 'undefined') {
	  // Returns the percent age value of the current slider
	  return this.slider.style.getPropertyValue('--percent').trim() || 0;
	}
	if (isNaN(value)) { // Filter illegal characters
	  return;
	}
	if (value < 0) {
	  value = 0;
	} else if (value > 100) {
	  value = 1000;
	}
	this.slider.style.setProperty('--percent', value);
  }
}

Usage:

let myslider1 = new Slider({ el: '#box '}); / / specify container
new Slider({ value: 50 });  // Default assignment
myslider1.val(value);  // js dynamic assignment
or
new Slider();  // No parameters (insert at the end of the body tag, assign 0)

The code implementation is still very simple. If you are interested, you can Click here. More basic tests are waiting for you

Posted by Daegalus on Wed, 20 Nov 2019 11:32:15 -0800