自定义range sliders滑块实现元素拖动方法

目录
  • 1. 使用原生 range input
  • 2. 创建自定义 range slider
    • 监听 knob 把手的 mousedown 事件,记录当前鼠标的位置。
    • 计算左侧滑条宽度
    • 移除 document 元素上的监听事件

1. 使用原生 range input

这篇文章介绍两种创建 range slider 滑块的方法。

老样子,话不多说,先上菜。

const knob = document.getElementById('knob');
// 左边的滑条
const leftSide = knob.previousElementSibling;
// 当前鼠标位置
let x = 0;
let y = 0;
let leftWidth = 0;
// 处理 mousedown 事件
const mouseDownHandler = function (e) {
  // 获取当前鼠标位置
  x = e.clientX;
  y = e.clientY;
  leftWidth = leftSide.getBoundingClientRect().width;
  // 在 `document` 上添加事件
  document.addEventListener('mousemove', mouseMoveHandler);
  document.addEventListener('mouseup', mouseUpHandler);
};
knob.addEventListener('mousedown', mouseDownHandler);
const mouseMoveHandler = function (e) {
  // 鼠标移动的距离
  const dx = e.clientX - x;
  const dy = e.clientY - y;
  const containerWidth = knob.parentNode.getBoundingClientRect().width;
  let newLeftWidth = ((leftWidth + dx) * 100) / containerWidth;
  // 限制范围在 0 - 100
  newLeftWidth = Math.max(newLeftWidth, 0);
  newLeftWidth = Math.min(newLeftWidth, 100);
  leftSide.style.width = `${newLeftWidth}%`;
};
// 当松开鼠标时触发
const mouseUpHandler = function () {
  // ...
  // 移除事件
  document.removeEventListener('mousemove', mouseMoveHandler);
  document.removeEventListener('mouseup', mouseUpHandler);
};

input 元素本身支持设置 type 属性为 range,渲染一个 slider 滑块。

<input type="range" />

它的兼容性也还不错,支持所有现代浏览器以及 IE10 以上,但是它也有一些限制,比如:

  • 你不能自定义把手(中间蓝色圆圈)
  • 并不是所有现代浏览器都支持垂直方向的 slider 滑块

也就是说,它的自定义性不是很好,如果想要自定义 slider 滑块的话,这种方式就无法满足。

另外,兼容性方面我们可以通过下面这段代码来进行检测:

const isRangeInputSupported = function () {
  const ele = document.createElement('input');
  ele.setAttribute('type', 'range');
  // 如果当前浏览器不支持 `range` input
  // `type` 属性会还原到 `text`
  return ele.type !== 'text';
};

利用浏览器本身的默认行为机制,来判断当前浏览器是否支持 range input。

2. 创建自定义 range slider

一个 slider 滑块由 3 部分组成,1 个把手和把手左右两个的 2 个滑条。

我们先构造 HTML 结构,代码如下:

<div class="container">
  <div class="left"></div>
  <div class="knob" id="knob"></div>
  <div class="right"></div>
</div>

这 3 部分元素放置在同一行展示,右边部分的滑条表示的的是 range input 的可用宽度。所以,我们可以使用如下 CSS 代码进行布局。

.container {
  /* 内容水平居中 */
  display: flex;
  align-items: center;
  height: 1.5rem;
}
.right {
  /* 可用宽度 */
  flex: 1;
  height: 2px;
}

HTML 和 CSS 结构有了,我们接着来处理拖动行为。

监听 knob 把手的 mousedown 事件,记录当前鼠标的位置。

const knob = document.getElementById('knob');
// 左边的滑条
const leftSide = knob.previousElementSibling;
// 当前鼠标位置
let x = 0;
let y = 0;
let leftWidth = 0;
// 处理 mousedown 事件
const mouseDownHandler = function (e) {
  // 获取当前鼠标位置
  x = e.clientX;
  y = e.clientY;
  leftWidth = leftSide.getBoundingClientRect().width;
  // 在 `document` 上添加事件
  document.addEventListener('mousemove', mouseMoveHandler);
  document.addEventListener('mouseup', mouseUpHandler);
};
knob.addEventListener('mousedown', mouseDownHandler);

上面的代码要注意,mousedown 事件监听在 knob 元素上,而 mousemovemouseup 事件则是监听在 document 元素上。

document 元素上的监听回调事件 mouseMoveHandlermouseUpHandler 请看下文。

计算左侧滑条宽度

当 knob 把手移动时,通过当前鼠标位置和记录的鼠标位置,我们可以知道鼠标移动的距离,这段距离就是左侧滑条的宽度。

const mouseMoveHandler = function (e) {
  // 鼠标移动的距离
  const dx = e.clientX - x;
  const dy = e.clientY - y;
  const containerWidth = knob.parentNode.getBoundingClientRect().width;
  let newLeftWidth = ((leftWidth + dx) * 100) / containerWidth;
  // 限制范围在 0 - 100
  newLeftWidth = Math.max(newLeftWidth, 0);
  newLeftWidth = Math.min(newLeftWidth, 100);
  leftSide.style.width = `${newLeftWidth}%`;
};

移除 document 元素上的监听事件

当滑动行为结束,也就是松开鼠标的时候,我们还需要移除掉 document 元素上的监听事件,防止重复监听导致的问题。

// 当松开鼠标时触发
const mouseUpHandler = function () {
  // ...
  // 移除事件
  document.removeEventListener('mousemove', mouseMoveHandler);
  document.removeEventListener('mouseup', mouseUpHandler);
};
<div style="display: flex; justify-content: center; padding: 4rem">
  <div style="width: 16rem" class="container">
    <div class="left"></div>
    <div class="knob" id="knob"></div>
    <div class="right"></div>
  </div>
</div>

以上就是自定义range sliders滑块实现元素拖动方法的详细内容,更多关于range sliders滑块元素拖动的资料请关注我们其它相关文章!

(0)

相关推荐

  • JS实现拖动滑块验证

    使用这种验证方法的目的:证明当前的用户不是机器人~防止恶意操作. 实现思路: 1.获取silde滑块(获取元素) 2.为元素注册事件———鼠标点击事件(onmousedown)鼠标点击之后获得当前鼠标的X坐标. 3.如何获取到鼠标的x坐标——使用clientX事件(当事件被触发时,鼠标指针的水平坐标). 4.鼠标移动事件发生后根据从最开始点击的X值到移动后的X值之差,作为滑块移动的差值———— 鼠标移动事件 (onmousemove): 5.获取鼠标移动之后的X坐标 6.获得初始X坐标和移动后X

  • JavaScript实现滑块验证码

    本文实例为大家分享了JavaScript实现滑块验证码的具体代码,供大家参考,具体内容如下 效果:鼠标在底部滑块上按下按住不松拖动可以移动滑块,上面大图里面带有小图背景的滑块也会跟随移动,移动到大图背景缺少区域即可完成验证.以上效果要实现,需要鼠标按下(mousedown事件),鼠标松开(mouseup事件),鼠标移动(mousemove事件)这几个事件. 先制作html部分实现静态效果,大图里面可移动的小块背景大小与大图一致,给小图块的背景添加background-position属性来控制小

  • JavaScript实现滑块验证案例

    本文实例为大家分享了JavaScript实现滑块验证的具体代码,供大家参考,具体内容如下 <!DOCTYPE html> <html lang="en">   <head>     <meta charset="UTF-8">     <meta http-equiv="X-UA-Compatible" content="IE=edge">     <meta

  • jquery对元素拖动排序示例

    完整代码:(aspx文件末尾有下载) 复制代码 代码如下: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <

  • javascript实现的元素拖动函数宿主为浏览器

    //宿主为浏览器 //将相应的元素对象的引用传到函数中 function candrag(drager) { drager.onmousedown = function (down) { var offx = drager.offsetLeft var offy = drager.offsetTop; var offxl = down.clientX - offx; var offyl = down.clientY - offy; window.condition = 0;//为window添加

  • vue实现移动滑块验证

    本文实例为大家分享了vue实现移动滑块验证的具体代码,供大家参考,具体内容如下 记录一下今天的学习内容 <div class="solidBox" :class="{'solidBox1': validation}">     <div @mousedown="solidStar" class="solid" :class="{'solid1': validation}"></

  • 自定义range sliders滑块实现元素拖动方法

    目录 1. 使用原生 range input 2. 创建自定义 range slider 监听 knob 把手的 mousedown 事件,记录当前鼠标的位置. 计算左侧滑条宽度 移除 document 元素上的监听事件 1. 使用原生 range input 这篇文章介绍两种创建 range slider 滑块的方法. 老样子,话不多说,先上菜. const knob = document.getElementById('knob'); // 左边的滑条 const leftSide = kn

  • jQuery实现获取绑定自定义事件元素的方法

    本文实例讲述了jQuery实现获取绑定自定义事件元素的方法.分享给大家供大家参考,具体如下: (function ($) { // 自定义itemtab事件 $.fn.bind = function(types, data, fn) { // 重载jQuery.fn.bind方法,用来截获绑定自定义事件的元素 if(typeof types == 'string' && 'itemtab' == types) { var itemTouchStart = -1; // touchstart

  • 关于Vue 自定义指令实现元素拖动的详细代码

    昨天在做的一个功能时,同时弹出多个框展示多个表格数据. 这些弹出框可以自由拖动.单独的拖动好实现,给元素绑定 mousedowm 事件. 这里就想到了 Vue 里面自定义指令来实现. 一.自定义指令 在使用自定义指令之前,先对自定义指令有一定的了解.从以下几个方面着手: 1.自定义指令定义范围 全局注册和组件内注册(注册的范围根据实际业务需求来) // 注册一个全局指令,可以在任何组件使用 Vue.directive('focus',{ // 当被绑定的元素插入 DOM 时 inserted:

  • JavaScript实现拖拽网页内元素的方法

    本文实例讲述了JavaScript实现拖拽网页内元素的方法.分享给大家供大家参考.具体如下: 这段代码详细讲述了JS拖拽的原理和方法,值得学习和借鉴. /** * 跨平台的事件监听函数 * @param {Node} node 需要监听事件的DOM节点 * @param {String} eventType 需要监听的事件类型 * @param {Function} callback 事件监听回调函数 * @type Function 返回值为函数类型 * @return 返回监听回调函数的引用

  • JS控制伪元素的方法汇总

    一. 缘由: 本文源于在OSC社区中,有人提问如何用jq获取伪元素.我第一想法是强大的CSS Query应该可以获取伪元素吧. 然而事实上,CSS Query并不能.即我们不能通过$(":before").$(dom).find(":before")或document.querySelector(":before")来获取:before伪元素. 为此,我不得不重新了解伪元素(Pseudo-elements).为什么不能用JS直接获取伪元素呢? 譬

  • 自己封装的一个原生JS拖动方法(推荐)

    代码: function drag(t,p){ var point = p || null, target = t || null, resultX = 0, resultY = 0; (!point)? point = target : ''; //如果没有拖动点,则拖动点默认为整个别拖动元素 function getPos(t){ var offsetLeft = 0, offsetTop = 0, offsetParent = t; while(offsetParent){ offsetL

  • Android 中TabLayout自定义选择背景滑块的实例代码

    TabLayout是Android 的Material Design包中的一个控件,可以和V4包中的ViewPager搭配产生一个联动的效果.这里我自定义了一个滑块能够跟随TabLayout进行滑动选择的SliderLayout.效果见下图(白色方框): 下面是SliderLayout的源码: import android.content.Context; import android.content.res.TypedArray; import android.graphics.drawabl

  • JS仿iGoogle自定义首页模块拖拽特效的方法

    本文实例讲述了JS仿iGoogle自定义首页模块拖拽特效的方法.分享给大家供大家参考.具体实现方法如下: 复制代码 代码如下: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999

  • C#集合遍历时删除和增加元素的方法

    本文实例讲述了C#集合遍历时删除和增加元素的方法.分享给大家供大家参考,具体如下: 大多数时候,遍历集合元素的时候并不需要对元素进行增加或者删除操作,但有些时候则需要,比如,如果集合中盛放的元素是社会上所有的人,那么有人死亡则元素删除,有人出生则是集合元素的增加.对于这种情况,遍历不能按照原来那种方式去做了,而且C#中的集合对于这类有增删动作的遍历,也不支持foreach循环. 有三种办法可以解决这一问题. 第一种方法:使用C#的LinkedList<>双链表.我原来设想,把原来链表需要删除的

随机推荐