JS使用iView的Dropdown實(shí)現(xiàn)一個右鍵菜單
前段時(shí)間在用iView做個項(xiàng)目,其中需要使用自定義的右鍵菜單,然后去官網(wǎng)找了一下,發(fā)現(xiàn)有個Dropdown的組件,便想著能不能用來做個右鍵菜單的組件
你可能需要對iView有一定的使用經(jīng)驗(yàn)
嘗試
Dropdown的使用大概是這個樣子
<template>
<Dropdown>
<a href="javascript:void(0)" rel="external nofollow" >
下拉菜單
<Icon type="ios-arrow-down"></Icon>
</a>
<DropdownMenu slot="list">
<DropdownItem>驢打滾</DropdownItem>
<DropdownItem>炸醬面</DropdownItem>
<DropdownItem disabled>豆汁兒</DropdownItem>
<DropdownItem>冰糖葫蘆</DropdownItem>
<DropdownItem divided>北京烤鴨</DropdownItem>
</DropdownMenu>
</Dropdown>
</template>
<script>
export default {
}
</script>
發(fā)現(xiàn)有個觸發(fā)元素slot,可以自定義的插入元素,我一想,只要把slot的內(nèi)容設(shè)置為position: fixed,在右鍵的時(shí)候給它實(shí)時(shí)設(shè)置一下鼠標(biāo)所在的位置不就行了嘛,然后一頓搗騰
<template>
<Dropdown
transfer
placement="right-start"
trigger="custom"
:visible="currentVisible"
@on-clickoutside="handleCancel"
>
<div :style="locatorStyle"></div>
<DropdownMenu slot="list">
<DropdownItem>驢打滾</DropdownItem>
<DropdownItem>炸醬面</DropdownItem>
<DropdownItem disabled>豆汁兒</DropdownItem>
<DropdownItem>冰糖葫蘆</DropdownItem>
<DropdownItem divided>北京烤鴨</DropdownItem>
</DropdownMenu>
</Dropdown>
</template>
<script>
export default {
data () {
return {
posX: 0,
posY: 0,
currentVisible: false
}
},
computed: {
locatorStyle () {
return {
position: 'fixed',
left: `${this.posX}px`,
top: `${this.posY}px`
}
}
},
methods: {
handleContextmenu ({ button, clientX, clientY }) {
if (button === 2) {
if (this.posX !== clientX) this.posX = clientX
if (this.posY !== clientY) this.posY = clientY
this.currentVisible = true
}
},
handleCancel () {
this.currentVisible = false
}
},
mounted () {
document.addEventListener('contextmenu', this.handleContextmenu, true)
document.addEventListener('mouseup', this.handleContextmenu, true)
},
destroyed () {
document.removeEventListener('contextmenu', this.handleContextmenu, true)
document.removeEventListener('mouseup', this.handleContextmenu, true)
}
}
</script>
看上去很不錯,然后興高采烈地一試,發(fā)現(xiàn)無論怎么點(diǎn),菜單始終定位在右上角


slot的元素位置確實(shí)發(fā)生了變化,然而菜單位置始終不變化
這可把我折騰了半天,也沒弄出個結(jié)果。抱著 極不情愿 一探究竟的心情,我打開了Dropdown的源碼
<template>
<div
:class="[prefixCls]"
v-click-outside="onClickoutside"
@mouseenter="handleMouseenter"
@mouseleave="handleMouseleave">
<!-- 注意此處 -->
<div :class="relClasses" ref="reference" @click="handleClick" @contextmenu.prevent="handleRightClick"><slot></slot></div>
<transition name="transition-drop">
<Drop
:class="dropdownCls"
v-show="currentVisible"
:placement="placement"
ref="drop"
@mouseenter.native="handleMouseenter"
@mouseleave.native="handleMouseleave"
:data-transfer="transfer"
:transfer="transfer"
v-transfer-dom><slot name="list"></slot></Drop>
</transition>
</div>
</template>
<script>
// 以下省略
</script>
可以看到標(biāo)注的地方,slot的外層還有個div,而Dropdown的定位是依賴于外層的這個div的,所以無論你slot里的內(nèi)容位置,在初始化之后再怎么變化,都不會影響到組件的位置了(也有可能是position: fixed的影響)
調(diào)整
發(fā)現(xiàn)slot外層的div有一個ref="reference"的屬性
突然有了想法,我是不是可以直接通過Dropdown的refs直接把整個外層div替換掉,于是繼續(xù)搗騰,改造了一下
<template>
<Dropdown
transfer
placement="right-start"
trigger="custom"
ref="contextMenu"
:visible="currentVisible"
@on-clickoutside="handleCancel"
>
<DropdownMenu slot="list">
<DropdownItem>驢打滾</DropdownItem>
<DropdownItem>炸醬面</DropdownItem>
<DropdownItem disabled>豆汁兒</DropdownItem>
<DropdownItem>冰糖葫蘆</DropdownItem>
<DropdownItem divided>北京烤鴨</DropdownItem>
</DropdownMenu>
</Dropdown>
</template>
<script>
export default {
data () {
return {
posX: 0,
posY: 0,
currentVisible: false,
locator: null
}
},
methods: {
createLocator () {
// 獲取Dropdown
const contextmenu = this.$refs.contextMenu
// 創(chuàng)建locator
const locator = document.createElement('div')
locator.style.cssText = `position:fixed;left:${this.posX}px;top:${this.posY}px`
document.body.appendChild(locator)
// 將locator綁定到Dropdown的reference上
contextmenu.$refs.reference = locator
this.locator = locator
},
removeLocator () {
if (this.locator) document.body.removeChild(this.locator)
this.locator = null
},
handleContextmenu ({ button, clientX, clientY }) {
if (button === 2) {
if (this.posX !== clientX) this.posX = clientX
if (this.posY !== clientY) this.posY = clientY
if (this.trigger !== 'custom') {
this.createLocator()
this.currentVisible = true
}
}
},
handleCancel () {
this.currentVisible = false
this.removeLocator()
}
},
mounted () {
document.addEventListener('contextmenu', this.handleContextmenu, true)
document.addEventListener('mouseup', this.handleContextmenu, true)
},
destroyed () {
document.removeEventListener('contextmenu', this.handleContextmenu, true)
document.removeEventListener('mouseup', this.handleContextmenu, true)
}
}
</script>
根據(jù)鼠標(biāo)的位置實(shí)時(shí)創(chuàng)建一個position: fixed的div,通過給Dropdown添加ref屬性,獲取到Dropdown對象之后再通過$ref屬性將div賦值到reference
大功告成,現(xiàn)在Dropdown會根據(jù)鼠標(biāo)所在的位置出現(xiàn)啦

最后把一些點(diǎn)擊的回調(diào)方法補(bǔ)全,就是一個像樣的右鍵菜單組件了
當(dāng)然作為一個可以復(fù)用的組件,還需要把一些通用邏輯再提取出來,以及補(bǔ)全一些常用的API,具體代碼可以參考這個倉庫
總結(jié)
以上所述是小編給大家介紹的JS使用iView的Dropdown實(shí)現(xiàn)一個右鍵菜單,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時(shí)回復(fù)大家的。在此也非常感謝大家對腳本之家網(wǎng)站的支持!
如果你覺得本文對你有幫助,歡迎轉(zhuǎn)載,煩請注明出處,謝謝!
- js實(shí)現(xiàn)右鍵菜單功能
- JS組件Bootstrap ContextMenu右鍵菜單使用方法
- JavaScript模擬鼠標(biāo)右鍵菜單效果
- js實(shí)現(xiàn)完全自定義可帶多級目錄的網(wǎng)頁鼠標(biāo)右鍵菜單方法
- 深入探討JavaScript、JQuery屏蔽網(wǎng)頁鼠標(biāo)右鍵菜單及禁止選擇復(fù)制
- js禁止頁面復(fù)制功能禁用頁面右鍵菜單示例代碼
- JavaScript 對任意元素,自定義右鍵菜單的實(shí)現(xiàn)方法
- JS組件Bootstrap dropdown組件擴(kuò)展hover事件
- JS簡單操作select和dropdownlist實(shí)例
- asp.net省市三級聯(lián)動的DropDownList+Ajax的三種框架(aspnet/Jquery/ExtJs)示例
相關(guān)文章
WEB開發(fā)之注冊頁面驗(yàn)證碼倒計(jì)時(shí)代碼的實(shí)現(xiàn)
近期在搞一個H5+backbone 項(xiàng)目,驗(yàn)證輸入手機(jī)號 驗(yàn)證碼倒計(jì)時(shí)功能,代碼中包含了前端樣式布局代碼和后端邏輯實(shí)現(xiàn),思路明確,具有參考借鑒價(jià)值,需要的朋友參考下吧2016-12-12
JS實(shí)現(xiàn)頁面中所有img對象添加onclick事件及新窗口查看圖片的方法
這篇文章主要介紹了JS實(shí)現(xiàn)頁面中所有img對象添加onclick事件及新窗口查看圖片的方法,涉及JS頁面元素遍歷及屬性動態(tài)操作相關(guān)技巧,需要的朋友可以參考下2016-12-12
js前端實(shí)現(xiàn)圖片懶加載(lazyload)的兩種方式
本篇文章主要介紹了js前端實(shí)現(xiàn)圖片懶加載(lazyload)的兩種方式 ,使用圖片懶加載可以提高網(wǎng)頁運(yùn)行速度,有興趣的可以了解一下。2017-04-04
使用TypeScript?V8來改進(jìn)您的JavaScript代碼
TypeScript?V8是一個強(qiáng)大的JavaScript類型系統(tǒng),它可以幫助你發(fā)現(xiàn)JavaScript代碼中的錯誤和潛在問題,并在編譯時(shí)捕獲它們,以便您可以解決它們,TypeScript?V8為JavaScript提供一系列的類型注釋,包括自定義類型和其他高級功能2023-08-08
關(guān)于Bootstrap彈出框無法調(diào)用問題的解決辦法
這篇文章主要介紹了關(guān)于Bootstrap彈出框無法調(diào)用問題的解決辦法的相關(guān)資料,需要的朋友可以參考下2016-03-03

