JSFiddle - React, Tailwind, and code Playground
by MeoMix
HTML
<script src="http://requirejs.org/docs/release/2.1.2/minified/require.js"></script>
<div class='clickable'>
right-click me!
</div>
<div id="contextMenu">
</div>
<script type="text/template" id="contextMenuTemplate">
<% groups.each(function(group){ %>
<ul id="<%= group.cid %>">
<% group.get('items').each(function(item){ %>
<li>
<a id="<%= item.cid %>" href="#"><%= item.get('text') %></a>
</li>
<% }); %>
</ul>
<% }); %>
</script>
CSS
body{
height: 600px;
width: 600px;
}
.clickable{
position: absolute;
padding: 20px;
background: black;
color: white;
left: 20%;
top: 20%;
}
#contextMenu {
-webkit-box-shadow: 4px 7px 3px rgba(0, 0, 0, .3);
background: #fff;
position: absolute;
z-index: 100;
padding: 5px 0;
border: 1px solid #BABABA;
display: none;
}
#contextMenu ul {
list-style: none;
padding: 0;
margin: 0;
}
#contextMenu ul:not(:last-child) {
border-bottom: 1px solid #EFEFEF;
}
#contextMenu ul li {
overflow: hidden;
max-width: 200px;
text-overflow: ellipsis;
white-space: nowrap;
color: #000;
padding: 0 15px;
}
#contextMenu ul a {
color: #000;
font: 12px/2.2 sans-serif;
text-decoration: none;
}
#contextMenu ul li:hover { background: #EFEFEF; }
#contextMenu ul li:active {
background: rgb(36, 109, 149);
color: #fff;
}
JavaScript
require.config({
paths: {
jquery: "http://code.jquery.com/jquery.min",
underscore: "http://underscorejs.org/underscore-min",
backbone: "http://backbonejs.org/backbone-min"
},
shim: {
underscore: { exports: "_" },
backbone: { deps: ["underscore", "jquery"], exports: "Backbone" },
stickit: { deps: ["backbone"] }
}
});
require(['jquery', 'underscore', 'backbone'], function($, _, Backbone){
require(['app'], function(App){});
});
define("app", ['contextMenuView'], function(ContextMenuView){
$('.clickable').contextmenu(function(event){
ContextMenuView.addGroup({
position: 0,
items: [{
position: 0,
text: 'And this is a much longer title that could go on for quite some time',
onClick: function () {
}
}]
});
ContextMenuView.show({
top: event.pageY,
left: event.pageX + 1
});
return false;
});
});
define("contextMenuView", ['contextMenu', 'helpers'], function (ContextMenu, helpers) {
'use strict';
// A singleton view which is either displayed somewhere in body with groups of items or empty and hidden.
var ContextMenuView = Backbone.View.extend({
el: $('#contextMenu'),
template: _.template($('#contextMenuTemplate').html()),
events: {
'click li': 'onItemClick',
},
model: new ContextMenu,
render: function () {
this.$el.html(this.template(this.model.toJSON()));
this.$el.find('a').each(function () {
var parentUl = $(this).closest('ul');
helpers.scrollElementInsideParent(this, parentUl);
});
// TODO: Should this logic be part of 'show' or 'render' ?
// Prevent display outside viewport.
var...