免费观看又色又爽又黄的小说免费_美女福利视频国产片_亚洲欧美精品_美国一级大黄大色毛片

如何自定義類似于jQueryUISelectable的Vue指令v-selectable

這期內(nèi)容當(dāng)中小編將會(huì)給大家?guī)碛嘘P(guān)如何自定義類似于jQueryUISelectable的Vue指令v-selectable,文章內(nèi)容豐富且以專業(yè)的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。

成都創(chuàng)新互聯(lián)公司擁有網(wǎng)站維護(hù)技術(shù)和項(xiàng)目管理團(tuán)隊(duì),建立的售前、實(shí)施和售后服務(wù)體系,為客戶提供定制化的成都網(wǎng)站設(shè)計(jì)、網(wǎng)站建設(shè)、網(wǎng)站維護(hù)、光華機(jī)房服務(wù)器托管解決方案。為客戶網(wǎng)站安全和日常運(yùn)維提供整體管家式外包優(yōu)質(zhì)服務(wù)。我們的網(wǎng)站維護(hù)服務(wù)覆蓋集團(tuán)企業(yè)、上市公司、外企網(wǎng)站、成都商城網(wǎng)站開發(fā)、政府網(wǎng)站等各類型客戶群體,為全球近1000家企業(yè)提供全方位網(wǎng)站維護(hù)、服務(wù)器維護(hù)解決方案。

話不多說,先看效果。

如何自定義類似于jQueryUISelectable的Vue指令v-selectable

其實(shí)就是一個(gè)可以按住鼠標(biāo)進(jìn)行一個(gè)區(qū)域內(nèi)條目選擇的功能,相信用過Jquery UI 的都知道這是selectable的功能,然而我們?nèi)绻肰ue開發(fā)的話沒有類似的插件,當(dāng)然你仍然可以把jquery的拿過來直接用,但是我又不想引入jquery 和 jquery UI在我的項(xiàng)目中,于是我就自己嘗試著實(shí)現(xiàn)類似的功能。

要實(shí)現(xiàn)這個(gè)功能分兩步。第一步是實(shí)現(xiàn)鼠標(biāo)選擇區(qū)域的功能,第步部是把這個(gè)區(qū)域內(nèi)被選擇的item添加一個(gè)active的類。

先看如何實(shí)現(xiàn)按住鼠標(biāo)畫虛線框,思路是先把容器元素的定位改為relative 然后判斷當(dāng)鼠標(biāo)按下(mousedown)的時(shí)候,進(jìn)行記住這個(gè)點(diǎn)擊點(diǎn)的位置(e.layerX , e.layerY),然后鼠標(biāo)移動(dòng)(mousemove)的時(shí)候,實(shí)時(shí)的監(jiān)測(cè)鼠標(biāo)的位置(e.layerX , e.layerY),有了這兩個(gè)位置就可以動(dòng)態(tài)的創(chuàng)建一個(gè)div,它的定位為absolute,然后把它添加的容器框里,并且每次清空前一個(gè)框就可以了。為什么是用e.layerX e.layerY呢,

layerX layerY

         如果元素的position樣式不是默認(rèn)的static,我們說這個(gè)元素具有定位屬性。

         在當(dāng)前觸發(fā)鼠標(biāo)事件的元素和它的祖先元素中找到最近的具有定位屬性的元素,計(jì)算鼠標(biāo)與其的偏移值,以找到元素的border的左上角的外交點(diǎn)作為相對(duì)點(diǎn)。如果找不到具有定位屬性的元素,那么就相對(duì)于當(dāng)前頁面計(jì)算偏移,此時(shí)等同于pageY。按照這個(gè)思路完成以下代碼:

export default (Vue, options = {}) =>{
  const listener = (ele, binding) =>{
    let reactArea = {
      startX: 0,
      startY: 0,
      endX: 0,
      endY: 0
    }
    //是否一直按下鼠標(biāo)
    let isMouseDown = false
    let areaSelect = {}
    //將元素定位改為relative
    ele.style.position = 'relative'
    ele.addEventListener('mousedown', function(e) {
      reactArea.startX = e.layerX;
      reactArea.startY = e.layerY;
      isMouseDown = true
    })
    ele.addEventListener('mousemove', function(e) {
      if(isMouseDown){
        let preArea = ele.getElementsByClassName('v-selected-area')
        if(preArea.length){
          ele.removeChild(preArea[0])
        }
        reactArea.endX = e.layerX
        reactArea.endY = e.layerY
        let leftValue = 0
        let topValue = 0
        let widthValue = Math.abs(reactArea.startX - reactArea.endX)
        let heightValue = Math.abs(reactArea.startY - reactArea.endY)
        if(reactArea.startX >= reactArea.endX){
          leftValue = reactArea.endX
        }else{
          leftValue = reactArea.startX
        }
        if(reactArea.startY > reactArea.endY ){
          topValue = reactArea.endY
        }else{
          topValue = reactArea.startY
        }
        //判斷同時(shí)有寬高才開始畫虛線框
        if(reactArea.startX != reactArea.endX && reactArea.startY !=reactArea.endY){
          areaSelect = document.createElement('div')
          areaSelect.classList.add("v-selected-area")
          areaSelect.style.position = "absolute";
          areaSelect.style.left = leftValue + 'px'
          areaSelect.style.top = topValue + 'px'
          areaSelect.style.width = widthValue + 'px'
          areaSelect.style.height = heightValue + 'px'
          areaSelect.style.border = "1px dashed grey"
          ele.append(areaSelect)
        }
      }
    })
    ele.addEventListener('mouseup', function(e) {
      isMouseDown = false
      //每次鼠標(biāo)點(diǎn)擊完了areaSelect
      if(areaSelect && areaSelect.childNodes && ele.contains(areaSelect)){
        ele.removeChild(areaSelect)
      }
      areaSelect = null
    })
  }
   Vue.directive('selectable',{
    inserted:listener,
    updated:listener
  })
}

這個(gè)時(shí)就可以實(shí)現(xiàn)畫虛線框的效果

如何自定義類似于jQueryUISelectable的Vue指令v-selectable

下一步是如何把每個(gè)item置為選中狀態(tài)。思路是遍歷這個(gè)容器ul 的所有子元素li ,然后判斷每個(gè)li是否在選中的框內(nèi)部。然后看每個(gè)元素的offsetLeft 和 offsetTop 計(jì)算元素相對(duì)于父元素的位置,然后通過getBoundingClientRect().height 和 getBoundingClientRect().width 確定子元素的寬高。這些就可以計(jì)算出元素的位置和大小了,然后如何判斷這個(gè)元素是否在選擇區(qū)域內(nèi)呢?我的規(guī)則是這個(gè)元素的四個(gè)角位置有任何一個(gè)在選擇區(qū)域內(nèi)或者選擇區(qū)域就在這個(gè)區(qū)域的內(nèi)部,就算是這個(gè)元素被選中了(這個(gè)判斷方式感覺不是很完美)。按照這個(gè)思路,繼續(xù)完成我們的代碼:

export default (Vue, options = {}) =>{
 const listener = (ele, binding) =>{
 let reactArea = {
  startX: 0,
  startY: 0,
  endX: 0,
  endY: 0
 }
 //是否一直按下鼠標(biāo)
 let isMouseDown = false
 let areaSelect = {}
 //將元素定位改為relative
 ele.style.position = 'relative'
 ele.addEventListener('mousedown', function(e) {
  reactArea.startX = e.layerX;
  reactArea.startY = e.layerY;
  isMouseDown = true
 })
 ele.addEventListener('mousemove', function(e) {
  if(isMouseDown){
   let preArea = ele.getElementsByClassName('v-selected-area')
  if(preArea.length){
   ele.removeChild(preArea[0])
  }
  reactArea.endX = e.layerX
  reactArea.endY = e.layerY
  let leftValue = 0
  let topValue = 0
  let widthValue = Math.abs(reactArea.startX - reactArea.endX)
  let heightValue = Math.abs(reactArea.startY - reactArea.endY)
  if(reactArea.startX >= reactArea.endX){
   leftValue = reactArea.endX
  }else{
   leftValue = reactArea.startX
  }
  if(reactArea.startY > reactArea.endY ){
   topValue = reactArea.endY
  }else{
   topValue = reactArea.startY
  }
  //判斷同時(shí)有寬高才開始畫虛線框
  if(reactArea.startX != reactArea.endX && reactArea.startY !=reactArea.endY){
   areaSelect = document.createElement('div')
   areaSelect.classList.add("v-selected-area")
   areaSelect.style.position = "absolute";
   areaSelect.style.left = leftValue + 'px'
   areaSelect.style.top = topValue + 'px'
   areaSelect.style.width = widthValue + 'px'
   areaSelect.style.height = heightValue + 'px'
   areaSelect.style.border = "1px dashed grey"
   ele.append(areaSelect)
  }
  let children = ele.getElementsByTagName('li')
  for(let i =0 ; i < children.length ; i ++ ){
   let childrenHeight = children[i].getBoundingClientRect().height
   let childrenWidth = children[i].getBoundingClientRect().width
   //每個(gè)li元素的位置
   let offsetLeft = children[i].offsetLeft
   let offsetTop = children[i].offsetTop
   //每個(gè)li元素的寬高
   let endPositionH = childrenHeight + offsetTop
   let endPositionW = childrenWidth + offsetLeft
   //五個(gè)條件滿足一個(gè)就可以判斷被選擇
   //一是右下角在選擇區(qū)域內(nèi)
   let require1 = endPositionH > topValue && endPositionW > leftValue && endPositionH < topValue + heightValue && endPositionW < leftValue + widthValue
   //二是左上角在選擇區(qū)域內(nèi)
   let require2 = offsetTop > topValue && offsetLeft > leftValue && offsetTop < topValue + heightValue && offsetLeft < leftValue + widthValue
   //三是右上角在選擇區(qū)域內(nèi)
   let require3 = offsetTop > topValue && offsetLeft + childrenWidth > leftValue && offsetTop < topValue + heightValue && offsetLeft + childrenWidth< leftValue + widthValue
   //四是左下角在選擇區(qū)域內(nèi)
   let require4 = offsetTop + childrenHeight > topValue && offsetLeft > leftValue && offsetTop + childrenHeight < topValue + heightValue && offsetLeft < leftValue + widthValue
   //五選擇區(qū)域在元素體內(nèi)
   let require5 = offsetTop < topValue && offsetLeft < leftValue && offsetTop + childrenHeight > topValue + heightValue && offsetLeft + childrenWidth > leftValue + widthValue
   if(require1 || require2 || require3 || require4 || require5){
   children[i].classList.add('active')
   }else{
   children[i].classList.remove('active')
   }
  }
  }
 })
 ele.addEventListener('mouseup', function(e) {
  isMouseDown = false
  if(areaSelect && areaSelect.childNodes && ele.contains(areaSelect)){
  ele.removeChild(areaSelect)
  }
  areaSelect = null
 })
 }
 Vue.directive('selectable',{
 inserted:listener,
 updated:listener
 })
}

完成之后再看看如何使用,html 結(jié)構(gòu):

<ul v-selectable >
  <li class="square">
 item1
  </li>
  <li class="oval">
 item2
  </li>
  <li class="triangle">
 item3
  </li>
  <li class="triangle-topleft">
 item4
  </li>
  <li class="curvedarrow">
 item5
  </li>
  <li class="triangle-topleft">
 item6
  </li>
</ul>

注意ul的這個(gè)v-selectable就是我們自定義的指令,但是使用之前必須 Vue.use

import Vue from 'vue'
import Selectable from '@/components/vue-selectable/vue-selectable.js' //這個(gè)修改為你的js路徑
Vue.use(Selectable);

再給我們的ul li 加點(diǎn)樣式,注意我們的被選擇項(xiàng)會(huì)被添加一個(gè)active的class,通過這個(gè)來改變選中項(xiàng)樣式

<style scoped>
 ul{
 margin: 40px 40px 40px 40px;
 border: 1px solid red;
 width: 300px;
 padding-bottom: 20px;
 }
 ul li {
 width: 200px;
 height: 30px;
 list-style: none;
 border: 1px solid black;
 margin-left: 10px;
 margin-top: 30px;
 text-align: center;
 line-height: 30px;
 user-select:none;
 }
 ul li.active{
 background-color: red;
 }
</style>

這樣就可以達(dá)到開頭的效果了。實(shí)際上代碼運(yùn)行過程中還是有許多小bug的,本文只是提供了一個(gè)簡(jiǎn)單的思路和代碼,更多功能可以自己修改代碼進(jìn)行添加。如果不明白這個(gè)自定義指令為什么是這樣的寫法,可以參考我的另一篇文章自定義懶加載圖片插件v-lazyload。

上述就是小編為大家分享的如何自定義類似于jQueryUISelectable的Vue指令v-selectable了,如果剛好有類似的疑惑,不妨參照上述分析進(jìn)行理解。如果想知道更多相關(guān)知識(shí),歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道。

網(wǎng)站題目:如何自定義類似于jQueryUISelectable的Vue指令v-selectable
文章地址:http://m.newbst.com/article34/pogese.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供小程序開發(fā)網(wǎng)站建設(shè)企業(yè)建站微信公眾號(hào)網(wǎng)頁設(shè)計(jì)公司網(wǎng)站維護(hù)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

成都seo排名網(wǎng)站優(yōu)化