Кастомный Range Input (Slider)

Добавлено: 07/05/2021 12:04 |  Обновлено: 07/05/2021 12:09 |  Добавил: nick |  Просмотры: 2990 Комментарии: 0
Вводная часть
Долго искал в Сети слайдер с дополнительными кнопками для установки предустановленных значений. Не нашел (искал вроде бы хорошо). Решил сделать сам. Для создания слайдера использовал Vue.js. Выкладываю здесь, может кому пригодится.
Итак, для создания кастомного Range Input или слайдера или slider’a нужны 3 составляющие, немного html, гораздо больше css и еще больше js-кода. Взболтать, но не перемешивать.

HTML

Привожу прямо в виде html-страницы, думаю, никому не помешает.
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Кастомный Range Input</title>

<link href="styles.css" rel="stylesheet">
</head>
<body>
<div id="app">

    <h1>Кастомный Range Input</h1>
    <App></App>

</div>

<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script src="script.js"></script>    
</body>
</html>

CSS

Естественно, стили даю для примера, можете менять на свое усмотрение.
#app {
  font-family: "Avenir", Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  background-color: #22283e;
  color: white;
  margin-top: 60px;
  padding: 20px;
}
.range-component .rangecontainer {
    width: 100%;
}

.range-component .rangecontainer .range {
    -webkit-appearance: none;
    appearance: none;
    width: 100%;
    height: 20px;
    border-radius: 20px;
    background: #c2c2c2;
    outline: none;
    opacity: 0.7;
    -webkit-transition: .2s;
    transition: opacity .2s;
}

.range-component .rangecontainer .range:hover {
    opacity: 1;
}

.range-component .slidecontainer .range::-webkit-range-thumb {
    -webkit-appearance: none;
    appearance: none;
    width: 18px;
    height: 18px;
    background: white;
    cursor: pointer;
    border-radius: 50%;
}

.range-component .rangecontainer .range::-moz-range-thumb {
    width: 18px;
    height: 18px;
    background: white;
    cursor: pointer;
    border-radius: 50%;
}

.button {
    background-color: #54618b;
    border: none;
    width: 7rem;
    border-radius: 25px;
    color: white;
    padding: 15px 15px;
    text-align: center;
    text-decoration: none;
    display: inline-block;
    font-size: 24px;
    opacity: 0.7;
    -webkit-transition: .2s;
    transition: opacity .2s;
    margin: 15px 5px;
}
.button:hover {
    opacity: 1;
    cursor: pointer;
}

JS

Ну и заключительная часть, та, что заставляет шевелиться html и css.
var app = Vue.extend({
  data() {
    return {
      value: 50,
    };
  },
  template: `
  <template>
    <div>
      <h2> {{ value }}% </h2>
      <range v-model="value" ref="range" :min="0" :max="100" class="range" />
      <button class="button" @click="$refs.range.setFirst(25)">25%</button>
      <button class="button" @click="$refs.range.setFirst(50)">50%</button>
      <button class="button" @click="$refs.range.setFirst(75)">75%</button>
      <button class="button" @click="$refs.range.setFirst(100)">100%</button>
    </div>
  </template>
  `
});


var range = Vue.extend({
  props: {
    value: {
      type: Number,
      required: true
    },
    min: {
      type: Number,
      required: true
    },
    max: {
      type: Number,
      required: true
    }
  },
  data(){
    return {
      currentValue: this.value
    };
  },
  methods: {
    onInput() {
      this.$emit('input', this.currentValue);
    },

    setFirst(value) {
      this.$emit('input', value);
      this.$refs['input'].value = value;
    }
  },
  template: `
<template>
  <div>
    <div class="range-component">
      <div class="rangecontainer">
        <input
          ref="input"
          v-model="currentValue"
          type="range"
          :min="min"
          :max="max"
          step="0.1"
          class="range"
          @input="onInput"
        >
      </div>
    </div>
  </div>
</template>
  `
});

Vue.component('app', app);
Vue.component('range', range);

new Vue({
  el: '#app',
});

Оставьте свой комментарий

Комментариев нет