亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > JavaScript > 正文

基于Fixed定位的框選功能的實現代碼

2019-11-19 11:35:36
字體:
來源:轉載
供稿:網友

最近項目涉及到一個支持批量操作的小需求,交互上需要使用框選來觸發。在查閱了一些資料后發現,網上的方案基本都是基于絕對定位布局的,此方案如果是針對全局(在body上)的框選,還是可用的。但是現實需求里幾乎都是針對某個區域的框選。如果用絕對定位實現就比較繁瑣了,需要調整定位原點。下面介紹一種基于Fixed定位的框選實現。

需求描述

 

  • 按住鼠標左鍵不放,移動鼠標出現選擇框
  • 在鼠標移動的過程中,在框選范圍內的元素高亮
  • 松開鼠標左鍵,彈出編輯框,批量操作所有被框選的元素

實現

事件綁定

首先梳理一下需要用到的事件。

按住鼠標左鍵,因為并沒有原生的鼠標左鍵按下事件,所以使用mousedown事件配合setTimeout模擬實現。mousedown事件綁定在當前區域上。 使用一個標志變量mouseOn來代表是否開始繪制

handleMouseDown(e) { // 判斷是否為鼠標左鍵被按下 if (e.buttons !== 1 || e.which !== 1) return; this.settimeId = window.setTimeout(() => {  this.mouseOn = true;  // 設置選框的初始位置  this.startX = e.clientX;  this.startY = e.clientY; }, 300);},handleMouseUp(e) { //在mouseup的時候清除計時器,如果按住的時間不足300毫秒 //則mouseOn為false this.settimeId && window.clearTimeout(this.settimeId) if (!this.mouseOn) return;}

這里有一個小的注意點,就是clearTimeout一定要寫成 window.clearTimeout ,否則在vue里會報錯timeout.close is not a function,具體的原因尚未找到,有大佬了解望告知。

鼠標移動,使用mousemove事件。 鼠標抬起,使用mouseup事件,注意抬起事件需要 綁定在document上 。因為用戶的框選操作不會局限在當前區域,在任意位置松開鼠標都應能夠結束框選的繪制。

選框繪制

在明確了事件之后,就只需要在幾個事件中填充具體的繪制和判斷邏輯了。先來看繪制的邏輯。在mousedown事件中,設置選框的初始位置,也就是鼠標按下的位置。這里我們提前寫好一個div,用來代表選框。

<div class="promotion-range__select" ref="select"></div>.promotion-range__select { background: #598fe6; position: fixed; width: 0; height: 0; display: none; top: 0; left: 0; opacity:.6; pointer-events: none;}

按下后顯示這個div并且設置初始定位即可

this.$refs.select.style.cssText = `display:block;                  left:${this.startX}px;                  top:${this.startY}px                  width:0;                  height:0;`;

有了初始位置,在mousemove事件中,設置選框的寬高和定位。

handleMouseMove(e) { if (!this.mouseOn) return; const $select = this.$refs.select; const _w = e.clientX - this.startX; const _h = e.clientY - this.startY; //框選有可能是往左框選,此時框選矩形的左上角就變成 //鼠標移動的位置了,所以需要判斷。同理寬高要取絕對值 this.top = _h > 0 ? this.startY : e.clientY; this.left = _w > 0 ? this.startX : e.clientX; this.width = Math.abs(_w); this.height = Math.abs(_h); $select.style.left = `${this.left}px`; $select.style.top = `${this.top}px`; $select.style.width = `${this.width}px`; $select.style.height = `${this.height}px`;},

如果使用絕對定位,就要去校準坐標原點了,在布局中嵌套多個relative定位容器的情況下,就非常繁瑣了。使用fixed定位就不需要考慮相對于哪個容器的問題了。

判斷被框選的內容

//獲取目標元素const selList = document.getElementsByClassName( "promotion-range__item-inner");const { bottom, left, right, top } = $select.getBoundingClientRect();for (let i = 0; i < selList.length; i++) { const rect = selList[i].getBoundingClientRect(); const isIntersect = !(  rect.top > bottom ||  rect.bottom < top ||  rect.right < left ||  rect.left > right ); selList[i].classList[isIntersect ? "add" : "remove"]("is-editing");}

判斷使用了getBoundingClientRect,定義引用自MDN

返回值是一個 DOMRect 對象,這個對象是由該元素的 getClientRects() 方法返回的一組矩形的集合, 即:是與該元素相關的CSS 邊框集合 。

DOMRect 對象包含了一組用于描述邊框的只讀屬性――left、top、right和bottom,單位為像素。除了 width 和 height 外的屬性都是相對于 視口的左上角 位置而言的。

從定義中可以看到getBoundingClientRect中獲取的left、top、right和bottom是相對于視口左上角的,這和fixed定位的定義是一致的。因此,我們僅需要對比選框和被框選元素的四個定位值即可。

rect.top > bottom 被框選元素位于選框上方

rect.bottom < top 被框選元素位于選框下方

rect.right < left 被框選元素位于選框左側

rect.left > right 被框選元素位于選框右側

排除這四種情況以外就是選框和被框選元素存在交集,給這些div加上class,因為移動過程中也需要讓用戶感知到被框選的元素,所以上述方法在mousemove中也要執行。

在mouseup中判斷被框選元素后,將選框置為display:none。

功能demo地址

參考鏈接

http://www.49028c.com/article/161132.htm
https://developer.mozilla.org/zh-CN/docs/Web/CSS/position
https://developer.mozilla.org/zh-CN/docs/Web/API/Element/getBoundingClientRect

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持武林網。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国产精品九九九| 国产精品69av| 亚洲区中文字幕| 精品国产一区二区三区久久久狼| 欧美日韩性生活视频| 亚洲国产精彩中文乱码av在线播放| 亚洲精品视频久久| 96国产粉嫩美女| 亚洲精品国精品久久99热| 日韩精品视频在线免费观看| 色综合色综合久久综合频道88| 国产精品老牛影院在线观看| 亚洲成人精品av| 亚洲第一天堂av| 国产综合色香蕉精品| 国产欧美一区二区三区久久| yellow中文字幕久久| 国产精品视频公开费视频| 97成人精品区在线播放| 最近免费中文字幕视频2019| 国产精品久久久久久久久影视| 国产成人啪精品视频免费网| 国内精品免费午夜毛片| 国产aⅴ夜夜欢一区二区三区| 欧美最猛性xxxxx免费| 国产成人在线精品| 中文字幕精品久久| 欧美激情视频一区二区| 亚洲大胆美女视频| 国产伦精品一区二区三区精品视频| 欧美性xxxx极品hd满灌| 久久影视电视剧凤归四时歌| 91免费看片网站| 91国偷自产一区二区三区的观看方式| 色偷偷88888欧美精品久久久| 黑人巨大精品欧美一区二区一视频| 亚洲社区在线观看| 热99在线视频| 国产精品久久久久7777婷婷| 亚洲国产日韩精品在线| 国产亚洲精品美女久久久久| 91精品国产成人| 亚洲欧美日韩一区在线| 欧美成人午夜激情| 国产成人一区二区三区小说| 国产欧美日韩91| 国产精品爱啪在线线免费观看| 亚洲欧美激情视频| 在线亚洲午夜片av大片| 欧美日韩综合视频网址| 国产精品日韩久久久久| 亚洲天堂av电影| 国产精品亚洲网站| 久久久精品久久久| 精品久久久久久国产91| 国产精品永久免费在线| 欧美午夜性色大片在线观看| 亚洲性视频网址| 日韩欧美有码在线| 欧美日韩裸体免费视频| 国产a∨精品一区二区三区不卡| 亚洲精品456在线播放狼人| 亚洲缚视频在线观看| 韩剧1988免费观看全集| 欧美在线xxx| 在线精品国产成人综合| 中文字幕av日韩| 91嫩草在线视频| 菠萝蜜影院一区二区免费| 姬川优奈aav一区二区| 久久久久久久国产精品视频| 超碰97人人做人人爱少妇| 97在线视频免费| 亚洲国产精久久久久久| 欧美高清视频在线观看| 欧美电影在线播放| 国产精品九九久久久久久久| 国产又爽又黄的激情精品视频| 精品成人久久av| 久久久久久91香蕉国产| 国产精品1234| 正在播放亚洲1区| 姬川优奈aav一区二区| 亚洲国产一区二区三区在线观看| 欧美视频在线观看免费网址| 亚洲国产女人aaa毛片在线| 欧美国产日韩一区二区三区| 国内伊人久久久久久网站视频| 26uuu日韩精品一区二区| 操人视频在线观看欧美| 91社影院在线观看| 国产日韩欧美一二三区| 日本高清久久天堂| 亚洲欧洲日韩国产| 久久久久久香蕉网| 欧美激情精品久久久久久大尺度| 欧美天堂在线观看| 精品视频久久久久久| 久久久女女女女999久久| 国产精品无av码在线观看| 欧美裸体xxxx极品少妇软件| 伊人久久综合97精品| 久久精品国产一区二区电影| 久久色免费在线视频| 欧美大尺度激情区在线播放| 日韩欧美大尺度| 亚洲精品一区av在线播放| 欧美大秀在线观看| 欧美大全免费观看电视剧大泉洋| 国模吧一区二区| 美女久久久久久久| 欧美xxxx综合视频| 欧美日韩久久久久| 精品呦交小u女在线| 日韩精品中文字幕有码专区| 国产91精品网站| 亚洲精品网址在线观看| 国产精品久久久久久久av大片| 国产欧美日韩中文| 中文字幕不卡av| 亚洲欧美中文日韩在线| 欧美日韩国产中字| 爱福利视频一区| 欧美日韩国产一区在线| 亚洲风情亚aⅴ在线发布| 亚洲国产成人精品久久久国产成人一区| 91精品国产色综合| 久久人人爽人人爽人人片亚洲| 国产日韩在线亚洲字幕中文| 欧美电影免费播放| 成人综合网网址| 欧美高清视频在线观看| 国产不卡在线观看| 久久久人成影片一区二区三区观看| 欧美最顶级丰满的aⅴ艳星| 欧美成在线视频| 亚洲毛片在线免费观看| 黄色一区二区在线| 狠狠躁夜夜躁人人爽天天天天97| 久久久精品日本| 97视频在线免费观看| 亚洲图片欧洲图片av| 国产精品白嫩美女在线观看| 国产精品18久久久久久麻辣| 亚洲缚视频在线观看| 欧美一级大片在线观看| 日韩欧美国产一区二区| 91精品国产综合久久香蕉的用户体验| 亚洲最大av网站| 欧美最猛性xxxxx亚洲精品| 欧美裸身视频免费观看| 午夜精品久久久久久久久久久久久| 成人黄色短视频在线观看| xxav国产精品美女主播| 成人免费观看网址| 91中文在线观看| 91av在线影院| 国产偷国产偷亚洲清高网站| 国产99久久精品一区二区永久免费| 欧美亚洲在线视频| 国产欧美一区二区白浆黑人| 亚洲视频综合网| 欧美成人午夜激情| 日韩av网站在线|