js实现元素范围内拖动
元素拖拽,网上一堆的实现,其中很多是原生js写的,都不够简洁,甚至运行后看不到效果。
于是乎,安静地想了下,拖动元素貌似就是一个滑动事件的监听处理,具体操作如下:
1、一个外层DIV,或者直接用根节点代替。
2、一个可拖动的元素,设置一个选择器,如下设置的是class="obj"。
3、元素css设置绝对定位,相对于影响其定位的父元素做范围内可拖拽
注:例子中相对于网页可见高宽的范围移动,所以用到了document.documentElement的高宽,如果其父元素是swiper插件的滑块,可以给元素再加个"swiper-no-swiping"类名,具体看swiper禁止切换文档,以保证拖动时的良好体验。
$(".obj").on("touchmove", function(e) {
e.preventDefault();
var moveEndX = e.originalEvent.changedTouches[0].pageX;
var moveEndY = e.originalEvent.changedTouches[0].pageY;
var xMM = moveEndX - $(this).width() / 2;
var yMM = moveEndY - $(this).height() / 2;
if(xMM < document.documentElement.clientWidth - $(this).width() && xMM > 0){
$(this).css("left",xMM+"px");
}
if(yMM < document.documentElement.clientHeight - $(this).height() && yMM > 0){
$(this).css("top",yMM+"px");
}
});
没错,就是这么简单,这是用jquery实现的,别忘了引入jquery库,以下是关于触摸事件和手势事件的一些简介,多了解下还是很有用的。
内容摘自javaScript高级程序设计手册:
iOS 版Safari 为了向开发人员传达一些特殊信息,新增了一些专有事件。因为iOS 设备既没有鼠标也没有键盘,所以在为移动Safari 开发交互性网页时,常规的鼠标和键盘事件根本不够用。随着Android中的WebKit 的加入,很多这样的专有事件变成了事实标准,导致W3C 开始制定Touch Events 规范(参见https://dvcs.w3.org/hg/webevents/raw-file/tip/touchevents.html)。以下介绍的事件只针对触摸设备。
1. 触摸事件
包含iOS 2.0 软件的iPhone 3G 发布时,也包含了一个新版本的Safari 浏览器。这款新的移动Safari提供了一些与触摸(touch)操作相关的新事件。后来,Android 上的浏览器也实现了相同的事件。触摸事件会在用户手指放在屏幕上面时、在屏幕上滑动时或从屏幕上移开时触发。具体来说,有以下几个触摸事件。
- touchstart:当手指触摸屏幕时触发;即使已经有一个手指放在了屏幕上也会触发。
- touchmove:当手指在屏幕上滑动时连续地触发。在这个事件发生期间,调用preventDefault()可以阻止滚动。
- touchend:当手指从屏幕上移开时触发。
- touchcancel:当系统停止跟踪触摸时触发。关于此事件的确切触发时间,文档中没有明确说明。
上面这几个事件都会冒泡,也都可以取消。虽然这些触摸事件没有在DOM 规范中定义,但它们却是以兼容DOM 的方式实现的。因此,每个触摸事件的event 对象都提供了在鼠标事件中常见的属性:
bubbles、cancelable、view、clientX、clientY、screenX、screenY、detail、altKey、shiftKey、ctrlKey 和metaKey。
除了常见的DOM属性外,触摸事件还包含下列三个用于跟踪触摸的属性。
- touches:表示当前跟踪的触摸操作的Touch 对象的数组。
- targetTouchs:特定于事件目标的Touch 对象的数组。
- changeTouches:表示自上次触摸以来发生了什么改变的Touch 对象的数组。
每个Touch 对象包含下列属性。
- clientX:触摸目标在视口中的x 坐标。
- clientY:触摸目标在视口中的y 坐标。
- identifier:标识触摸的唯一ID。
- pageX:触摸目标在页面中的x 坐标。
- pageY:触摸目标在页面中的y 坐标。
- screenX:触摸目标在屏幕中的x 坐标。
- screenY:触摸目标在屏幕中的y 坐标。
- target:触摸的DOM 节点目标。
使用这些属性可以跟踪用户对屏幕的触摸操作。来看下面的例子。
function handleTouchEvent(event) {
//只跟踪一次触摸
if (event.touches.length == 1) {
var output = document.getElementById("output");
switch (event.type) {
case "touchstart":
output.innerHTML = "Touch started (" + event.touches[0].clientX + "," + event.touches[0].clientY + ")";
break;
case "touchend":
output.innerHTML += "<br>Touch ended (" + event.changedTouches[0].clientX + "," + event.changedTouches[0].clientY + ")";
break;
case "touchmove":
event.preventDefault(); //阻止滚动
output.innerHTML += "<br>Touch moved (" + event.changedTouches[0].clientX + "," + event.changedTouches[0].clientY + ")";
break;
}
}
}
EventUtil.addHandler(document, "touchstart", handleTouchEvent);
EventUtil.addHandler(document, "touchend", handleTouchEvent);
EventUtil.addHandler(document, "touchmove", handleTouchEvent);
以上代码会跟踪屏幕上发生的一次触摸操作。为简单起见,只会在有一次活动触摸操作的情况下输出信息。当touchstart 事件发生时,会将触摸的位置信息输出到<div>元素中。当touchmove 事件发生时,会取消其默认行为,阻止滚动(触摸移动的默认行为是滚动页面),然后输出触摸操作的变化信息。而touchend 事件则会输出有关触摸操作的最终信息。注意,在touchend 事件发生时,touches集合中就没有任何Touch 对象了,因为不存在活动的触摸操作;此时,就必须转而使用changeTouchs集合。
这些事件会在文档的所有元素上面触发,因而可以分别操作页面的不同部分。在触摸屏幕上的元素时,这些事件(包括鼠标事件)发生的顺序如下:
- (1) touchstart
- (2) mouseover
- (3) mousemove(一次)
- (4) mousedown
- (5) mouseup
- (6) click
- (7) touchend
支持触摸事件的浏览器包括iOS 版Safari、Android 版WebKit、bada 版Dolfin、OS6+中的BlackBerryWebKit、Opera Mobile 10.1+和LG 专有OS 中的Phantom 浏览器。目前只有iOS 版Safari 支持多点触摸。桌面版Firefox 6+和Chrome 也支持触摸事件。
2. 手势事件
iOS 2.0 中的Safari 还引入了一组手势事件。当两个手指触摸屏幕时就会产生手势,手势通常会改变显示项的大小,或者旋转显示项。有三个手势事件,分别介绍如下。
- gesturestart:当一个手指已经按在屏幕上而另一个手指又触摸屏幕时触发。
- gesturechange:当触摸屏幕的任何一个手指的位置发生变化时触发。
- gestureend:当任何一个手指从屏幕上面移开时触发。
只有两个手指都触摸到事件的接收容器时才会触发这些事件。在一个元素上设置事件处理程序,意味着两个手指必须同时位于该元素的范围之内,才能触发手势事件(这个元素就是目标)。由于这些事件冒泡,所以将事件处理程序放在文档上也可以处理所有手势事件。此时,事件的目标就是两个手指都位于其范围内的那个元素。
触摸事件和手势事件之间存在某种关系。当一个手指放在屏幕上时,会触发touchstart 事件。如果另一个手指又放在了屏幕上,则会先触发gesturestart 事件,随后触发基于该手指的touchstart事件。如果一个或两个手指在屏幕上滑动,将会触发gesturechange 事件。但只要有一个手指移开,就会触发gestureend 事件,紧接着又会触发基于该手指的touchend 事件。
与触摸事件一样,每个手势事件的event 对象都包含着标准的鼠标事件属性:bubbles、cancelable、view、clientX、clientY、screenX、screenY、detail、altKey、shiftKey、ctrlKey 和metaKey。此外,还包含两个额外的属性:rotation 和scale。其中,rotation 属性表示手指变化引起的旋转角度,负值表示逆时针旋转,正值表示顺时针旋转(该值从0 开始)。而scale属性表示两个手指间距离的变化情况(例如向内收缩会缩短距离);这个值从1 开始,并随距离拉大而增长,随距离缩短而减小。
下面是使用手势事件的一个示例。
function handleGestureEvent(event) {
var output = document.getElementById("output");
switch (event.type) {
case "gesturestart":
output.innerHTML = "Gesture started (rotation=" + event.rotation + ",scale=" + event.scale + ")";
break;
case "gestureend":
output.innerHTML += "<br>Gesture ended (rotation=" + event.rotation + ",scale=" + event.scale + ")";
break;
case "gesturechange":
output.innerHTML += "<br>Gesture changed (rotation=" + event.rotation + ",scale=" + event.scale + ")";
break;
}
}
document.addEventListener("gesturestart", handleGestureEvent, false);
document.addEventListener("gestureend", handleGestureEvent, false);
document.addEventListener("gesturechange", handleGestureEvent, false);
与前面演示触摸事件的例子一样,这里的代码只是将每个事件都关联到同一个函数中,然后通过该函数输出每个事件的相关信息。
触摸事件也会返回rotation 和scale 属性,但这两个属性只会在两个手指与屏幕保持接触时才会发生变化。一般来说,使用基于两个手指的手势事件,要比管理触摸事件中的所有交互要容易得多。
js实现元素范围内拖动的更多相关文章
- 原生js获取元素非行内样式属性的方法
获取当前对象的样式DOM标准中的全局方法 getComputedStyle(obj).width (获取元素的宽度),但在非标准IE浏览器(IE8)以下有兼容问题IE8以下要这样写 obj.curre ...
- .NET前后台-JS获取/设置iframe内对象元素并进行数据处理
转载请注明出处:果冻栋吖 这个主要是修改H3BPM一个批量审批的功能时候做的.先看下图: H3自带了批量审批的功能,也就是按钮1,有审批意见3,但是如果3里边不填写内容点击1之后,效果就是表单里边没有 ...
- 【全面总结】js获取元素位置大小
[js获取元素位置+元素大小]全面总结 目录 1.关于offset offsetParent(只读) offsetTop(只读) offsetLeft(只读) offsetHeight(只读) off ...
- js获取元素transform参数得出的个人理解
之前写页面的时候有试过想用js获取某些元素的translate的数值什么的,但是translate又是transform的子样式(勉强说说),理所当然就是先获取transform样式,再读里面的值. ...
- Js获取元素样式值(getComputedStyle¤tStyle)兼容性解决方案
因为:style(document.getElementById(id).style.XXX)只能获取元素的内联样式,内部样式和外部样式使用style是获取不到的. 一般js获取内部样式和外部样式使用 ...
- JS子元素oumouseover触发父元素onmouseout
原文:JS子元素oumouseover触发父元素onmouseout JavaScript中,父元素包含子元素: 当父级设置onmouseover及onmouseout时,鼠标从父级移入子级,则触发父 ...
- js获取元素位置和style的兼容性写法
今天说一下js获取元素位置和style的方法.当然不只是element.style那么简单.. 主角:getBoundingClientRect,getClientRects,getComputedS ...
- mongodb对数组元素及内嵌文档进行增删改查操作(转)
from:https://my.oschina.net/132722/blog/168274 比如我有一个user类,他包含一个标签属性,这个标签是一个数组,数组里面的元素是内嵌文档,格式如下: &l ...
- JS获取元素宽高的两种情况
JS获取元素宽高分两种情况, 一.内联样式,也就是直接把width和height写在HTML元素中的style里: 这种情况使用 document.getElementById('xxx'). ...
随机推荐
- 链表(LinkedList)解题总结
链表基础知识 定义 链表(Linked List)是一种常见的基础数据结构,是一种线性表,但是并不会按线性的顺序存储数据,而是在每一个节点里存到下一个节点的指针(Pointer). 链表的操作 操作 ...
- deepin V20 简易入门指南
deepin V20 入坑指南 系统安装 入坑第一步自然是先安装系统了,deepin的安装方式很简单只需要一个U盘即可,在官网下载好安装镜像文件,使用官方的启动盘制作工具,开机时选择从U盘启动即可,安 ...
- Java编发编程 - 线程池的认识(一)
每逢面试都会询问道线程池的概念和使用,但是工作中真正的又有多少场景使用呢?相信大家都会有这样的疑问:面试选拔造汽车,实际进公司就是拧螺丝!但是真正要把这颗螺丝拧紧,拧牢,没有这些最底层的知识做铺垫你可 ...
- [代码审计Day1] in_array代码审计
简介 1 简介 in_array() 函数搜索数组中是否存在指定的值. 语法:in_array(search,array,type) 参数 描述 search 必需.规定要在数组搜索的值. arra ...
- 做了两年java,这些高性能高可用高并发的技术架构你都知道吗?
前言 每一个模式描述了一个在我们周围不断重复发生的问题及该问题解决方案的核心.这样,你就能一次又一次地使用该方案而不必做重复工作. 所谓网站架构模式即为了解决大型网站面临的高并发访问.海量数据.高可靠 ...
- 02python开发之基本运算符
02 python开发之基本运算符 目录 02 python开发之基本运算符 2 基本运算符 2.1 算数运算符 2.1.1 种类 2.1.2 用法 2.2 比较运算符 2.2.1 种类 2.2.2 ...
- Guitar Pro 7教程之如何导入吉他谱
在前面的章节小编为大家也讲解了不少关于Guitar Pro 的相关教程,譬如{cms_selflink page='index' text='Guitar Pro下载'},安装等等一系列的使用教程,前 ...
- MyBatis的一二级缓存
一级缓存 一级缓存默认是开启的,生命周期和SqlSession相同.一个会话中每次执行一个查询操作时,会先查询二级缓存,如果二级缓存没查到或者二级缓存未开启就会从一级缓存中查询,如果一级缓存也未查到就 ...
- selenium+python自动化元素定位
最近学习自动化测试,终于初步学习完成,需要进行博客日志总结,加深巩固自己的知识. 元素的八种定位方式 1.id 以百度为例子 我们在python输入的元素定位语法:bs.find_element_by ...
- Java基础教程——Map
Map 返回类型 方法 描述 V get(Object key) 根据key取得value V put(Obejct k,Object v) 向Map中加入(替换)元素,返回之前的Value:之前没有 ...