鼠标捕获(setCapture,releaseCapture)的学习
鼠标捕获(setCapture)作用是将鼠标事件捕获到当前文档的指定的对象——对指定的对象设置鼠标捕获。这个对象会为当前应用程序或整个系统接收所有鼠标事件。
- 所谓鼠标捕获,是指对鼠标事件(onmousedown, onmouseup, onmousemove, onclick, ondblclick, onmouseover, onmouseout)进行捕捉,使在容器内的子对象的鼠标事件均由容器对象触发,因此,只能在容器对象的鼠标事件函数中进行处理。
- 当参数为true时,对鼠标进行捕捉,相反,不捕捉。
- 与这个函数对应,releaseCapture方法释放鼠标捕获,并触发onlosecapture事件。
一、语法
1. MDN(Mozilla Developer Network)
element.setCapture(retargetToElement);
retargetToElement——If true, all events are targeted directly to this element; if false, events can also fire at descendants of this element.
document.releaseCapture()
释放鼠标捕捉——Once mouse capture is released, mouse events will no longer all be directed to the element on which capture is enabled.
2. msdn(Internet Explorer Dev Center)
object.setCapture(containerCapture)
- 其中: containerCapture [in, optional]—— Type: Boolean
-
- true (true)——Default. 容器会捕获容器内所有对象的鼠标事件,即容器内的对象不会触发鼠标事件(跟容器外的对象一样)Events originating in a container are captured by the container.
- false (false)——容器不会捕获容器内对象的鼠标事件,即容器内的对象可以正常地触发事件和取消冒泡。Events originating in a container are not captured by the container.
object.setCapture() 当一个object的被 setCapture 后,他的方法将会被继承到整个文档进行捕获。当不需要把方法继承到整个文档捕获时,要用 object.releaseCapture() 来释放.
二、案例——简单拖拽
完整代码
<!DOCTYPE html>
<html>
<head>
<title>drag example</title>
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/>
<style type="text/css">
#drag{position:absolute;left:12px;top:24px;width:100px;height:150px; display:block;border:1px solid #000000;z-index:1;background:#eeeeee; cursor: pointer;}
</style>
</head>
<body>
<div id="drag">drag me</div>
<script type="text/javascript">
window.onload=function(){
objDiv = document.getElementById("drag");
drag(objDiv);
};
function drag(dv){
dv.onmousedown=function(e){
var d=document;
e = e || window.event; var x= e.layerX || e.offsetX;
var y= e.layerY || e.offsetY; //设置捕获范围
if(dv.setCapture){
dv.setCapture();
}else if(window.captureEvents){
window.captureEvents(Event.MOUSEMOVE | Event.MOUSEUP);
} d.onmousemove=function(e){
e= e || window.event;
if(!e.pageX)e.pageX=e.clientX;
if(!e.pageY)e.pageY=e.clientY;
document.getElementById("drag").innerHTML= e.pageX+ e.pageY;
var tx=e.pageX-x;
var ty=e.pageY-y;
dv.style.left=tx+"px";
dv.style.top=ty+"px";
};
d.onmouseup=function(){
//取消捕获范围
if(dv.releaseCapture){
dv.releaseCapture();
}else if(window.captureEvents){
window.captureEvents(Event.MOUSEMOVE|Event.MOUSEUP);
}
//清除事件
d.onmousemove=null;
d.onmouseup=null;
};
};
}
</script>
</body>
</html>
三、案例——完美拖拽
完整代码
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>完美拖拽</title>
<style type="text/css">
html,body{overflow:hidden;}
body,div,h2,p{margin:0;padding:0;}
body{color:#fff;background:#000;font:12px/2 Arial;}
p{padding:0 10px;margin-top:10px;}
span{color:#ff0;padding-left:5px;}
#box{position:absolute;width:300px;height:150px;background:#333;border:2px solid #ccc;top:50%;left:50%;margin:-75px 0 0 -150px;}
#box h2{height:25px;cursor:move;background:#222;border-bottom:2px solid #ccc;text-align:right;padding:0 10px;}
#box h2 a{color:#fff;font:12px/25px Arial;text-decoration:none;outline:none;}
</style>
<script type="text/javascript">
window.onload=function (){
var oBox=document.getElementById("box");
var oH2 = oBox.getElementsByTagName("h2")[0];
var oA = oBox.getElementsByTagName("a")[0];
var aSpan = oBox.getElementsByTagName("span");
var disX = disY = 0;
var bDrag = false;
var aPos = [{x:oBox.offsetLeft, y:oBox.offsetTop}]; //鼠标按下, 激活拖拽
oH2.onmousedown = function (event){
var event = event || window.event;
bDrag = true;
disX = event.clientX - oBox.offsetLeft;
disY = event.clientY - oBox.offsetTop;
aPos.push({x:oBox.offsetLeft, y:oBox.offsetTop}) this.setCapture && this.setCapture();
return false;
}; //拖拽开始
document.onmousemove = function (event){
if (!bDrag) return;
var event = event || window.event;
var iL = event.clientX - disX;
var iT = event.clientY - disY;
var maxL = document.documentElement.clientWidth - oBox.offsetWidth;
var maxT = document.documentElement.clientHeight - oBox.offsetHeight; iL = iL < 0 ? 0 : iL;
iL = iL > maxL ? maxL : iL; iT = iT < 0 ? 0 : iT;
iT = iT > maxT ? maxT : iT; oBox.style.marginTop = oBox.style.marginLeft = 0;
oBox.style.left = iL + "px";
oBox.style.top = iT + "px";
aPos.push({x:iL, y:iT}) status(); return false;
}; //鼠标释放, 结束拖拽
document.onmouseup = window.onblur = oH2.onlosecapture = function (){
bDrag = false;
oH2.releaseCapture && oH2.releaseCapture();
status();
}; //回放拖动轨迹
oA.onclick = function (){
if (aPos.length == 1) return;
var timer = setInterval(function () {
var oPos = aPos.pop();
oPos ? (oBox.style.left = oPos.x + "px", oBox.style.top = oPos.y + "px", status()) : clearInterval(timer)
}, 30);
this.focus = false;//去除链接虚线
return false;
}; //阻止冒泡
oA.onmousedown = function (event){
(event || window.event).cancelBubble = true
}; //监听状态函数
function status (){
aSpan[0].innerHTML = bDrag;
aSpan[1].innerHTML = oBox.offsetTop;
aSpan[2].innerHTML = oBox.offsetLeft;
} //初始调用
status();
};
</script>
</head>
<body>
<div id="box">
<h2><a href="javascript:;">点击回放拖动轨迹</a></h2>
<p><strong>Drag:</strong><span></span></p>
<p><strong>offsetTop:</strong><span></span></p>
<p><strong>offsetLeft:</strong><span></span></p>
</div>
</body>
</html>
javascript代码
//鼠标按下, 激活拖拽
oH2.onmousedown = function (event){
var event = event || window.event;
bDrag = true;
disX = event.clientX - oBox.offsetLeft;
disY = event.clientY - oBox.offsetTop;
aPos.push({x:oBox.offsetLeft, y:oBox.offsetTop});
this.setCapture && this.setCapture();
return false;
}; //拖拽开始
document.onmousemove = function (event){
if (!bDrag) return;
var event = event || window.event;
var iL = event.clientX - disX;
var iT = event.clientY - disY;
var maxL = document.documentElement.clientWidth - oBox.offsetWidth;
var maxT = document.documentElement.clientHeight - oBox.offsetHeight; iL = iL < 0 ? 0 : iL;
iL = iL > maxL ? maxL : iL; iT = iT < 0 ? 0 : iT;
iT = iT > maxT ? maxT : iT; oBox.style.marginTop = oBox.style.marginLeft = 0;
oBox.style.left = iL + "px";
oBox.style.top = iT + "px";
aPos.push({x:iL, y:iT})
status();
return false;
}; //鼠标释放, 结束拖拽
document.onmouseup = window.onblur = oH2.onlosecapture = function (){
bDrag = false;
oH2.releaseCapture && oH2.releaseCapture();
status();
};
//阻止冒泡
oA.onmousedown = function (event){
(event || window.event).cancelBubble = true
}; //监听状态函数
function status (){
aSpan[0].innerHTML = bDrag;
aSpan[1].innerHTML = oBox.offsetTop;
aSpan[2].innerHTML = oBox.offsetLeft;
}
参考:
- https://developer.mozilla.org/en-US/docs/Web/API/Element.setCapture
- http://msdn.microsoft.com/en-us/library/ie/ms536742%28v=vs.85%29.aspx
鼠标捕获(setCapture,releaseCapture)的学习的更多相关文章
- SetCapture ReleaseCapture
函数功能:该函数在属于当前线程的指定窗体里设置鼠标捕获.一旦窗体捕获了鼠标,全部鼠标输入都针对该窗体,不管光标是否在窗体的边界内.同一时刻仅仅能有一个窗体捕获鼠标.假设鼠标光标在还有一个线程创建的窗体 ...
- wpf鼠标捕获与控件交互——UIElement.CaptureMouse
应用场景是这样的,我需要拖动一个元素在屏幕上移动,注册了被移动元素的MouseMove事件,但是当鼠标移到被移动元素的外面时,移动失效,且鼠标的手势变成了普通的箭头形状,于是就找到了以下的解决方案. ...
- SetCapture() & ReleaseCapture() 捕获窗口外的【松开左键事件】: WM_LBUTTONUP
今天在窗口上绘图的时候,遇到一个问题:在特殊情况下,当用户在窗口中按下鼠标左键,然后移动到窗口外松开鼠标左键,这时程序中只能捕获到 WM_LBUTTONDOWN(按下) 和 WM_MOUSEMOVE( ...
- 事件流之事件冒泡与事件捕获<JavaScript高级程序设计>学习笔记
1.事件流 浏览器开发团队遇到一个很有意思问题:页面的那一部分会拥有特定的事件? 对于理解这个问题您可以想象画在一张纸上的一组同心圆,如果你把手指放在圆心上,那么你的手指指向的其实不是一个圆,而是纸上 ...
- win32中SetCapture 和 ReleaseCapture的使用(查一下在VCL中的使用)
最近在用win32写<visual C++经典游戏程序设计>中的扫雷游戏,在写到鼠标点击雷区的时候用到了SetCapture,和ReleaseCapture这对系统函数. 那么为什么需要用 ...
- 《JavaScript 实战》:实现拖放(Drag & Drop)效果
拖放效果,也叫拖拽.拖动,学名Drag-and-drop ,是最常见的js特效之一.如果忽略很多细节,实现起来很简单,但往往细节才是难点所在.这个程序的原型是在做图片切割效果的时候做出来的,那时参考了 ...
- windows API普通函数跟回调函数有何区别
通俗点讲:1.普通函数(假设我们都是函数)你卖电脑,我买电脑,我给你钱(调用你)后,你给我电脑(得到返回值).这种情况下,我给钱后就不能走开,必须等你把电脑给我,否则你交货的时候可能找不到人.2.回调 ...
- js自定义的简易滚动条
<!doctype html> <html> <head> <meta charset="utf-8"> <title> ...
- JS模拟滚动条(有demo和源码下载,支持拖动 滚轮 点击事件)
由于游览器自带的滚动条在美观方面并不是很好看,所以很多设计师希望通过自己设计出来的滚动条来做这样的效果,JS模拟滚动条其实很早看到jQuery有这样的插件或者KISSY有这样的组件,一直想着自己什么时 ...
随机推荐
- 【转】z-index层级在老版本的IE中无效
在CSS中,只能通过代码改变层级,这个属性就是z-index,要让z-index起作用有个小小前提,就是元素的position属性要是relative,absolute或是fixed. 1.第一种情况 ...
- wpf程序线程与UI内容交互
在UI线程里执行复杂的操作,会造成UI假死.常用的解决方法是开2个线程. 而新线程要调用UI里的东西,必须这么用: this.Dispatcher.Invoke(content);
- ISE和Modelsim联合仿真(详细步骤讲解)
ISE和Modelsim联合仿真(转) 地址:http://www.cnblogs.com/feitian629/archive/2013/07/13/3188192.html 相信很多人会遇到过这个 ...
- RednaxelaFX写的文章/回答的导航帖
https://www.zhihu.com/people/rednaxelafx/answers http://hllvm.group.iteye.com/group/topic/44381#post ...
- C++程序文件链接
1.什么是转换单元程序中的每个.cpp文件和它包含的所有头文件称为一个转换单元.编译器处理每个转换单元,生成二进制对象文件,用扩展名.obj来标识.链接器将对象文件组合起来,生成一个可执行文件,用扩展 ...
- 每日英语:Some Chinese Students Stay Home to Get Ahead
Li Shan's oldest son was the perfect candidate to join the throngs of Chinese students studying abro ...
- mysql 匹配 findinset
SELECT FS_ITEM_DESC FROM dictionary WHERE FS_TYPE = 'prizeType' AND FIND_IN_SET(FS_ITEM_CODE,(SELE ...
- 使用 FreeRTOS 时注意事项总结(基础篇教程完结)
以下转载自安富莱电子: http://forum.armfly.com/forum.php FreeRTOS 的初始化流程推荐的初始化流程如下,本教程配套的所有例子都是采用的这种形式,当然,不限制必须 ...
- displaytag的Excel导出实践
本文转自 http://lingceng.iteye.com/blog/1820081/ Displaytag官网有1.0, 1.1, 1.2等,注意找到对应的版本.源码和API可以在Maven库中找 ...
- 如何在linux下实现mysql数据库每天自动备份
建备份文件夹: mkdir mysql_data_bak 建脚本文件: touch autobackupmysql.sh 打开文件 vi autobackupmysql.sh 在脚本中加入如下内容: ...