JSFiddle - React, Tailwind, and code Playground
by ChangJoo Park
HTML
<script src="https://unpkg.com/[email protected]/dist/vue.js"></script>
<div id="app">
<div class="message-wrapper">
<div v-for="message in messages" class="message-item">
{{message}}
</div>
</div>
<context-menu ref="contextMenu"></context-menu>
</div>
<template id="context-menu">
<div class="context-menu" v-if="isOpen">
<div v-for="item in items" class="context-menu-item">
{{item}}
</div>
</div>
</template>
CSS
html, body {
box-sizing: border-box;
user-select: none;
}
.message-item {
padding: 20px;
border-bottom: 1px solid tomato;
border-left: 1px solid tomato;
border-right: 1px solid tomato;
cursor: pointer;
}
.message-item:first-child {
border-top: 1px solid tomato;
}
.context-menu {
border: 1px solid orange;
display: inline-block;
position: absolute;
width: 100px;
}
.context-menu-item {
text-align: center;
padding: 3px;
border-bottom: 1px solid orange;
cursor: pointer;
}
.context-menu-item:last-child {
border-bottom: none;
}
JavaScript
function getPosition(e) {
var posx = 0;
var posy = 0;
if (!e) var e = window.event;
if (e.pageX || e.pageY) {
posx = e.pageX;
posy = e.pageY;
} else if (e.clientX || e.clientY) {
posx = e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft;
posy = e.clientY + document.body.scrollTop + document.documentElement.scrollTop;
}
return {
x: posx,
y: posy
}
}
Vue.component('context-menu', {
template: '#context-menu',
data: function () {
return {
isOpen: false,
items: ['A', 'B', 'C', 'D']
}
}
})
new Vue ({
el: '#app',
mounted: function () {
var item = document.querySelector('.message-wrapper');
console.log(item);
item.addEventListener('contextmenu', function (event) {
event.preventDefault();
var contextMenuComponent = this.$refs.contextMenu;
var contextMenuDOM = contextMenuComponent.$el;
var menuWidth = contextMenuDOM.clientWidth;
var menuHeight = contextMenuDOM.clientHeight;
contextMenuComponent.$data.isOpen = true;
var position = getPosition(event);
console.log(position);
console.log(contextMenuDOM.style);
}.bind(this));
},
data: function () {
return {
messages: [
'Hello - A',
'Hello - B',
'Hello - C',
'Hello - D',
'Hello - E'
]
}
}
})