JS使用iView的Dropdown實(shí)現(xiàn)一個(gè)右鍵菜單
前段時(shí)間在用iView做個(gè)項(xiàng)目,其中需要使用自定義的右鍵菜單,然后去官網(wǎng)找了一下,發(fā)現(xiàn)有個(gè)Dropdown的組件,便想著能不能用來(lái)做個(gè)右鍵菜單的組件
你可能需要對(duì)iView有一定的使用經(jīng)驗(yàn)
嘗試
Dropdown的使用大概是這個(gè)樣子
<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)有個(gè)觸發(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>
看上去很不錯(cuò),然后興高采烈地一試,發(fā)現(xiàn)無(wú)論怎么點(diǎn),菜單始終定位在右上角


slot的元素位置確實(shí)發(fā)生了變化,然而菜單位置始終不變化
這可把我折騰了半天,也沒(méi)弄出個(gè)結(jié)果。抱著 極不情愿 一探究竟的心情,我打開(kāi)了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的外層還有個(gè)div,而Dropdown的定位是依賴(lài)于外層的這個(gè)div的,所以無(wú)論你slot里的內(nèi)容位置,在初始化之后再怎么變化,都不會(huì)影響到組件的位置了(也有可能是position: fixed的影響)
調(diào)整
發(fā)現(xiàn)slot外層的div有一個(gè)ref="reference"的屬性
突然有了想法,我是不是可以直接通過(guò)Dropdown的refs直接把整個(gè)外層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)建一個(gè)position: fixed的div,通過(guò)給Dropdown添加ref屬性,獲取到Dropdown對(duì)象之后再通過(guò)$ref屬性將div賦值到reference
大功告成,現(xiàn)在Dropdown會(huì)根據(jù)鼠標(biāo)所在的位置出現(xiàn)啦

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

