用JS原生写出卷轴拖动验证码效果

1 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 =
while(offsetParent){
offsetLeft+=offsetParent.offsetL
offsetTop+=offsetParent.offsetT
offsetParent = offsetParent.offsetP
return {'top':offsetTop,'left':offsetLeft};
function core(){
var width = document.body.clientWidth || document.documentElement.clientWidth,
height = document.body.clientHeight || document.documentElement.clientH
maxWidth = width - target.offsetWidth,
maxHeight = height - target.offsetH
(resultX &= maxWidth)?
target.style.left = maxWidth+'px' :
(resultX & 0)?target.style.left = resultX +'px': ''; //重置默认位置。
(resultY &= maxHeight)?
target.style.top = maxHeight +'px' : (resultY & 0)?target.style.top = resultY +'px':''; //重置默认位置。
point.onmousedown=function(e){
var e = e || window.event,
coordX = e.clientX,
coordY = e.clientY,
posX = getPos(target).left,
posY = getPos(target).
point.setCapture && point.setCapture();
//将Mouse事件锁定到指定元素上。
document.onmousemove=function(e){
var ev = e || window.event,
moveX = ev.clientX,
moveY = ev.clientY;
resultX = moveX - (coordX - posX); //结果值是坐标点减去被拖动元素距离浏览器左侧的边距
resultY = moveY - (coordY - posY);
(resultX & 0 )?((resultX & maxWidth)?target.style.left = resultX+'px' : target.style.left = maxWidth+'px') : target.style.left = '0px';
(resultY & 0 )?((resultY & maxHeight)?target.style.top = resultY+'px' : target.style.top = maxHeight+'px') : target.style.top = '0px';
ev.stopPropagation && ev.stopPropagation();
ev.preventD
ev.returnValue = false;
ev.cancelBubble = true;
document.onmouseup=function(){
// 解决拖动时,当鼠标指向的DOM对象非拖动点元素时,无法触发拖动点的onmousedown的BUG。
document.onmousemove = null;
point.releaseCapture && point.releaseCapture();
// 将Mouse事件从指定元素上移除。
point.onmouseup=function(e){
var e = e || window.
document.onmousemove = null;
point.releaseCapture && point.releaseCapture();
window.onresize =
使用方式:
1 drag(t,p)
* t 表示被拖动的元素
* p 表示拖动点
8 // 注意:如果省略拖动点,默认可拖动的区域是整个被拖动元素
阅读(...) 评论()一聚教程网:一个值得你收藏的教程网站
原生JS实现圣旨卷轴展开效果
时间: 00:00:00
编辑:简简单单
来源:转载
在其他网站看见类似效果,但代码有400多行且看不懂,我用60多行的代码给予实现。实现原理:(1)利用绝对定位固定好起始位置;(2)利用遮罩将右轴右侧的部分遮住;(3)让右轴和遮罩同时同速度向右运动!效果图:代码如下:&
&!DOCTYPE html&&htmllang=&en&&&head&&&metacharset=&UTF-8&&&&title&诏书&/title&&&styletype=&text/&&&* {&&margin: 0;&&padding: 0;&}&#animate {&&margin: 40&&width: 495&&height: 150&&position:&&overflow:&}&#back {&&width: 495&&height: 150&&position:&&left: 0;&&top: 10&&background: url(http://cdn./notes/pics//191654mcfqzdfrxann5551.png) no-&}&#left {&&position:&&left: 0;&}&#right {&&position:&&left: 16&}&#mark {&&position:&&left: 44&}&&/style&&/head&&body&&divid=&animate&&&&divid=&back&&&imgsrc=&http://cdn./notes/pics//h47d81jyfy6vh.png&/&&/div&&&divid=&left&&&imgsrc=&http://cdn./notes/pics//191236gldigxmxg2zlh9s7.png&/&&/div&&&divid=&right&&&imgsrc=&http://cdn./notes/pics//191244uhavf49l1zw440cv.png&/&&/div&&&divid=&mark&&&imgsrc=&http://cdn./notes/pics//191254kfbz2tjupc1jigbb.png&/&&/div&&/div&&/body&&script&&var animate=document.getElementById(&animate&);&var right = document.getElementById(&right&);&var mark = document.getElementById(&mark&);&var timer = setInterval(function () {&var right1=getComputedStyle(right).&var mark1=getComputedStyle(mark).&if(parseFloat(right1)&=447){&&right1=447+&px&;&&clearInterval(timer);&}&right.style.left=(parseFloat(right1)+10)+&px&;&mark.style.left=(parseFloat(mark1)+10)+&px&;&}, 100)&/script&&/html&&原生JavaScript与jQuery(绝对、相对定位)实现拖拽效果 - CSDN博客
原生JavaScript与jQuery(绝对、相对定位)实现拖拽效果
今天给大家谈谈这个拖拽功能的实现
一来是想复习一下这个小知识,二来是看到网上都是absolute绝对定位实现的,感觉有一定局限性
所以自己写了一下用relative相对定位来实现的拖拽效果
原生js绝对定位实现拖拽
首先我们来思考一下拖拽功能用到的事件
拖拽无非是鼠标按下点击物体(DOM节点)
鼠标移动,物体移动
鼠标抬起,物体停止拖拽
所以这里我们需要绑定三个事件
mousedown、mousemove、mouseup
不过通过刚才我们所思考的
mousemove和mouseup事件触发应该是由一个鼠标按下的前提
我们可以利用一个布尔变量储存状态表示当前是否鼠标按下
或者干脆在mousedown事件处理函数中去绑定mousemove、mouseup
那么现在我们大脑里有了这样一个实现拖拽功能函数的蓝图
(主要是逻辑,绑定事件等等兼容问题我就不具体实现了b( ̄▽ ̄)d)
function drag(ele){
ele.onmousedown = function(){
document.onmousemove = function(){
document.onmouseup = function(){
既然要让DOM节点被拖拽,当然不能少了作为参数的元素
下面我们来仔细分析一下拖拽的事件:
既然是绝对定位实现,那我们就加一个容错机制
让鼠标按下的时候就为它添加css样式绝对定位
我们在拖拽的过程中实际上就是改变元素的left和top
可是在拖拽过程中怎样知道它的left和top值应该是什么呢?
拖拽中,有一个量是不变的,那就是光标相对DOM节点左上角的坐标是不变的
而鼠标移动时我们可以获取到的是光标相对于视窗的坐标
DOM节点相对于视窗坐标 = 光标相对于视窗坐标 - 光标相对于DOM节点坐标
这样逆向思考思路就清晰多了
不知道我这样描述大家能不能看懂
所以我们要在mousedown中处理的就是获取那个不变的量——光标相对于DOM节点的坐标
于是每次移动都根据公式获取DOM节点的相对于视窗的坐标(left与top值)
鼠标抬起清理事件
理清了这些,我们来封装这个函数
function drag(ele){
var posX, posY;
ele.onmousedown = function(e){
this.style.position = 'absolute';
posX = e.clientX - parseInt(window.getComputedStyle(this,false)['left']);
posY = e.clientY - parseInt(window.getComputedStyle(this,false)['top']);
ele.onmousemove = function(e){
this.style.left = e.clientX - posX + 'px';
this.style.top = e.clientY - posY + 'px';
ele.onmouseup = function(){
this.onmousemove = null;
this.onmouseup = null;
这里多说一句,其实posX = e.offsetX; posY = e.offfsetY; 和上面的那一长串是一样的
这是IE的非标准方法,虽然我现在使用的无比强大的chrome也好使……
然后我们在来使用一下我们刚刚封装的函数
class="demo"&&
width: 100px;
height: 100px;
background-color: orangered;
border-radius: 50%;
var demo = document.getElementsByTagName('div');
drag(demo[0]);
很快我们发现了问题:当鼠标移动很快时,元素就不会跟随鼠标移动了
为什么会有这样的情况发生呢?
问题就出在了我们把鼠标移动的事件绑定到了元素身上
如果我们让光标移动的很快而移到了元素有效边界之外
那么mousemove的事件就不能触发了,也就不能修改它的left和top值了
正确的做法应该是这样的,把mousemove和mouseup绑定到document
function drag(ele){
var posX, posY;
ele.onmousedown = function(e){
this.style.position = 'absolute';
posX = e.clientX - parseInt(window.getComputedStyle(this,false)['left']);
posY = e.clientY - parseInt(window.getComputedStyle(this,false)['top']);
document.onmousemove = function(e){
ele.style.left = e.clientX - posX + 'px';
ele.style.top = e.clientY - posY + 'px';
document.onmouseup = function(){
this.onmousemove = null;
this.onmouseup = null;
这样无论我们拖拽的有多么的丧心病狂,都不会有问题了
(上面的绑定事件、解除事件、获取样式低版本IE都有兼容问题,以后我会总结的,这里就不予考虑了)
原生js相对定位实现拖拽
为什么我说绝对定位有一定局限性呢?
因为我感觉它有局限性 []~( ̄▽ ̄)~*
开个玩笑我举个例子
class="demo"&&
class="demo"&&
class="demo"&&
width: 100px;
height: 100px;
background-color: orangered;
border-radius: 50%;
var demo = document.getElementsByTagName('div');
drag(demo[0]);
drag(demo[1]);
drag(demo[2]);
利用我们刚刚封装的绝对定位拖拽函数
我鼠标按下第一个球(DOM节点)的一瞬间
第二个球和第三个球跑到了上面
这是因为点击节点的一瞬间,它多了样式position:absolute
绝对定位会使节点脱离当前的文本流
于是没有经过拖拽的节点2和节点3就看不到节点1了
(浏览器发生了reflow重排)
不仅仅这这样,如果这个元素原来是float元素,absolute定位后float也会失效
同样会产生这样的问题
那么怎样解决这种问题呢?
最开始我的想法是创建一个一模一样的透明节点占位
光是想一想都觉得很麻烦,(然而我不想麻烦)
反过来想一想relative或许更合适
相对定位不同于绝对定位的一点就是它不会脱离正常的文本流
而且它的left和top是相对于自己原来位置的,而不是相对于离自己最近的定位父级元素
有了这些想法,我们来尝试重构函数
function drag(ele){
var oldX, oldY, newX, newY;
ele.onmousedown = function(e){
this.style.position = 'relative';
if(!this.style.left && !this.style.top){
this.style.left = 0;
this.style.top = 0;
oldX = e.clientX;
oldY = e.clientY;
document.onmousemove = function(e){
newX = e.clientX;
newY = e.clientY;
ele.style.left = parseInt(ele.style.left) + newX - oldX + 'px';
ele.style.top = parseInt(ele.style.top) + newY - oldY + 'px';
oldX = newX;
oldY = newY;
document.onmouseup = function(){
document.onmousemove = null;
document.onmouseup = null;
这段代码我就不细说了,也很容易看懂
如果你还想写的再丰满一些,可以添加z-index属性
jQuery绝对定位实现拖拽
上面解释了很多,这里我就不那么啰嗦了
直接上代码,道理是一样的
$.fn.extend({
drag: function(){
this.on('mousedown',function(e){
$(this).css('position','absolute');
var disX = e.clientX - $(this).position().left,
disY = e.clientY - $(this).position().top,
$self = $(this);
$(document).on('mousemove',function(e){
$self.css('left',e.clientX - disX);
$self.css('top',e.clientY - disY);
$(document).on('mouseup',function(){
$(document).off();
$('.demo').drag();
还记得我里提到的扩展插件么
这里我利用了$.fn.extend()封装了对象方法的插件
提到这里多说一嘴,这里drag方法内部的this是一个jQuery对象,而不是元素,与on()绑定的事件触发函数内部不同,这里要特别注意
但是同样会产生上面所说的浏览器reflow重排的灾难问题
jQuery相对定位实现拖拽
$.fn.extend({
drag: function(){
var oldX, oldY, newX, newY;
this.on('mousedown',function(e){
$(this).css('position','relative');
oldX = e.clientX;
oldY = e.clientY;
var $self = $(this);
$(document).on('mousemove',function(e){
newX = e.clientX,
newY = e.clientY;
$self.css('left','+=' + (newX - oldX));
$self.css('top','+=' + (newY - oldY));
oldX = newX;
oldY = newY;
$(document).on('mouseup',function(){
$(document).off();
$('.demo').drag();
我也同样利用jQuery的相对定位实现了拖拽
话说jQuery这个off()方法倒是很方便,不填参数把document所有事件都解除了
以上就是我通过原生js还有jQuery分别用绝对定位和相对定位实现拖拽效果的方法
虽然不知道网上为什么没有相对定位的实现
或许它并不常用
不过通过这个小问题练习一下逻辑思维还是不错的
在此分享给大家..(呃码字好累)
本文已收录于以下专栏:
相关文章推荐
New Document
/*模块拖拽*/
.drag{position:width:100height:100border:1px solid #...
很久之前写了一个jquery3D楼盘在线选择,这么一个插件,插件很简单,因为后期项目中没有实际用到,因此,有些地方不是很完善,后面也懒得再进行修改维护了。最近放到github上面,但是也少有人问津及s...
FROM:http://www.jb51.net/article/51290.ht
绝对位置坐标:
复制代码代码如下:
$("#elem").offset().top
获取页面某一元素的绝对X,Y坐标,可以用offset()方法:1
var X = $('#DivID').offset().var Y = $('#DivID').offset().l...
原生JS实现元素跟随鼠标拖动事件
移动端div块跟随手指拖动,pc端div根据鼠标拖动请用mousemove事件,代码如下请勿转载!
一、关于拖拽API
拖拽API是HTML5的新特性,相对于其他新特性来说,重要程度占到6成,实际开发中使用比例占到3成,学习要求个人认为是达到掌握即可的程度。
二、什么是拖拽和释放?
HTML5之前,要实现网页元素的拖放操作,需要依靠mousedown、mousemove、mouseup等API,通过大量的JS代码来实现;HTML5中引入了直接支持拖放操作的API,大大简化了网页元...
DIV+CSS+JS实现的可以随意拖动的网页布局丨芯晴网页特效丨
body {margin:0padding:0font-size:12text-align:...
他的最新文章
讲师:钟钦成
讲师:宋宝华
您举报文章:
举报原因:
原文地址:
原因补充:
(最多只允许输入30个字)在 SegmentFault,解决技术问题
每个月,我们帮助 1000 万的开发者解决各种各样的技术问题。并助力他们在技术能力、职业生涯、影响力上获得提升。
一线的工程师、著名开源项目的作者们,都在这里:
获取验证码
已有账号?
问题对人有帮助,内容完整,我也想知道答案
问题没有实际价值,缺少关键内容,没有改进余地
最近需要做一个效果,就是类似淘宝上面的,拖动查看图文详情的效果,就是类似下方这样的效果。往下拖动是查看图文详情,而且还可以返回上面的部分。
网上搜索到的,大都是使用Android或ios实现的。可否利用JS模拟成类似的效果吗?
答案对人有帮助,有参考价值
答案没帮助,是错误的答案,答非所问
就是监听滚动条,下拉距离底部为某个距离时触发函数,在函数里ajax异步请求查询数据,具体实现代码可以参考我回答的另外一个问题,里面代码有贴,拿过来修改即可传送门:
答案对人有帮助,有参考价值
答案没帮助,是错误的答案,答非所问
监听 touch 开头的几个事件就可以实现了吧。
答案对人有帮助,有参考价值
答案没帮助,是错误的答案,答非所问
就跟下拉刷新一样的吧,监听对应动作,只不过执行的是弹出详情而已
答案对人有帮助,有参考价值
答案没帮助,是错误的答案,答非所问
实际上就是窗口下拉到一定程度时,发送一个ajax请求,将返回的结果渲染到浏览器。可以监听滚动条到底部的距离
答案对人有帮助,有参考价值
答案没帮助,是错误的答案,答非所问
我写了一个demo,大家可以参考一下,用iscroll插件做的
同步到新浪微博
分享到微博?
关闭理由:
删除理由:
忽略理由:
推广(招聘、广告、SEO 等)方面的内容
与已有问题重复(请编辑该提问指向已有相同问题)
答非所问,不符合答题要求
宜作评论而非答案
带有人身攻击、辱骂、仇恨等违反条款的内容
无法获得确切结果的问题
非开发直接相关的问题
非技术提问的讨论型问题
其他原因(请补充说明)
我要该,理由是:

我要回帖

更多关于 ios 拖动手势 的文章

 

随机推荐