鼠標拖拽吸附效果

JavaScript鼠標拖動+自動吸附實例

學了幾天的JavaScript,自己動手做了一個簡單的鼠標拖動的實例,拖動過程中科自動檢測與目標容器的距離,在一定的距離范圍內可以自動將被拖動的元素加入到目標容器中,希望對開始學習javascript的童鞋有用……

先看看效果圖(Chrome、FireFox、Opera、Safari測試通過):

效果圖(虛線框:目標對象 ? ?藍色填充透明框:臨時拖動對象 ? 紅色填充框:被拖動對象)

主要思路:首先給要拖動的div添加一個鼠標按下(mousedown)事件、給document對象添加鼠標移動(mousemove)事件和鼠標彈起(mouseup)事件。鼠標開始移動的時候創建一個臨時的拖動對象(temp),移動過程中改變臨時拖動目標的位置,鼠標釋放時將被拖動的div(elem)的位置設置為臨時拖動目標temp的位置,然后移出臨時拖動目標。移動過程中,同時還檢測了拖動的對象和目標div的位置關系,如果碰撞(可以設置吸附的范圍),則自動吸附(將被拖動的對象加入到目標對象中),需要說明的是:這里簡單起見,并沒有真正的把被拖動對象加入到目標對象中,只是設置了被拖動對象的位置。

鼠標按下時:獲取被拖動元素的位置和鼠標按下的位置,設置拖動的標志(isDrag)值為true。

復制代碼
elem.onmousedown = function(event){//鼠標按下isDrag = true;startX = parseInt(this.style.left||getCSSValue(this,'left'));startY = parseInt(this.style.top||getCSSValue(this,'top'));mX = event.pageX;mY = event.pageY;};
復制代碼

鼠標移動時:如果isDrag為true,并且temp對象不存在,則創建temp對象,并根據鼠標的位置計算并設置temp的位置。

復制代碼
document.onmousemove = function(event){//鼠標移動this.innerHTML = 'Mouse Position('+event.pageX+','+event.pageY+')';if(isDrag){//當前正在移動if(temp == undefined){//temp臨時拖動目標不存在temp = document.createElement('div');temp.id = 'drag';temp.className = 'temp';document.body.appendChild(temp);//將temp臨時拖動目標添加到頁面中}//改變位置temp.style.left = (startX + event.pageX - mX) + 'px';temp.style.top = (startY + event.pageY - mY) + 'px';//檢測是否在目標范圍內if(checkIntersect(temp,$('target'),20)){//在范圍內$('target').style.border = '2px #F00 dashed';$('target').style.webkitAnimationName = 'light';//閃爍動畫$('target').style.webkitAnimationDuration = '1s';$('target').style.webkitAnimationDelay = '0.5s';$('target').style.webkitAnimationIterationCount = '100';}else{//不在范圍內$('target').style.border = '2px #09F dashed';$('target').style.webkitAnimationName = '';}}};
復制代碼

說明:這里的mousemove事件并不是添加到被拖動對象(elem)上面,如果添加到elem上面,那么鼠標如果移動太快一旦鼠標離開了elem對象,那么就會出現問題。

鼠標釋放時:檢測碰撞結果,根據情況設置被拖動對象(elem)的位置,如果以碰撞,則根據目標div的位置設置被拖動對象(elem)的位置,否則根據temp的位置來設置被拖動對象(elem)的位置;

復制代碼
document.onmouseup = function(){//鼠標釋放isDrag = false;if(checkIntersect(temp,$('target'),20)){elem.style.left=$('target').offsetLeft+'px';elem.style.top=$('target').offsetTop+'px';}else{elem.style.left=temp.offsetLeft+'px';elem.style.top=temp.offsetTop+'px';}document.body.removeChild(temp);//移出臨時拖動目標temp = null;$('target').style.border = '2px #09F dashed';$('target').style.webkitAnimationName = '';//取消閃爍};
復制代碼

=======================================================

用到的其他函數:在設計過程中,我們需要或許某個元素樣式的一些值,如果我們采用行內式(即將樣式寫在元素標簽里面的style屬性里面),我們可以采用“obj.style.left”類似這樣的語法來或許,但是如果我們的樣式采用了內嵌式(將CSS寫在<head>與</head>之間,并且用<style>和</style>標記進行聲明)或者鏈接式(用類似這樣的<link href="css.css" type="text/css" rel="stylesheet">方式導入外部樣式表)、導入式(采用import語句),我們就無法從上面的方式中獲取樣式的相關值,但是我們可以用其他的方法:IE下元素有currentStyle對象,其他瀏覽器采用document.defaultView.getComputedStyle()方法,這樣可以獲取樣式屬性的值。代碼如下:

復制代碼
function getCSSValue(obj,key){//獲取元素CSS值if(obj.currentStyle){//IEreturn obj.currentStyle[key];    }else{//!IEreturn document.defaultView.getComputedStyle(obj,null)[key];}}
復制代碼

另外,檢測碰撞的函數;

復制代碼
function checkIntersect(obj1,obj2,distance){//檢測碰撞,distance為吸附的范圍var left1 = obj1.offsetLeft;var top1 = obj1.offsetTop;var left2 = obj2.offsetLeft;var top2 = obj2.offsetTop;var width1 = obj1.offsetWidth;var height1 = obj1.offsetHeight;var width2 = obj2.offsetWidth;var height2 = obj2.offsetHeight;return (((left1-left2>=0&&left1-left2<width2+distance)||(left2-left1>=0&&left2-left1<width1+distance))&&((top1-top2>=0&&top1-top2<height2+distance)||(top2-top1>=0&&top2-top1<height1+distance)));}
復制代碼

?

總結:這里面主要用到了javascript鼠標事件,簡單的DOM節點操作,還有css3的一些新的東西,比如動畫(animation)、圓角(border-radius)、陰影(box-shadow)等知識。

轉載于:https://www.cnblogs.com/wu-hou/p/6739498.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/393119.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/393119.shtml
英文地址,請注明出處:http://en.pswp.cn/news/393119.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

php修改mysql數據庫中的表格,如何修改mysql數據庫表?

修改mysql數據庫表的方法&#xff1a;使用“ALTER TABLE”語句&#xff0c;可以改變原有表的結構&#xff0c;例如增加字段或刪減字段、修改原有字段數據類型、重新命名字段或表、修改表字符集等&#xff1b;語法“ALTER TABLE [修改選項]”。修改數據表的前提是數據庫中已經存…

微軟最新GDI漏洞MS08-052安全解決方案

微軟最新GDI漏洞MS08-052安全解決方案 Simeon微軟于九月九日凌晨爆出有史以來最大的安全漏洞MS08-052&#xff0c;通過該漏洞&#xff0c;攻擊者可以將木馬藏于圖片中&#xff0c;網民無論是通過瀏覽器瀏覽、還是用各種看圖軟件打開、或者在即時聊天窗口、電子郵件、Office文檔…

DEM軌跡后處理

方法一&#xff1a;直接在paraview中顯示 首先在輸出顆粒信息的時候保存global ID&#xff1a;然后在paraview中導入vtp數據&#xff08;不要導入pvd&#xff09;&#xff0c;并使用Temporal Particle To Pathlines這個filter&#xff08;可以直接ctrlspace調出搜索框搜索&…

Oracle的JDBC Url的幾種方式

1.普通SID方式jdbc:oracle:thin:username/passwordx.x.x.1:1521:SID2.普通ServerName方式 jdbc:Oracle:thin:username/password//x.x.x.1:1522/ABCD3.RAC方式jdbc:oracle:thin:(DESCRIPTION(ADDRESS_LIST(ADDRESS(PROTOCOLTCP)(HOSTx.x.x.1)(PORT1521))(ADDRESS(PROTOCOLTCP)(H…

leetcode945. 使數組唯一的最小增量(排序)

給定整數數組 A&#xff0c;每次 move 操作將會選擇任意 A[i]&#xff0c;并將其遞增 1。 返回使 A 中的每個值都是唯一的最少操作次數。 示例 1: 輸入&#xff1a;[1,2,2] 輸出&#xff1a;1 解釋&#xff1a;經過一次 move 操作&#xff0c;數組將變為 [1, 2, 3]。 代碼 …

數據科學 python_如何使用Python為數據科學建立肌肉記憶

數據科學 pythonby Zhen Liu劉震 首先&#xff1a;數據預處理 (Up first: data preprocessing) Do you feel frustrated by breaking your data analytics flow when searching for syntax? Why do you still not remember it after looking up it for the third time?? It…

oracle 管道通信,oracle管道化表函數

轉自&#xff1a;http://pengfeng.javaeye.com/blog/260360在我所做過和參與的大多數項目中,都會有用戶提出的復雜的一些統計報表之內的功能要求,根據統計的復雜程度、效率及JAVA程序調用的方便性方面考慮,主要總結出以下幾種方案&#xff1a; 1、SQL語句 該方案只能實現一些相…

ebtables之BROUTING和PREROUTING的redirect的區別

ebtables和iptables實用工具都使用了Netfilter框架&#xff0c;這是它們一致的一方面&#xff0c;然而對于這兩者還真有一些需要聯動的地方。很多人不明白ebtales的broute表的redirect和nat表PREROUTING的redirect的區別&#xff0c;其實只要記住兩點即可&#xff0c;那就是對于…

LVS的四種模式的實現

LVS 是四層負載均衡&#xff0c;也就是說建立在 OSI 模型的第四層——傳輸層之上&#xff0c;傳輸層上有我們熟悉的 TCP/UDP&#xff0c;LVS 支持 TCP/UDP 的負載均衡。LVS 的轉發主要通過修改 IP 地址&#xff08;NAT 模式&#xff0c;分為源地址修改 SNAT 和目標地址修改 DNA…

MyISAM與InnoDB兩者之間區別與選擇,詳細總結,性能對比

1、MyISAM&#xff1a;默認表類型&#xff0c;它是基于傳統的ISAM類型&#xff0c;ISAM是Indexed Sequential Access Method (有索引的順序訪問方法) 的縮寫&#xff0c;它是存儲記錄和文件的標準方法。不是事務安全的&#xff0c;而且不支持外鍵&#xff0c;如果執行大量的sel…

leetcode557. 反轉字符串中的單詞 III

給定一個字符串&#xff0c;你需要反轉字符串中每個單詞的字符順序&#xff0c;同時仍保留空格和單詞的初始順序。 示例&#xff1a; 輸入&#xff1a;“Let’s take LeetCode contest” 輸出&#xff1a;“s’teL ekat edoCteeL tsetnoc” 代碼 class Solution {public St…

linux命令數據盤分多個區,pvmove命令 – 移動物理盤區

pvmove命令的作用是可以將源物理卷上的物理盤區移動到一個或多個其他的目標物理卷。使用pvmove命令時可以指定一個源日志或卷。在這種情況下&#xff0c;只有邏輯卷使用的區才會被移動到目標物理卷上的空閑或指定的區。如果沒有指定的物理卷&#xff0c;則使用卷組的默認規則分…

spanning-tree extend system-id

spanning-tree extend system-id 在交換機上啟用extended-system ID 特征使其支持 1024 MAC 地址, 在全局模式下使用 spanning-tree extend system-id命令.禁用時前面加 no。 spanning-tree extend system-id no spanning-tree extend system-id 命令用法 在不提供 1024 MAC 地…

leetcode841. 鑰匙和房間(bfs)

有 N 個房間&#xff0c;開始時你位于 0 號房間。每個房間有不同的號碼&#xff1a;0&#xff0c;1&#xff0c;2&#xff0c;…&#xff0c;N-1&#xff0c;并且房間里可能有一些鑰匙能使你進入下一個房間。 在形式上&#xff0c;對于每個房間 i 都有一個鑰匙列表 rooms[i]&a…

Codeforces 235C Cyclical Quest (后綴自動機)

題目鏈接: https://codeforces.com/contest/235/problem/C 題解: 對大串建后綴自動機 對詢問串復制拆環。這里一定要注意是復制一個循環節不是復制整個串&#xff01;循環節是要整除的那種 然后要做的實際上是在大串上跑&#xff0c;每經過一個點求出當前的最長公共子串&#x…

泛型型協變逆變_Java泛型類型簡介:協變和逆變

泛型型協變逆變by Fabian Terh由Fabian Terh Java泛型類型簡介&#xff1a;協變和逆變 (An introduction to generic types in Java: covariance and contravariance) 種類 (Types) Java is a statically typed language, which means you must first declare a variable and …

安卓系統換成linux系統軟件,將舊安卓手機打造成“簡易linux”機器,并部署AdGuardHome...

從原教程的安裝Linux Deploy 完成后&#xff0c;在配置 Linux下載鏡像的一些東西時有些許出入。首先&#xff0c;我是用的下載源地址是 http://mirrors.tuna.tsinghua.edu.cn/ubuntu-ports 清華的源挺好用的。 其他有出入的配置如圖(記得把源地址改清華的&#xff0c;華中科大…

let與expr命令的用法與實戰案例

let命令的用法 格式&#xff1a; let 賦值表達式 【注】let賦值表達式功能等同于&#xff1a;&#xff08;賦值表達式&#xff09; 例子&#xff1a;給自變量i加8 12345678[rootXCN ~]# i2 [rootXCN ~]# let ii8 [rootXCN ~]# echo $i 10[rootXCN ~]# ii8 #去掉let定義 [root…

在使用ToolBar + AppBarLayout,實現上劃隱藏Toolbar功能,遇到了一個坑。

問題&#xff1a;Android5.0以下版本Toolbar不顯示沉浸式狀態欄&#xff0c;沒有這個問題&#xff0c;但是5.0以上版本&#xff0c;就出現了莫名其妙的陰影問題&#xff0c;很是頭疼。 分享一下我的解決方案&#xff1a; 在AppBarLayout中加一個屬性&#xff1a; app:elevation…

leetcode1476. 子矩形查詢

請你實現一個類 SubrectangleQueries &#xff0c;它的構造函數的參數是一個 rows x cols 的矩形&#xff08;這里用整數矩陣表示&#xff09;&#xff0c;并支持以下兩種操作&#xff1a; updateSubrectangle(int row1, int col1, int row2, int col2, int newValue) 用 new…