RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 1320771
Accepted
Meth0d
Meth0d
Asked:2022-08-24 04:09:18 +0000 UTC2022-08-24 04:09:18 +0000 UTC 2022-08-24 04:09:18 +0000 UTC

拖动音频播放器滑块

  • 772

我有一个由我设计的自定义播放器。通过单击进度条,可以倒带音频文件。我还想这样做,以便在拖动滑块时,音频文件被倒带。因此,从视觉上看,它无法从容器中拉出。我也想知道如果没有 , 是否可以做到这一点input,因为。我最初没有使用它。拖动时跟踪什么事件也很有趣。一个非常简单的例子来说明如何做到这一点就足够了。

这是一个示例https://jsfiddle.net/dftx5b8n/

.range {
  width: 200px;
  height: 10px;
  border-radius: 12px;
  background-color: darksalmon;
}
.line {
  width: 30%;
  height: 10px;
  border-radius: 12px;
  background-color: aquamarine;
  position: relative;
}
.circle {
  position: absolute;
  right: -7px;
  top: -3px;
  width: 14px;
  height: 14px;
  border-radius: 50%;
  background-color: #f7f8fa;
  border: 2px solid blue;
}
<div class="range">
  <div class="line">
    <div class="circle"></div>
  </div>
</div>

javascript
  • 1 1 个回答
  • 10 Views

1 个回答

  • Voted
  1. Best Answer
    Иван Поднебесный
    2022-08-25T01:19:01Z2022-08-25T01:19:01Z

    让你成为一个范围。演示在这里。这是JS:

    class Range{
      constructor(parent, handler, {from = 0, to = 100, step = 1, defaultValue = null} = {})
      {
        //навешиваем все заданные значения
        this.from = from;
        this.to = to;
        this.step = step;
        this.handler = handler.bind(this);
        
        //готовим свойства для будущей записи
        this.value;
        this.persentValue;
        
        //определяем шаг в процентах
        this.persentStep = step * 100 / (this.to - this.from);
        
        //свойства в которых будем хранить dom узлы
        this._parent = parent;
        this._wrap;
        this._range;
        this._progressLine;
        this._offsetPointer;
        
        //создаем dom нашего range
        this._createHTML();
        //устанавливаем дефолтное знание
        this._setDefaultValue(defaultValue);
      }
      //считаем сколько шагов поместится в значение | нужно для того чтобы значения были кратны нашем шагу (любое некратное мы преобразовываем в ближайшее кратное)
       _countSteps(value)
      {
        return Math.round(value/this.persentStep);
      }
      //берем процентное значение об обычного значения
      _getPersentValue(value)
      {
        let fullPersentValue = ((value - this.from) * 100)/(this.to - this.from);
        let perstentStepsCount = this._countSteps(fullPersentValue);
        return perstentStepsCount * this.persentStep;
      }
      //устанавливаем дефалтное значение
      _setDefaultValue(defaultValue)
      {
        let persentDefaultValue;
        //если больше или меньше устанавливаем максимальное или минимальное процентное значение соответственно
        if(!defaultValue || defaultValue <= this.from ) persentDefaultValue = 0;
        else if(defaultValue >= this.to) persentDefaultValue = 100;
        //если в рамках тогда переводим дефалтное значение в процентную форму
        else persentDefaultValue = this._getPersentValue(defaultValue);
       
       //устанавливаем процентное значение
        this._setPersentValue(persentDefaultValue);
      }
      //тут создаем наш dom
      _createHTML()
      {
        this._wrap = document.createElement("div");
        this._wrap.className = "wrap";
        this._range = document.createElement("div");
        this._range.className = "range";
        this._progressLine = document.createElement("div");
        this._progressLine.className = "progress-line";
        this._offsetPointer = document.createElement("div");
        this._offsetPointer.className = "offset-pointer";
        
        this._progressLine.appendChild(this._offsetPointer);
        this._range.appendChild(this._progressLine);
        this._wrap.appendChild(this._range);
        this._parent.appendChild(this._wrap);
        //тут будем вешать обработчики событий
        this._setOnMoveHandler();
      }
      //тут устанавливаем обычное значение
      _setValue(value)
      {
        this.value = value;
        this.handler(this.value, this.persentValue);
      }
      //это используюем для внешней установки значения
      setValue(value)
      {
        //переводим наше значение в процентную форму
        this._setDefaultValue(value);
      }
      //устанавливаем процентное значение
      _setPersentValue(persentValue)
      {
        this.persentValue = persentValue;
        //переводим процент в обыкновенное значение
        let newValue = this.from + (this.persentValue * (this.to - this.from))/100;
        //тут отображаем наш progress-line
        this._setRangeOffset();
        //устанавливаем обычное значение
        this._setValue(newValue);
      }
      //отображаем progress-line
      _setRangeOffset()
      {
        this._progressLine.style.width = `${this.persentValue}%`;
      }
      //навешиваем нужные обработчики
      _setOnMoveHandler()
      {
        //движение начинается по событию mousedown на range
        function startMoving(e)
        {
          //берем координаты нашего range и получаем все прочие параметры
          const rangeCords = this._range.getBoundingClientRect();
          const rangeRight = rangeCords.right;
          const rangeLeft = rangeCords.left;
          const rangeWidth = rangeRight - rangeLeft;
          //обработчик mousemove по окну
          const Moving = function(e)
          {
            //смотрим какой x у нашего курсора
            const x = e.clientX;
            let _persentValue;
            //если x меньше или больше начала или конца нашего range тогда соответственно ставим минимальное или максимальное значение
            if(x <= rangeLeft) _persentValue = 0;
            else if(x >= rangeRight) _persentValue = 100;
            //в противном случае берем разницу x - rangeLeft и переводим ее в процент с учетом кратности шага
            else{
              let offsetValue = x - rangeLeft;
              let fullPersentValue = (offsetValue * 100)/rangeWidth;
              let persentStepsCount = this._countSteps(fullPersentValue);
              _persentValue = persentStepsCount * this.persentStep;
            }
            //устанавливаем процентное значение
            this._setPersentValue(_persentValue);
          }.bind(this);
          //вызываем функцию при клике (это нужно чтобы обработчик сработал даже если пользователь просто кликнет по range)
          Moving(e);
          //функция для подчистки всех наших обработчиков после того как пользователь закончит работу с ползунком
          function Cleaning()
          {
            window.removeEventListener("mousemove", Moving);
            window.removeEventListener("mouseup", Cleaning);
          }
          //навешиваем событие на движение мыши по окну 
          window.addEventListener("mousemove", Moving);
          //удаляем все события после того как кнопка мыши отжата
          window.addEventListener("mouseup", Cleaning);
        }
        //навешим события на клик по range
        this._range.addEventListener("mousedown", startMoving.bind(this))
      }
    }
    
    • 1

相关问题

  • 第二个 Instagram 按钮的 CSS 属性

  • 由于模糊,内容不可见

  • 弹出队列。消息显示不正确

  • 是否可以在 for 循环中插入提示?

  • 如何将 JSON 请求中的信息输出到数据表 Vuetify vue.js?

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    表格填充不起作用

    • 2 个回答
  • Marko Smith

    提示 50/50,有两个,其中一个是正确的

    • 1 个回答
  • Marko Smith

    在 PyQt5 中停止进程

    • 1 个回答
  • Marko Smith

    我的脚本不工作

    • 1 个回答
  • Marko Smith

    在文本文件中写入和读取列表

    • 2 个回答
  • Marko Smith

    如何像屏幕截图中那样并排排列这些块?

    • 1 个回答
  • Marko Smith

    确定文本文件中每一行的字符数

    • 2 个回答
  • Marko Smith

    将接口对象传递给 JAVA 构造函数

    • 1 个回答
  • Marko Smith

    正确更新数据库中的数据

    • 1 个回答
  • Marko Smith

    Python解析不是css

    • 1 个回答
  • Martin Hope
    Alexandr_TT 2020年新年大赛! 2020-12-20 18:20:21 +0000 UTC
  • Martin Hope
    Alexandr_TT 圣诞树动画 2020-12-23 00:38:08 +0000 UTC
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5