vue-contextmenu-json
Version:
Vue-contextmenu component,use only with json data
122 lines (121 loc) • 5.57 kB
JavaScript
import './index.css';
export default {
//binding.value={array:Array,ref:String}
install: (function () {
let contextmenu = {};
let node = {};
//隐藏所有菜单
function HiddenContextMenu() {
let ctm = document.querySelectorAll('.Plugin__Contextmenu__Container');
if (isDef(ctm)) {
ctm.forEach(element => {
element.style.display = 'none';
})
}
}
//生成菜单文件
/**
*
* @param {Array} array 生成数据的Array实例
* @param {string} id 当前菜单的id值,要求唯一
* @param {Object} context 当前vnode所在的vue实例
*/
function CreateContextmenuDOM(array, id, context) {
let div = document.createElement('div');
if (isDef(id)) {
div.setAttribute('id', id);
div.className = 'Plugin__Contextmenu__Container';
}
/*
let triangle = document.createElement('div');
triangle.className = 'Plugin__Contextmenu__triangle';
div.appendChild(triangle);
*/
let dom = document.createElement('ul');
dom.className = 'Plugin__Contextmenu__ul';
div.appendChild(dom);
for (let ii in array) {
let li = document.createElement('li');
li.innerText = array[ii].name;
li.className = 'Plugin__Contextmenu__li';
li.addEventListener('click', function (event) {
if (process.env.NODE_ENV !== 'production') {
console.log('in li click');
console.log(context[array[ii].function]);
}
let nowNode = this;
context[array[ii].function].call(this, node, event);
// Remove contextmenu DOM
let docs = document.getElementsByClassName('Plugin__Contextmenu__Container');
Array.prototype.slice.call(docs).forEach(item => {
document.body.removeChild(item);
})
})
if (isArray(array[ii].child)) {
let childUl = CreateContextmenuDOM(array[ii].child, id + ' ', context);
li.appendChild(childUl);
}
dom.appendChild(li);
}
return div;
}
function isDef(value) {
return value !== undefined && value !== null;
}
function isArray(value) {
return Object.prototype.toString.call(value) === '[object Array]';
}
// TODO 20190909 如果用在循环组件中,要如何处理???
function factory(Vue, options) {
'use strict';
Vue.directive('contextmenu', {
bind: function (el, binding, vnode) {
let { value, modifiers } = binding;
let { array, id } = value;
if (document.getElementById(id)) {
throw new Error('Vue-Contextmenu-Json: id property should not be repeated ');
}
document.removeEventListener('click', HiddenContextMenu, true);
document.removeEventListener('contextmenu', HiddenContextMenu, true)
document.addEventListener('click', HiddenContextMenu, true);
document.addEventListener('contextmenu', HiddenContextMenu, true)
el.addEventListener(modifiers.click ? 'click' : 'contextmenu', function (event) {
//先卸载所有其他内容
let dom = document.getElementById(id);
if (!dom) {
dom = CreateContextmenuDOM(array, id, vnode.context);
document.body.appendChild(dom);
//node = event.target;;
event.preventDefault();
HiddenContextMenu();
}
dom.style.display = 'block';
let height = 30 * array.length
let width = 200
var w=document.documentElement.clientWidth;
var h=document.documentElement.clientHeight;
if (h < height + event.clientY) {
dom.style.top = (event.clientY - height) + 'px'
} else {
dom.style.top = event.clientY + 'px'
}
if (w < width + event.clientX) {
dom.style.left = (event.clientX - width) + 'px'
}else{
dom.style.left = event.clientX + 'px'
}
}, false)
},
unbind: function (el, binding, vnode) {
let { value } = binding
let { id } = value
let dom = document.getElementById(id)
if (dom !== null) {
document.body.removeChild(dom)
}
}
})
}
return factory;
}())
}