Javascript: Trying to make images draggable and compare objects - javascript

stacksocial newbie here.
I'm working on a web project that's basically a puzzle game that teaches people how to configure the parts for a computer. Think pcpartpicker meets a puzzle but without the purchasing.
I've created several javascript objects with different elements that I plan on comparing via elements. (e.g Motherboard object has socket element and CPU has a socket element and these elements must match to continue).
When you click on the object in the nav. menu, an click event occurs where you the corresponding picture appears. I want to make that picture draggable. The end goal is to drag all the pictures together and compare the elements to make sure everything works out and if objects don't match an alert will tell the user that its wrong.
Here's jsfiddle: http://jsfiddle.net/ciddo/sgf50j96/9/
HTML+Javascript
<title>Practice</title>
<link rel="stylesheet" href="css/style.css" type="text/css" />
<!--[if lt IE 8]>
<script src ="http://ie7- js.googlecode.com/svn/version/2.1(beta2)/IE8.js"></script>
<![endif]-->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"> </script>
<header>
<script>
var img1; //Motherboard
var img2; //CPU
var img3; //Memory
var img4; //Case
var img5; //Hard Drive
var img6; //Power Supply
</script>
<script>
function preloader() {
if (document.images) {
img1 = new Image();
img2 = new Image();
img3 = new Image();
img4 = new Image();
img5 = new Image();
img6 = new Image();
img1.src = "http://i.imgur.com/u4cQogt.jpg"; // Motherboard
img2.src = "http://i.imgur.com/snLSsMm.png"; // CPU
img3.src = "http://i.imgur.com/L8jc43K.png?1"; // Memory
img4.src = "http://i.imgur.com/oP6hsN0.jpg"; // Case
img5.src = "http://i.imgur.com/WrFaslA.jpg"; // Hard Drive
img6.src = "http://i.imgur.com/IMhS0uw.jpg";// Power Supply
}
}
function addLoadEvent(func) {
var oldonload = window.onload;
if (typeof window.onload != 'function') {
window.onload = func;
} else {
window.onload = function() {
if (oldonload) {
oldonload();
}
func();
}
}
}
addLoadEvent(preloader);
</script>
<script>
function allowDrop(ev) {
ev.preventDefault();
}
function drag(ev) {
ev.dataTransfer.setData("text", ev.target.id);
}
function drop(ev) {
ev.preventDefault();
var data = ev.dataTransfer.getData("text");
ev.target.appendChild(document.getElementById(data));
}
</script>
<script>
//Need to call the folder containing images for all pc parts
//Variables that are used
var MoboSocket= ['LGA 1155','LGA 1150','LGA 1150','AM2','AM1','AM3'];
var MoboSize = ['ATX_Large','Micro-ATX_Medium','Mini-ITX_Small'];
var MoboMem = ['DDR','DDR2','DDR3','DDR4'];
var MoboPower = [25,50,75];
var intel = ['LGA 1155','LGA 1150','LGA 1150'];
var amd = ['AM2','AM1','AM3'];
var cpupower = [90,120,150,175,220];
var caseSize = ['Large','Medium','Small'];
var Memory = ['DDR','DDR2','DDR3','DDR4'];
var ram = [2,4,8,16];
var Power = [300,400,500,600,700];
var hddSize = [250,500,750,1000];
//Motherboards
var Motherboard = document.createElement("IMG");
var Motherboard1 = {
Socket:MoboSocket[Math.floor((Math.random()*MoboSocket.length))],
Size:MoboSize[Math.floor((Math.random()*MoboSize.length))],
RAM:MoboMem[Math.floor((Math.random()*MoboMem.length))],
Power:MoboPower[Math.floor((Math.random()*MoboPower.length))]
};
var Motherboard2 = {
Socket:MoboSocket[Math.floor((Math.random()*MoboSocket.length))],
Size:MoboSize[Math.floor((Math.random()*MoboSize.length))],
RAM:MoboMem[Math.floor((Math.random()*MoboMem.length))],
Power:MoboPower[Math.floor((Math.random()*MoboPower.length))]
};
var Motherboard3 = {
Socket:MoboSocket[Math.floor((Math.random()*MoboSocket.length))],
Size:MoboSize[Math.floor((Math.random()*MoboSize.length))],
RAM:MoboMem[Math.floor((Math.random()*MoboMem.length))],
Power:MoboPower[Math.floor((Math.random()*MoboPower.length))]
};
var Motherboard4 = {
Socket:MoboSocket[Math.floor((Math.random()*MoboSocket.length))],
Size:MoboSize[Math.floor((Math.random()*MoboSize.length))],
RAM:MoboMem[Math.floor((Math.random()*MoboMem.length))],
Power:MoboPower[Math.floor((Math.random()*MoboPower.length))]
};
//CPU Parts
var Intel_CPU = {
CPU:"Intel",
Socket:intel[Math.floor((Math.random()*intel.length))],
Power:cpupower[Math.floor(Math.random()*cpupower.length)]
};
var AMD_CPU = {
CPU:"AMD",
Socket:amd[Math.floor((Math.random()*amd.length))],
Power:cpupower[Math.floor(Math.random()*cpupower.length)]
};
//Cases
var Case1 = {
Size:caseSize[Math.floor((Math.random()*caseSize.length))]
};
var Case2 = {
Size:caseSize[Math.floor((Math.random()*caseSize.length))]
};
//Memory
var Memory1 = {
Type:Memory[Math.floor((Math.random()*Memory.length))],
Size:ram[Math.floor((Math.random()*ram.length))]
};
var Memory2 = {
Type:Memory[Math.floor((Math.random()*Memory.length))],
Size:ram[Math.floor((Math.random()*ram.length))]
};
var Memory3 = {
Type:Memory[Math.floor((Math.random()*Memory.length))],
Size:ram[Math.floor((Math.random()*ram.length))]
};
//Power Supply
var Power_Supply1 = {
Wattage:Power[Math.floor((Math.random()*Power.length))]
};
var Power_Supply2 = {
Wattage:Power[Math.floor((Math.random()*Power.length))]
};
//Hard Drives
var Hard_Drive1 = {
Size:hddSize[Math.floor(Math.random()*hddSize.length)]
};
var Hard_Drive2 = {
Size:hddSize[Math.floor(Math.random()*hddSize.length)]
};
//Generic Print Functions
function printPart(obj){
var str = "";
for (var x in obj){
str +="<br>"+obj[x];
}
return str;
};
function printMobo(obj){
var str1 = "<br> Socket: "+obj.Socket;
var str2 = "<br> Size: "+obj.Size;
var str3 = "<br> RAM Type: "+obj.RAM;
var str4 = "<br>"+obj.Power;
var str5 = str1+str2+str3+str4;
return str5;
};
function printCPU(obj){
var str1 = "<br> Type: "+obj.CPU;
var str2 = "<br> Socket: "+obj.Socket;
var str4 = "<br>"+obj.Power;
var str5 = str1+str2+str4;
return str5;
};
</script>
<script>
// Dragable moveable object code thingy
var ele = document.getElementsByClassName ("Motherboard")[0];
//ele.onmousedown = eleMouseDown;
ele.addEventListener ("mousedown" , eleMouseDown , false);
function eleMouseDown () {
stateMouseDown = true;
document.addEventListener ("mousemove" , eleMouseMove , false);
}
function eleMouseMove (ev) {
var pX = ev.pageX;
var pY = ev.pageY;
ele.style.left = pX + "px";
ele.style.top = pY + "px";
document.addEventListener ("mouseup" , eleMouseUp , false);
}
function eleMouseUp () {
document.removeEventListener ("mousemove" , eleMouseMove , false);
document.removeEventListener ("mouseup" , eleMouseUp , false);
}
</script>
<div id="jQuery">
<script>
$(function(){
});
</script>
</div>
</header>
<body>
<div class="">
<ul id="nav">
<li>Motherboards
<ul>
<li id="Mobo1"><a href="#">Motherboard 1:
<script type="text/javascript">
document.write(printMobo(Motherboard1));
</script>Watts
</a>
</li>
<li id="Motherboard2"><a href="#">Motherboard 2:
<script type="text/javascript">
document.write(printMobo(Motherboard2));
</script>Watts
</a>
</li>
<li id="Motherboard3"><a href="#">Motherboard 3:
<script type="text/javascript">
document.write(printMobo(Motherboard3));
</script>Watts
</a>
</li>
<li id="Motherboard4"><a href="#">Motherboard 4:
<script type="text/javascript">
document.write(printMobo(Motherboard4));
</script>Watts
</a>
</li>
</ul>
</li>
<li>CPUs
<ul>
<li id="CPU1"><a href="#">CPU 1: <script type="text/javascript">
document.write(printCPU(Intel_CPU));
</script>Watts
</a>
</li>
<li id="CPU2"><a href="#">CPU 2: <script type="text/javascript">
document.write(printCPU(AMD_CPU));
</script>Watts
</a>
</li>
</ul>
</li>
<li>Memory
<ul>
<li id="Memory1"><a href="#"><script type="text/javascript">
document.write(printPart(Memory1));
</script>GBs
</a>
</li>
<li id="Memory2"><a href="#"><script type="text/javascript">
document.write(printPart(Memory2));
</script>GBs
</a>
</li>
<li id="Memory3"><a href="#"><script type="text/javascript">
document.write(printPart(Memory3));
</script>GBs
</a>
</li>
</ul>
<li>Power Supplies
<ul>
<li id="PSU1"><a href="#"><script type="text/javascript">
document.write(printPart(Power_Supply1));
</script>Watts
</a>
</li>
<li id="PSU2"><a href="#"><script type="text/javascript">
document.write(printPart(Power_Supply2));
</script>Watts
</a>
</li>
</ul>
</li>
<li>Cases
<ul>
<li id="Case1"><a href="#"><script type="text/javascript">
document.write(printPart(Case1));
</script>
</a>
</li>
<li id="Case2"><a href="#"><script type="text/javascript">
document.write(printPart(Case2));
</script>
</a>
</li>
</ul>
</li>
<li>Hard Drives
<ul>
<li id="HDD1"><a href="#"><script type="text/javascript">
document.write(printPart(Hard_Drive1));
</script>GB
</a>
</li>
<li id="HDD2"><a href="#"><script type="text/javascript">
document.write(printPart(Hard_Drive2));
</script>GB
</a>
</li>
</ul>
</li>
</ul>
<div>
<script>
document.getElementById("Mobo1").addEventListener("click", function() {
document.body.appendChild(img1);
});
document.getElementById("CPU1").addEventListener("click", function() {
document.body.appendChild(img2);
});
document.getElementById("Memory1").addEventListener("click", function() {
document.body.appendChild(img3);
});
document.getElementById("PSU1").addEventListener("click", function() {
document.body.appendChild(img6);
});
document.getElementById("Case1").addEventListener("click", function() {
document.body.appendChild(img4);
});
document.getElementById("HDD1").addEventListener("click", function() {
document.body.appendChild(img5);
});
document.getElementsById(img1).addEventListener("click", function() {
alert("This Click worked");
});
</script>
</div>
</body>
</html>
CSS
body {
font-family: helvetica, arial, sans-serif;
background: #e3e3e3;
text-align: center;
}
/* MENU */
#nav {
background: #e5e5e5;
float: left;
margin: 0; padding: 0;
border: 1px solid white;
border-bottom: none;
}
#nav li a, #nav li {
float: left;
}
#nav li {
list-style: none;
position: relative;
}
#nav li a {
padding: 1em 2em;
text-decoration: none;
color: white;
background: #292929;
background: -moz-linear-gradient(top, black, #3c3c3c 1px, #292929 25px);
background: -webkit-gradient(linear, left top, left 25, from(black), color- stop(4%, #3c3c3c), to(#292929));
border-right: 1px solid #3c3c3c;
border-left: 1px solid #292929;
border-bottom: 1px solid #232323;
border-top: 1px solid #545454;
}
#nav li a:hover {
background: #2a0d65;
background: -moz-linear-gradient(top, #11032e, #2a0d65);
background: -webkit-gradient(linear, left top, left bottom, from(#11032e), to(#2a0d65));
}
/* Submenu */
.hasChildren {
position: absolute;
width: 5px; height: 5px;
background: black;
right : 0;
bottom: 0;
}
#nav li ul {
display: none;
position: absolute;
left: 0;
top: 100%;
padding: 0; margin: 0;
}
#nav li:hover > ul {
display: block;
}
#nav li ul li, #nav li ul li a {
float: none;
}
#nav li ul li {
_display: inline; /* for IE6 */
}
#nav li ul li a {
width: 150px;
display: block;
}
/* SUBSUB Menu */
#nav li ul li ul {
display: none;
}
#nav li ul li:hover ul {
left: 100%;
top: 0;
}
#nav li ul

Related

How to display all articles with same height [duplicate]

This question already has answers here:
Floated elements of variable height push siblings down
(3 answers)
Closed 3 years ago.
I'm working on a website where i want to display the recommended videos from my youtube channel. I can load all the videos and display them but after 4-5 rows theres a problem. Some Videos are a few milimeters heigher and destroy the whole layout.
Those are the first two rows and how it should be
And then the 4 and the 5 row looks like this
The 3th video in the first row is few milimeteres heigher and this destroy the whole layout so how can i format all cells the same i ve tried adding display:table to the parent and display:table-cell to thec hild without success
Here is the HTML and the JS
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://code.jquery.com/jquery-1.11.1.min.js"></script>
<script src="https://code.jquery.com/ui/1.11.1/jquery-ui.min.js"></script>
<link href="../css/youtube.css" type ="text/css" rel="stylesheet">
<link href="../css/navigation.css" type ="text/css" rel="stylesheet">
</head>
<body>
<div id ="main">
<div class="menu">
<div class="hori-menu">
<ul>
<ul>
<li>Weiterschauen</li>
<li>Meine Serien</li>
<li>Demnächst</li>
<li>Vorschläge</li>
<li><a class="active" href="youtube.html">YouTube</a></li>
<li>Mitbewohner</li>
</ul>
</ul>
</div>
</div>
<main id="container">
<section id="video"></section>
<div id="videos"></div>
</main>
</body>
<script language="JavaScript">
var key = '...';
var videos = [];
var totalResults = 0;
$(document).ready(function(){
getMyChannel();
});
function shuffle() {
for (let i = videos.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[videos[i], videos[j]] = [videos[j], videos[i]];
}
}
function getMyChannel(){
var url = "https://www.googleapis.com/youtube/v3/activities";
var options = {
part: 'contentDetails',
channelId: 'UCAe66hs74KDbpvK2x3ZrTXA',
maxResults: 20,
key: key
}
loadUser();
function loadUser(){
$.getJSON(url, options, function(data){
loadUsersChannels(data);
});
}
function loadUsersChannels(data){
$.each(data.items, function (i, item) {
var id = item.contentDetails.subscription.resourceId.channelId;
getChannel(id);
});
}
}
function getChannel(id){
var url = "https://www.googleapis.com/youtube/v3/channels";
var options = {
part: 'snippet,contentDetails',
id: id,
maxResults: 20,
key: key
}
loadLists();
function loadLists(){
$.getJSON(url, options, function(data) {
loadPlaylists(data);
});
}
function loadPlaylists(data){
$.each(data.items, function (i, item) {
var id = item.contentDetails.relatedPlaylists.uploads;
getPlaylist(id);
});
}
}
function getPlaylist(playlistId){
var URL = 'https://www.googleapis.com/youtube/v3/playlistItems';
var options = {
part: 'snippet',
key: key,
maxResults: 20,
playlistId: playlistId
}
loadVids();
function loadVids() {
$.getJSON(URL, options, function (data) {
// var id = data.items[0].snippet.resourceId.videoId;
// mainVid(id);
resultsLoop(data);
});
}
function mainVid(id) {
$('#video').html(`
<iframe width="560" height="315" src="https://www.youtube.com/embed/${id}" frameborder="0" allow="autoplay; encrypted-media" allowfullscreen></iframe>
`);
}
function resultsLoop(data) {
totalResults = totalResults + data.pageInfo.resultsPerPage;
$.each(data.items, function (i, item) {
var thumb = item.snippet.thumbnails.medium.url;
var title = item.snippet.title;
var vid = item.snippet.resourceId.videoId;
$('#videos').append(`
<article class="item" data-key="${vid}">
<div class="details">
<img src="${thumb}" alt="" class="thumb">
<h4>${title}</h4>
</div>
</article>
`);
});
}
// CLICK EVENT
$('main').on('click', 'article', function () {
var id = $(this).attr('data-key');
mainVid(id);
});
}
</script>
</body>
</html>
And here is the css
#mixin font-base {
padding: 0;
margin: 0;
line-height: 1.3;
font-weight: 600;
}
h4 {
#include font-base;
}
p {
#include font-base;
color: grey;
font-size: 0.7rem;
}
.container {
width: 100%;
background-color: #fff;
margin: 0 auto;
display:table;
border-spacing: 10px;
}
section {
height:100%;
margin-top: 4%;
margin-bottom:2%;
text-align:center;
background-color:#eee;
}
iframe{
width:100%;
height:900px;
background-color:#65626b;
padding:8px 12px;
}
#videos{
overflow:hidden;
}
article {
margin:5px 5px;
width:24%;
float:left;
background-color:#eee;
border-radius:8px;
}
article div{
border: 1px solid black;
border-radius: 8px;
padding: 8px 12px;
}
article:hover{
background-color:#65626b;
color:white;
}
.thumb {
width: 100%;
border-radius:8px;
}
For more infos on code please ask. Thank you!
You can try using min-height or max-height CSS property on article divs.

Image slider: back an image

So I followed a tutorial on how to create image slider with jquery but he didn't show how to add next image and previous image, so I'm trying to do that my self. The next image part is working but I can't get previous image to work. https://jsfiddle.net/vmab7xk6/10/
//slider
var sliderWidth = 960;
var sliderSpeed = 1000;
var sliderPause = 5000;
var sliderCurrent = 1;
var sliderInterval;
var $sliderLocation = $(".slider");
var $sliderContainer = $sliderLocation.find(".slides");
var $sliderSlides = $sliderContainer.find(".slide");
// img slider
function startSlider() {
sliderInterval = setInterval(function() {
$sliderContainer.animate({'margin-left': '-='+sliderWidth}, sliderSpeed, function() {
sliderCurrent++;
if(sliderCurrent === $sliderSlides.length) {
sliderCurrent = 1;
$sliderContainer.css("margin-left", 0);
}
});
}, sliderPause);
}
function pauseSlider() {
clearInterval(sliderInterval);
}
function backSlider() {
$sliderContainer.animate({"margin-left": "+="+sliderWidth}, sliderSpeed, function() {
sliderCurrent--;
if(sliderCurrent === $sliderSlides.length) {
sliderCurrent = $sliderSlides.length - 1;
$sliderContainer.css("margin-left", "-1920");
}
});
}
function nextSlider() {
$sliderContainer.animate({"margin-left": "-="+sliderWidth}, sliderSpeed, function() {
sliderCurrent++;
if(sliderCurrent === $sliderSlides.length) {
sliderCurrent = 1;
$sliderContainer.css("margin-left", 0);
}
});
}
$("#sliderControllsLeft").on("click", function() {
backSlider();
console.log("left");
});
$("#sliderControllsPause").on("click", function() {
pauseSlider();
console.log("pause");
});
$("#sliderControllsStart").on("click", function() {
startSlider();
console.log("start");
});
$("#sliderControllsRight").on("click", function() {
nextSlider();
console.log("right");
});
startSlider();
<section class="slider">
<ul class="slides">
<li class="slide"><img src="img/slider_01.jpg"></li>
<li class="slide"><img src="img/slider_02.jpg"></li>
<li class="slide"><img src="img/slider_03.jpg"></li>
<li class="slide"><img src="img/slider_01.jpg"></li>
</ul>
<ul class="sliderControlls">
<li id="sliderControllsLeft"><</li>
<li id="sliderControllsPause">=</li>
<li id="sliderControllsStart">+</li>
<li id="sliderControllsRight">></li>
</ul>
</section>
section.slider {
width: 100%;
height: 500px;
overflow: hidden;
margin: 100px 0;
}
section.slider .slides {
display: block;
width: 6000px;
height: 400px;
margin: 0;
padding: 0;
}
section.slider .slide {
width: 960px;
height: 400px;
float: left;
list-style-type: none;
}
ul.sliderControlls {
list-style-type: none;
}
ul.sliderControlls li {
display: inline-block;
font-size: 60px;
color: #000;
text-decoration: none;
padding: 0 10px 0 10px;
}
You have a few syntax errors. See updated fiddle: jsfiddle
You needed to declare the jQuery shorthand $ before using it. I added a wrapper function that does that. On your JS, (at least on the fiddle), you did not include your slider variables - I added those.

Allow user to drop item in two different droppable areas inside loop

So I do have a loop of droppable areas where user is able to drop items. Size of the loop can be different. It depends on user's input. You can check fiddle here
Here is my droppable area:
$(".projLeader ol").droppable({
tolerance: 'pointer',
hoverClass: 'highlight',
drop: function(ev, ui)
{
var zz = ui.draggable.text()
var xyz = itm.includes(zz);
if (xyz === false)
{
var item = ui.draggable;
if (!ui.draggable.closest('.placeholder').length) item = item.clone().draggable();// if item was dragged from the source list - clone it
//this.innerHTML = ''; // clean the placeholder
item.addClass('dropClass').appendTo(this);
// append item to placeholder
//add to array
itm.push(zz);
var n = $(this).closest("div.proc").find(".dropClass").length;
$(this).closest("div.proc").find("h6").text("Items Dropped: " + n + ".");
}
else
{
alert('Name is Already Exist');
}
}
});
The problem is I got warning message for each field. For example if I drop item in box1 and then want to drop same item in box2 I got warning message. How can I fix it? Thanks for any help
I spent some time understanding your code and here's the solution. I added some code to detect if an existing box already exists.Hope it helps :)!
var itm = [];
$( "#savebutton" ).click(function() { LISTOBJ.saveList(); });
$("#myAccordion").accordion({heightStyle:"content", active: false, collapsible:true});
$("#myAccordion li").draggable({
appendTo: "body",
helper: "clone",
start: function(ev, ui){ ui.helper.width($(this).width()); }
});
$(".projLeader ol").droppable({
tolerance: 'pointer',
hoverClass: 'highlight',
drop: function(ev, ui)
{
var zz = ui.draggable.text()
var xyz = itm.includes(zz);
if (xyz === false)
{
var item = ui.draggable;
var map = {}, i , size;
var flag = false;
if (!ui.draggable.closest('.placeholder').length){
item = item.clone().draggable();// if item was dragged from the source list - clone it
//this.innerHTML = ''; // clean the placeholder
item.addClass('dropClass').appendTo(this);
// append item to placeholder
//add to array
var n = $(this).closest("div.proc").find(".dropClass").length;
$(this).closest("div.proc").find("h6").text("Items Dropped: " + n + ".");
var listOfElements = $(this).closest("div.proc").find("li").text();
var newarr = listOfElements.split('x');
newarr.shift();
var actualArrayLength = newarr.length;
for (i = 0, size = newarr.length; i < size; i++){
if (map[newarr[i]]){
xyz = true;
alert("Name is Already Exist");
$(this).closest("div.proc").find("h6").text("Items Dropped: " + (n - 1) + ".");
$(this).closest("div.proc").find("li:last-child").remove();
return false;
}
else{
map[newarr[i]] = true;
newarr[newarr.length - 1];
}
}
}
}
}
});
$(".projLeader").on('click', '.closer', function(){
var item = $(this).closest('.item');
itm.splice(item);
item.fadeTo(200, 0, function(){ item.remove(); })
});
var LISTOBJ = {
saveList: function() {
var listCSV = "";
$( ".projLeader li" ).each(function() {
if (listCSV === "") {
listCSV = $(this).text();
} else {
listCSV += ", " + $(this).text();
}
$("#output").text(listCSV);
$(".hiddenListInput").val(listCSV);
});
}
}
body {
font-family: verdana;
font-size: 12px;
}
ul {
list-style-type: none;
margin: 0;
padding: 0;
margin-bottom: 10px;
}
ol{list-style-type: none;}
.item { height:20px; width: 180px; margin:5px; padding:5px; border:1px solid gray; background-color: #cd8; position: relative; }
.item .closer { position: absolute; right: 5px; top: 2px; font: bold 14px arial; color: #666; padding: 1px 3px; line-height: 1; cursor: pointer; display: none;}
.item .closer:hover { color: #000; }
.placeholder { height: 30px; width: 195px; margin: 5px; background: #eee; border: 1px dashed #999; }
.placeholder .item { margin: 0; }
ol .item .closer { display: block; }
.highlight { border: 1px solid red; background: #fff; }
.highlight .item { opacity: 0.3; }
.ui-draggable-dragging { z-index: 99; opacity: 1 !important; }
.dropClass {
background-color: lightblue;
padding-left: 10px;
width: 180px;
border: 1px solid black;
border-radius: 8px;
margin-bottom: 5px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<h1 class="ui-widget-header">Products</h1>
<div id="myAccordion">
<h3>T-Shirts</h3>
<div>
<ul>
<li class="item"><span class="closer">x</span>Lolcat Shirt</li>
<li class="item"><span class="closer">x</span>Cheezeburger Shirt</li>
<li class="item"><span class="closer">x</span>Buckit Shirt</li>
</ul>
</div>
<h3>Bags</h3>
<div>
<ul>
<li class="item"><span class="closer">x</span>Zebra Striped</li>
<li class="item"><span class="closer">x</span>Black Leather</li>
<li class="item"><span class="closer">x</span>Alligator Leather</li>
</ul>
</div>
<h3>Gadgets</h3>
<div>
<ul>
<li class="item"><span class="closer">x</span>iPhone</li>
<li class="item"><span class="closer">x</span>iPod</li>
<li class="item"><span class="closer">x</span>iPad</li>
</ul>
</div>
</div>
<div class='proc'><pre>
<h6> </h6><br /></pre>
<div class="projLeader">
<label>Box1:</label>
<div class="ui-widget-content">
<ol id = "ID1">
<li class="placeholder" name="projLeader"></li>
<input type="hidden" name="projLeader" class="hiddenListInput1" />
</ol>
</div>
</div>
</div>
<div class='proc'><pre>
<h6> </h6><br /></pre>
<div class="projLeader">
<label>Box2:</label>
<div class="ui-widget-content">
<ol id = "ID2" >
<li class="placeholder" name="projLeader"></li>
<input type="hidden" name="projLeader" class="hiddenListInput2" />
</ol>
</div>
</div>
</div>
<br/>
<input type="submit" id="savebutton" class="button" value="Save" onclick="userSubmitted = true;" />
<div id="output"></div>

Upfront active menu link

I use Javascript that will decorate an active link after it's been clicked. Question is, how can I load the page with one of the menu items already active?
Example: http://moschalkx.nl/
Javascript code:
function hlite_menu(obj) {
var lnk = document.getElementById('menu').getElementsByTagName('A');
for (var i in lnk) {
lnk[i].className = (lnk[i] === obj) ? 'menu_active' : 'menu_idle';
}
}
function set_menu() {
var lnk = document.getElementById('menu').getElementsByTagName('A');
for (var i in lnk) {
lnk[i].className = 'menu_idle';
lnk[i].onclick = function () {
hlite_menu(this);
}
}
if (lnk[i]) { /* ??? how do you know whether this is the link to activeate up front? */
hlist_menu(lnk[i]);
}
}
window.onload = set_menu;
CSS:
a.menu_idle {color:#333333; text-decoration:none;}
a.menu_active {color:#333333; text-decoration:underline;}
a:visited {color:#333333; text-decoration:none;}
a:hover {color:#333333; text-decoration:underline;}
I need to put in the logic somewhere inside
if (lnk[i]) { /* ??? how do you know whether this is the link to activeate up front? */
hlist_menu(lnk[i]);
}
to let the script know which link will be active upfront. As i'm not familiar with coding, i have no clue how to do this!
Set the initially active link in your markup:
<a target="iframe1" class="menu_active" href="gallery/photo_menu.html">PHOTOGRAPHY</a>
Then in your set_menu function, set the iframe's src attribute to the href of that link:
for (i in lnk) {
if (lnk.hasOwnProperty(i)) {
//lnk[i].className = 'menu_idle'; // initial menu states are set in markup. This line is no longer necessary.
lnk[i].onclick = hlite_menu;
if (lnk[i].className === 'menu_active') {
iframe.src = lnk[i].href;
}
}
}
I would also strongly recommend re-writing your JavaScript to the following:
var hlite_menu = function hlite_menu() {
'use strict';
var lnk = document.getElementById('menu').getElementsByTagName('a'),
i = null;
//set all links to idle
for (i in lnk) {
if (lnk.hasOwnProperty(i)) {
lnk[i].className = 'menu_idle';
}
}
//set this link to active
this.className = 'menu_active';
},
set_menu = function set_menu() {
'use strict';
var lnk = document.getElementById('menu').getElementsByTagName('a'),
iframe = document.getElementById('iframe1'),
c = document.getElementById('copyright'),
i = null;
// set copyright
c.innerText = (new Date()).getFullYear();
// set onclicks and initial iframe src.
for (i in lnk) {
if (lnk.hasOwnProperty(i)) {
//lnk[i].className = 'menu_idle'; // initial menu states are set in markup. This line is no longer necessary.
lnk[i].onclick = hlite_menu;
if (lnk[i].className === 'menu_active') {
iframe.src = lnk[i].href;
}
}
}
};
window.onload = set_menu;
This avoids several long-term problems like readability/maintenance, variable hoisting, and the dreaded document.write (which you are using to set your copyright date). You'll also want to change the copyright section to this:
<div id="footer">
ALL IMAGES © <span id="copyright"></span>
</div>
You can also write your navigation like this (avoiding tables for layout):
<div id="header">
<div class="logo">
<span style="">MO SCHALKX</span>
</div>
<div id="menu">
<a target="iframe1" class="menu_active" href="gallery/photo_menu.html">PHOTOGRAPHY</a>
<a target="iframe1" class="menu_idle" href="gallery/film_menu.html">FILM</a>
<a target="iframe1" class="menu_idle" href="about.html">ABOUT</a>
<a target="iframe1" class="menu_idle" href="http://reflecture.tumblr.com">BLOG</a>
</div>
</div>
and add this to your CSS:
#header {
float: left;
display: inline-block;
margin: 1em;
text-align: center;
}
.logo, #menu {
background-color: #FFF;
}
.logo {
font-size: 40px;
font-weight: 500;
font-style: inherit;
}
#menu {
margin-top: 5px;
}
#menu > a {
padding-left: 0.25em;
}
#menu > a {
border-left: 1px solid #000;
}
#menu > a:first-child {
border-left: none;
}
which should make it look the same. You can also combine your CSS rules for menu_active and a:hover (likewise with menu_idle and a:visited) like so:
a.menu_idle, a:visited {
color: #333333;
text-decoration: none;
}
a.menu_active, a:hover {
color: #333333;
text-decoration: underline;
}
Finally, you've wrapped your iframe in a <form id="form1" runat="server"> element. You can remove this entirely. It won't affect your layout and you don't actually have a form with any input elements so it's unnecessary. Also, the runat="server" attribute doesn't do anything unless you're running this on ASP.Net (and you obviously are not) so you may want to keep that in mind.
Altogether, you should be able to change the entire document source to the following with no real visual changes (and I think you'll find that it's a lot cleaner to look at in the source):
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>Mo Schalkx Photography</title>
<script type="text/javascript">
var hlite_menu = function hlite_menu() {
'use strict';
var lnk = document.getElementById('menu').getElementsByTagName('a'),
i = null;
//set all links to idle
for (i in lnk) {
if (lnk.hasOwnProperty(i)) {
lnk[i].className = 'menu_idle';
}
}
//set this link to active
this.className = 'menu_active';
},
set_menu = function set_menu() {
'use strict';
var lnk = document.getElementById('menu').getElementsByTagName('a'),
iframe = document.getElementById('iframe1'),
c = document.getElementById('copyright'),
i = null;
// set copyright
c.innerText = (new Date()).getFullYear();
// set onclicks and initial iframe src.
for (i in lnk) {
if (lnk.hasOwnProperty(i)) {
//lnk[i].className = 'menu_idle'; // initial menu states are set in markup. This line is no longer necessary.
lnk[i].onclick = hlite_menu;
if (lnk[i].className === 'menu_active') {
iframe.src = lnk[i].href;
}
}
}
};
window.onload = set_menu;
</script>
<style type="text/css">
body {
margin: 0;
overflow: hidden;
}
#header {
float: left;
display: inline-block;
margin: 1em;
text-align: center;
}
#iframe1 {
position: absolute;
left: 0px;
top: 0px;
width: 100%;
height: 100%;
z-index: -1;
}
#footer {
font-size: 9px;
font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
text-align: center;
position: absolute;
bottom: 0px;
left: 0px;
width: 100%;
height: 20px;
visibility: visible;
display: block;
color: #000;
opacity: 0.4;
filter: alpha(opacity=40);
text-shadow: 0px 1px 0px rgba(255,255,255,.5); /* 50% white from bottom */;
}
.logo, #menu {
background-color: #FFF;
}
.logo {
font-size: 40px;
font-weight: 500;
font-style: inherit;
}
#menu {
margin-top: 5px;
}
#menu > a {
padding-left: 0.25em;
}
#menu > a {
border-left: 1px solid #000;
}
#menu > a:first-child {
border-left: none;
}
a.menu_idle, a:visited {
color: #333333;
text-decoration: none;
}
a.menu_active, a:hover {
color: #333333;
text-decoration: underline;
}
</style>
</head>
<body>
<div id="header">
<div class="logo">
<span style="">MO SCHALKX</span>
</div>
<div id="menu">
<a target="iframe1" class="menu_active" href="gallery/photo_menu.html">PHOTOGRAPHY</a>
<a target="iframe1" class="menu_idle" href="gallery/film_menu.html">FILM</a>
<a target="iframe1" class="menu_idle" href="about.html">ABOUT</a>
<a target="iframe1" class="menu_idle" href="http://reflecture.tumblr.com">BLOG</a>
</div>
</div>
<div id="footer">
ALL IMAGES © <span id="copyright"></span>
</div>
<iframe id="iframe1" frameborder="0"></iframe>
</body>
</html>
UDPATE
To apply this on http://moschalkx.nl/gallery/film_menu.html, simply include the same JavaScript and comment out the lines that involve setting the copyright in set_menu and update the id of the iframe:
var hlite_menu = function hlite_menu() {
'use strict';
var lnk = document.getElementById('menu').getElementsByTagName('a'),
i = null;
//set all links to idle
for (i in lnk) {
if (lnk.hasOwnProperty(i)) {
lnk[i].className = 'menu_idle';
}
}
//set this link to active
this.className = 'menu_active';
},
set_menu = function set_menu() {
'use strict';
var lnk = document.getElementById('menu').getElementsByTagName('a'),
iframe = document.getElementById('gallery'),
//c = document.getElementById('copyright'),
i = null;
// set copyright
//c.innerText = (new Date()).getFullYear();
// set onclicks and initial iframe src.
for (i in lnk) {
if (lnk.hasOwnProperty(i)) {
//lnk[i].className = 'menu_idle'; // initial menu states are set in markup. This line is no longer necessary.
lnk[i].onclick = hlite_menu;
if (lnk[i].className === 'menu_active') {
iframe.src = lnk[i].href;
}
}
}
};
window.onload = set_menu;
Also, since you're including jQuery on this page, you could write that in jQuery as:
$(document).ready(function () {
$('#menu a').click(function (e) {
var self = $(this),
href = self.attr('href');
$('#menu a').not(self).removeClass('menu_active').addClass('menu_idle');
self.removeClass('menu_idle').addClass('menu_active');
$('#gallery').attr('src', href);
});
});

How to add a custom right-click menu to a webpage?

I want to add a custom right-click menu to my web application. Can this be done without using any pre-built libraries? If so, how to display a simple custom right-click menu which does not use a 3rd party JavaScript library?
I'm aiming for something like what Google Docs does. It lets users right-click and show the users their own menu.
NOTE:
I want to learn how to make my own versus using something somebody made already since most of the time, those 3rd party libraries are bloated with features whereas I only want features that I need so I want it to be completely hand-made by me.
Answering your question - use contextmenu event, like below:
if (document.addEventListener) {
document.addEventListener('contextmenu', function(e) {
alert("You've tried to open context menu"); //here you draw your own menu
e.preventDefault();
}, false);
} else {
document.attachEvent('oncontextmenu', function() {
alert("You've tried to open context menu");
window.event.returnValue = false;
});
}
<body>
Lorem ipsum...
</body>
But you should ask yourself, do you really want to overwrite default right-click behavior - it depends on application that you're developing.
JSFIDDLE
Was very useful for me. For the sake of people like me, expecting the drawing of menu, I put here the code I used to make the right-click menu:
$(document).ready(function() {
if ($("#test").addEventListener) {
$("#test").addEventListener('contextmenu', function(e) {
alert("You've tried to open context menu"); //here you draw your own menu
e.preventDefault();
}, false);
} else {
//document.getElementById("test").attachEvent('oncontextmenu', function() {
//$(".test").bind('contextmenu', function() {
$('body').on('contextmenu', 'a.test', function() {
//alert("contextmenu"+event);
document.getElementById("rmenu").className = "show";
document.getElementById("rmenu").style.top = mouseY(event) + 'px';
document.getElementById("rmenu").style.left = mouseX(event) + 'px';
window.event.returnValue = false;
});
}
});
// this is from another SO post...
$(document).bind("click", function(event) {
document.getElementById("rmenu").className = "hide";
});
function mouseX(evt) {
if (evt.pageX) {
return evt.pageX;
} else if (evt.clientX) {
return evt.clientX + (document.documentElement.scrollLeft ?
document.documentElement.scrollLeft :
document.body.scrollLeft);
} else {
return null;
}
}
function mouseY(evt) {
if (evt.pageY) {
return evt.pageY;
} else if (evt.clientY) {
return evt.clientY + (document.documentElement.scrollTop ?
document.documentElement.scrollTop :
document.body.scrollTop);
} else {
return null;
}
}
.show {
z-index: 1000;
position: absolute;
background-color: #C0C0C0;
border: 1px solid blue;
padding: 2px;
display: block;
margin: 0;
list-style-type: none;
list-style: none;
}
.hide {
display: none;
}
.show li {
list-style: none;
}
.show a {
border: 0 !important;
text-decoration: none;
}
.show a:hover {
text-decoration: underline !important;
}
<!-- jQuery should be at least version 1.7 -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<script src="contextmenu.js"></script>
<link rel="stylesheet" href="contextmenu.css" />
<div id="test1">
Google
Link 2
Link 3
Link 4
</div>
<!-- initially hidden right-click menu -->
<div class="hide" id="rmenu">
<ul>
<li>
Google
</li>
<li>
Localhost
</li>
<li>
C
</li>
</ul>
</div>
A combination of some nice CSS and some non-standard html tags with no external libraries can give a nice result (JSFiddle)
HTML
<menu id="ctxMenu">
<menu title="File">
<menu title="Save"></menu>
<menu title="Save As"></menu>
<menu title="Open"></menu>
</menu>
<menu title="Edit">
<menu title="Cut"></menu>
<menu title="Copy"></menu>
<menu title="Paste"></menu>
</menu>
</menu>
Note: the menu tag does not exist, I'm making it up (you can use anything)
CSS
#ctxMenu{
display:none;
z-index:100;
}
menu {
position:absolute;
display:block;
left:0px;
top:0px;
height:20px;
width:20px;
padding:0;
margin:0;
border:1px solid;
background-color:white;
font-weight:normal;
white-space:nowrap;
}
menu:hover{
background-color:#eef;
font-weight:bold;
}
menu:hover > menu{
display:block;
}
menu > menu{
display:none;
position:relative;
top:-20px;
left:100%;
width:55px;
}
menu[title]:before{
content:attr(title);
}
menu:not([title]):before{
content:"\2630";
}
The JavaScript is just for this example, I personally remove it for persistent menus on windows
var notepad = document.getElementById("notepad");
notepad.addEventListener("contextmenu",function(event){
event.preventDefault();
var ctxMenu = document.getElementById("ctxMenu");
ctxMenu.style.display = "block";
ctxMenu.style.left = (event.pageX - 10)+"px";
ctxMenu.style.top = (event.pageY - 10)+"px";
},false);
notepad.addEventListener("click",function(event){
var ctxMenu = document.getElementById("ctxMenu");
ctxMenu.style.display = "";
ctxMenu.style.left = "";
ctxMenu.style.top = "";
},false);
Also note, you can potentially modify menu > menu{left:100%;} to menu > menu{right:100%;} for a menu that expands from right to left. You would need to add a margin or something somewhere though
According to the answers here and on other 'flows, I've made a version that looks like the one of Google Chrome, with css3 transition.
JS Fiddle
Lets start easy, since we have the js above on this page, we can worry about the css and layout. The layout that we will be using is an <a> element with a <img> element or a font awesome icon (<i class="fa fa-flag"></i>) and a <span> to show the keyboard shortcuts. So this is the structure:
<a href="#" onclick="doSomething()">
<img src="path/to/image.gif" />
This is a menu option
<span>Ctrl + K</span>
</a>
We will put these in a div and show that div on the right-click. Let's style them like in Google Chrome, shall we?
#menu a {
display: block;
color: #555;
text-decoration: no[...]
Now we will add the code from the accepted answer, and get the X and Y value of the cursor. To do this, we will use e.clientX and e.clientY. We are using client, so the menu div has to be fixed.
var i = document.getElementById("menu").style;
if (document.addEventListener) {
document.addEventListener('contextmenu', function(e) {
var posX = e.clientX;
var posY = e.client[...]
And that is it! Just add the css transisions to fade in and out, and done!
var i = document.getElementById("menu").style;
if (document.addEventListener) {
document.addEventListener('contextmenu', function(e) {
var posX = e.clientX;
var posY = e.clientY;
menu(posX, posY);
e.preventDefault();
}, false);
document.addEventListener('click', function(e) {
i.opacity = "0";
setTimeout(function() {
i.visibility = "hidden";
}, 501);
}, false);
} else {
document.attachEvent('oncontextmenu', function(e) {
var posX = e.clientX;
var posY = e.clientY;
menu(posX, posY);
e.preventDefault();
});
document.attachEvent('onclick', function(e) {
i.opacity = "0";
setTimeout(function() {
i.visibility = "hidden";
}, 501);
});
}
function menu(x, y) {
i.top = y + "px";
i.left = x + "px";
i.visibility = "visible";
i.opacity = "1";
}
body {
background: white;
font-family: sans-serif;
color: #5e5e5e;
}
#menu {
visibility: hidden;
opacity: 0;
position: fixed;
background: #fff;
color: #555;
font-family: sans-serif;
font-size: 11px;
-webkit-transition: opacity .5s ease-in-out;
-moz-transition: opacity .5s ease-in-out;
-ms-transition: opacity .5s ease-in-out;
-o-transition: opacity .5s ease-in-out;
transition: opacity .5s ease-in-out;
-webkit-box-shadow: 2px 2px 2px 0px rgba(143, 144, 145, 1);
-moz-box-shadow: 2px 2px 2px 0px rgba(143, 144, 145, 1);
box-shadow: 2px 2px 2px 0px rgba(143, 144, 145, 1);
padding: 0px;
border: 1px solid #C6C6C6;
}
#menu a {
display: block;
color: #555;
text-decoration: none;
padding: 6px 8px 6px 30px;
width: 250px;
position: relative;
}
#menu a img,
#menu a i.fa {
height: 20px;
font-size: 17px;
width: 20px;
position: absolute;
left: 5px;
top: 2px;
}
#menu a span {
color: #BCB1B3;
float: right;
}
#menu a:hover {
color: #fff;
background: #3879D9;
}
#menu hr {
border: 1px solid #EBEBEB;
border-bottom: 0;
}
<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css" rel="stylesheet"/>
<h2>CSS3 and JAVASCRIPT custom menu.</h2>
<em>Stephan Stanisic | Lisence free</em>
<p>Right-click anywhere on this page to open the custom menu. Styled like the Google Chrome contextmenu. And yes, you can use <i class="fa fa-flag"></i>font-awesome</p>
<p style="font-size: small">
<b>Lisence</b>
<br /> "THE PIZZA-WARE LICENSE" (Revision 42):
<br /> You can do whatever you want with this stuff. If we meet some day, and you think this stuff is worth it, you can buy me a Pizza in return.
<br />
<a style="font-size:xx-small" href="https://github.com/KLVN/UrbanDictionary_API#license">https://github.com/KLVN/UrbanDictionary_API#license</a>
</p>
<br />
<br />
<small>(The white body background is just because I hate the light blue editor background on the result on jsfiddle)</small>
<div id="menu">
<a href="#">
<img src="http://puu.sh/nr60s/42df867bf3.png" /> AdBlock Plus <span>Ctrl + ?!</span>
</a>
<a href="#">
<img src="http://puu.sh/nr5Z6/4360098fc1.png" /> SNTX <span>Ctrl + ?!</span>
</a>
<hr />
<a href="#">
<i class="fa fa-fort-awesome"></i> Fort Awesome <span>Ctrl + ?!</span>
</a>
<a href="#">
<i class="fa fa-flag"></i> Font Awesome <span>Ctrl + ?!</span>
</a>
</div>
Simplest jump start function, create a context menu at the cursor position, that destroys itself on mouse leave.
oncontextmenu = (e) => {
e.preventDefault()
let menu = document.createElement("div")
menu.id = "ctxmenu"
menu.style = `top:${e.pageY-10}px;left:${e.pageX-40}px`
menu.onmouseleave = () => ctxmenu.outerHTML = ''
menu.innerHTML = "<p>Option1</p><p>Option2</p><p>Option3</p><p>Option4</p><p onclick='alert(`Thank you!`)'>Upvote</p>"
document.body.appendChild(menu)
}
#ctxmenu {
position: fixed;
background: ghostwhite;
color: black;
cursor: pointer;
border: 1px black solid
}
#ctxmenu > p {
padding: 0 1rem;
margin: 0
}
#ctxmenu > p:hover {
background: black;
color: ghostwhite
}
You could try simply blocking the context menu by adding the following to your body tag:
<body oncontextmenu="return false;">
This will block all access to the context menu (not just from the right mouse button but from the keyboard as well).
P.S. you can add this to any tag you want to disable the context menu on
for example:
<div class="mydiv" oncontextmenu="return false;">
Will disable the context menu in that particular div only
Pure JS and css solution for a truly dynamic right click context menu, albeit based on predefined naming conventions for the elements id, links etc.
jsfiddle
and the code you could copy paste into a single static html page :
var rgtClickContextMenu = document.getElementById('div-context-menu');
/** close the right click context menu on click anywhere else in the page*/
document.onclick = function(e) {
rgtClickContextMenu.style.display = 'none';
}
/**
present the right click context menu ONLY for the elements having the right class
by replacing the 0 or any digit after the "to-" string with the element id , which
triggered the event
*/
document.oncontextmenu = function(e) {
//alert(e.target.id)
var elmnt = e.target
if (elmnt.className.startsWith("cls-context-menu")) {
e.preventDefault();
var eid = elmnt.id.replace(/link-/, "")
rgtClickContextMenu.style.left = e.pageX + 'px'
rgtClickContextMenu.style.top = e.pageY + 'px'
rgtClickContextMenu.style.display = 'block'
var toRepl = "to=" + eid.toString()
rgtClickContextMenu.innerHTML = rgtClickContextMenu.innerHTML.replace(/to=\d+/g, toRepl)
//alert(rgtClickContextMenu.innerHTML.toString())
}
}
.cls-context-menu-link {
display: block;
padding: 20px;
background: #ECECEC;
}
.cls-context-menu {
position: absolute;
display: none;
}
.cls-context-menu ul,
#context-menu li {
list-style: none;
margin: 0;
padding: 0;
background: white;
}
.cls-context-menu {
border: solid 1px #CCC;
}
.cls-context-menu li {
border-bottom: solid 1px #CCC;
}
.cls-context-menu li:last-child {
border: none;
}
.cls-context-menu li a {
display: block;
padding: 5px 10px;
text-decoration: none;
color: blue;
}
.cls-context-menu li a:hover {
background: blue;
color: #FFF;
}
<!-- those are the links which should present the dynamic context menu -->
<a id="link-1" href="#" class="cls-context-menu-link">right click link-01</a>
<a id="link-2" href="#" class="cls-context-menu-link">right click link-02</a>
<!-- this is the context menu -->
<!-- note the string to=0 where the 0 is the digit to be replaced -->
<div id="div-context-menu" class="cls-context-menu">
<ul>
<li>link-to=0 -item-1 </li>
<li>link-to=0 -item-2 </li>
<li>link-to=0 -item-3 </li>
</ul>
</div>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<head>
<title>Context menu - LabLogic.net</title>
</head>
<body>
<script language="javascript" type="text/javascript">
document.oncontextmenu=RightMouseDown;
document.onmousedown = mouseDown;
function mouseDown(e) {
if (e.which===3) {//righClick
alert("Right-click menu goes here");
}
}
function RightMouseDown() { return false; }
</script>
</body>
</html>
Tested and works in Opera 11.6, firefox 9.01, Internet Explorer 9 and chrome 17
Try this:
var cls = true;
var ops;
window.onload = function() {
document.querySelector(".container").addEventListener("mouseenter", function() {
cls = false;
});
document.querySelector(".container").addEventListener("mouseleave", function() {
cls = true;
});
ops = document.querySelectorAll(".container td");
for (let i = 0; i < ops.length; i++) {
ops[i].addEventListener("click", function() {
document.querySelector(".position").style.display = "none";
});
}
ops[0].addEventListener("click", function() {
setTimeout(function() {
/* YOUR FUNCTION */
alert("Alert 1!");
}, 50);
});
ops[1].addEventListener("click", function() {
setTimeout(function() {
/* YOUR FUNCTION */
alert("Alert 2!");
}, 50);
});
ops[2].addEventListener("click", function() {
setTimeout(function() {
/* YOUR FUNCTION */
alert("Alert 3!");
}, 50);
});
ops[3].addEventListener("click", function() {
setTimeout(function() {
/* YOUR FUNCTION */
alert("Alert 4!");
}, 50);
});
ops[4].addEventListener("click", function() {
setTimeout(function() {
/* YOUR FUNCTION */
alert("Alert 5!");
}, 50);
});
}
document.addEventListener("contextmenu", function() {
var e = window.event;
e.preventDefault();
document.querySelector(".container").style.padding = "0px";
var x = e.clientX;
var y = e.clientY;
var docX = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth || document.body.offsetWidth;
var docY = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight || document.body.offsetHeight;
var border = parseInt(getComputedStyle(document.querySelector(".container"), null).getPropertyValue('border-width'));
var objX = parseInt(getComputedStyle(document.querySelector(".container"), null).getPropertyValue('width')) + 2;
var objY = parseInt(getComputedStyle(document.querySelector(".container"), null).getPropertyValue('height')) + 2;
if (x + objX > docX) {
let diff = (x + objX) - docX;
x -= diff + border;
}
if (y + objY > docY) {
let diff = (y + objY) - docY;
y -= diff + border;
}
document.querySelector(".position").style.display = "block";
document.querySelector(".position").style.top = y + "px";
document.querySelector(".position").style.left = x + "px";
});
window.addEventListener("resize", function() {
document.querySelector(".position").style.display = "none";
});
document.addEventListener("click", function() {
if (cls) {
document.querySelector(".position").style.display = "none";
}
});
document.addEventListener("wheel", function() {
if (cls) {
document.querySelector(".position").style.display = "none";
static = false;
}
});
.position {
position: absolute;
width: 1px;
height: 1px;
z-index: 2;
display: none;
}
.container {
width: 220px;
height: auto;
border: 1px solid black;
background: rgb(245, 243, 243);
}
.container p {
height: 30px;
font-size: 18px;
font-family: arial;
width: 99%;
cursor: pointer;
display: flex;
justify-content: center;
align-items: center;
background: rgb(245, 243, 243);
color: black;
transition: 0.2s;
}
.container p:hover {
background: lightblue;
}
td {
font-family: arial;
font-size: 20px;
}
td:hover {
background: lightblue;
transition: 0.2s;
cursor: pointer;
}
<div class="position">
<div class="container" align="center">
<table style="text-align: left; width: 99%; margin-left: auto; margin-right: auto;" border="0" cellpadding="2" cellspacing="2">
<tbody>
<tr>
<td style="vertical-align: middle; text-align: center;">Option 1<br>
</td>
</tr>
<tr>
<td style="vertical-align: middle; text-align: center;">Option 2<br>
</td>
</tr>
<tr>
<td style="vertical-align: middle; text-align: center;">Option 3<br>
</td>
</tr>
<tr>
<td style="vertical-align: middle; text-align: center;">Option 4<br>
</td>
</tr>
<tr>
<td style="vertical-align: middle; text-align: center;">Option 5<br>
</td>
</tr>
</tbody>
</table>
</div>
</div>
Here is a very good tutorial on how to build a custom context menu with a full working code example (without JQuery and other libraries).
You can also find their demo code on GitHub.
They give a detailed step-by-step explanation that you can follow along to build your own right-click context menu (including html, css and javascript code) and summarize it at the end by giving the complete example code.
You can follow along easily and adapt it to your own needs. And there is no need for JQuery or other libraries.
This is how their example menu code looks like:
<nav id="context-menu" class="context-menu">
<ul class="context-menu__items">
<li class="context-menu__item">
<i class="fa fa-eye"></i> View Task
</li>
<li class="context-menu__item">
<i class="fa fa-edit"></i> Edit Task
</li>
<li class="context-menu__item">
<i class="fa fa-times"></i> Delete Task
</li>
</ul>
</nav>
A working example (task list) can be found on codepen.
I know this has already been answered, but I spent some time wrestling with the second answer to get the native context menu to disappear and have it show up where the user clicked.
HTML
<body>
<div id="test1">
Google
Link 2
Link 3
Link 4
</div>
<!-- initially hidden right-click menu -->
<div class="hide" id="rmenu">
<ul>
<li class="White">White</li>
<li>Green</li>
<li>Yellow</li>
<li>Orange</li>
<li>Red</li>
<li>Blue</li>
</ul>
</div>
</body>
CSS
.hide {
display: none;
}
#rmenu {
border: 1px solid black;
background-color: white;
}
#rmenu ul {
padding: 0;
list-style: none;
}
#rmenu li
{
list-style: none;
padding-left: 5px;
padding-right: 5px;
}
JavaScript
if (document.getElementById('test1').addEventListener) {
document.getElementById('test1').addEventListener('contextmenu', function(e) {
$("#rmenu").toggleClass("hide");
$("#rmenu").css(
{
position: "absolute",
top: e.pageY,
left: e.pageX
}
);
e.preventDefault();
}, false);
}
// this is from another SO post...
$(document).bind("click", function(event) {
document.getElementById("rmenu").className = "hide";
});
CodePen Example
Try This
$(function() {
var doubleClicked = false;
$(document).on("contextmenu", function (e) {
if(doubleClicked == false) {
e.preventDefault(); // To prevent the default context menu.
var windowHeight = $(window).height()/2;
var windowWidth = $(window).width()/2;
if(e.clientY > windowHeight && e.clientX <= windowWidth) {
$("#contextMenuContainer").css("left", e.clientX);
$("#contextMenuContainer").css("bottom", $(window).height()-e.clientY);
$("#contextMenuContainer").css("right", "auto");
$("#contextMenuContainer").css("top", "auto");
} else if(e.clientY > windowHeight && e.clientX > windowWidth) {
$("#contextMenuContainer").css("right", $(window).width()-e.clientX);
$("#contextMenuContainer").css("bottom", $(window).height()-e.clientY);
$("#contextMenuContainer").css("left", "auto");
$("#contextMenuContainer").css("top", "auto");
} else if(e.clientY <= windowHeight && e.clientX <= windowWidth) {
$("#contextMenuContainer").css("left", e.clientX);
$("#contextMenuContainer").css("top", e.clientY);
$("#contextMenuContainer").css("right", "auto");
$("#contextMenuContainer").css("bottom", "auto");
} else {
$("#contextMenuContainer").css("right", $(window).width()-e.clientX);
$("#contextMenuContainer").css("top", e.clientY);
$("#contextMenuContainer").css("left", "auto");
$("#contextMenuContainer").css("bottom", "auto");
}
$("#contextMenuContainer").fadeIn(500, FocusContextOut());
doubleClicked = true;
} else {
e.preventDefault();
doubleClicked = false;
$("#contextMenuContainer").fadeOut(500);
}
});
function FocusContextOut() {
$(document).on("click", function () {
doubleClicked = false;
$("#contextMenuContainer").fadeOut(500);
$(document).off("click");
});
}
});
http://jsfiddle.net/AkshayBandivadekar/zakn7Lwb/14/
You can do it with this code.
visit here for full tutorial with automatic edge detection http://www.voidtricks.com/custom-right-click-context-menu/
$(document).ready(function () {
$("html").on("contextmenu",function(e){
//prevent default context menu for right click
e.preventDefault();
var menu = $(".menu");
//hide menu if already shown
menu.hide();
//get x and y values of the click event
var pageX = e.pageX;
var pageY = e.pageY;
//position menu div near mouse cliked area
menu.css({top: pageY , left: pageX});
var mwidth = menu.width();
var mheight = menu.height();
var screenWidth = $(window).width();
var screenHeight = $(window).height();
//if window is scrolled
var scrTop = $(window).scrollTop();
//if the menu is close to right edge of the window
if(pageX+mwidth > screenWidth){
menu.css({left:pageX-mwidth});
}
//if the menu is close to bottom edge of the window
if(pageY+mheight > screenHeight+scrTop){
menu.css({top:pageY-mheight});
}
//finally show the menu
menu.show();
});
$("html").on("click", function(){
$(".menu").hide();
});
});
`
<script language="javascript" type="text/javascript">
document.oncontextmenu = RightMouseDown;
document.onmousedown = mouseDown;
function mouseDown(e) {
if (e.which==3) {//righClick
alert("Right-click menu goes here");
}
}
function RightMouseDown() {
return false;
}
</script>
</body>
</html>
A simple way you could do it is use onContextMenu to return a JavaScript function:
<input type="button" value="Example" onContextMenu="return RightClickFunction();">
<script>
function RightClickFunction() {
// Enter your code here;
return false;
}
</script>
And by entering return false; you will cancel out the context menu.
if you still want to display the context menu you can just remove the return false; line.
Tested and works in Opera 12.17, firefox 30, Internet Explorer 9 and chrome 26.0.1410.64
document.oncontextmenu =function( evt ){
alert("OK?");
return false;
}
For those looking for a very simple self-contained implementation of a custom context menu using bootstrap 5 and jQuery 3, here it is...
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.2.0/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-gH2yIJqKdNHPEq0n4Mqa/HGKIhSkIHeL5AyhkYV8i59U5AR6csBvApHHNl/vI1Bx" crossorigin="anonymous">
<title>Custom Context Menu</title>
</head>
<style>
#context-menu {
position: absolute;
display: none;
}
</style>
<body>
<div class="container-fluid p-5">
<div class="row p-5">
<div class="col-4">
<span id="some-element" class="border border-2 border-primary p-5">Some element</span>
</div>
</div>
<div id="context-menu" class="dropdown clearfix">
<ul class="dropdown-menu" style="display:block;position:static;margin-bottom:5px;">
<li><a class="dropdown-item" href="#" data-value="copy">Copy</a></li>
<li><hr class="dropdown-divider"></li>
<li><a class="dropdown-item" href="#" data-value="select-all">Select All</a></li>
</ul>
</div>
<script src="https://code.jquery.com/jquery-3.6.1.min.js" integrity="sha256-o88AwQnZB+VDvE9tvIXrMQaPlFFSUTR+nldQm1LuPXQ=" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap#5.2.0/dist/js/bootstrap.bundle.min.js" integrity="sha384-A3rJD856KowSb7dwlZdYEkO39Gagi7vIsF0jrRAoQmDKKtQBHUuLZ9AsSv4jD4Xa" crossorigin="anonymous"></script>
<script>
$('body').on('contextmenu', '#some-element', function(e) {
$('#context-menu').css({
display: "block",
left: e.pageX,
top: e.pageY
});
return false;
});
$('html').click(function() {
$('#context-menu').hide();
});
$("#context-menu li a").click(function(e){
console.log('in context-menu item, value = ' + $(this).data('value'));
});
</script>
</body>
</html>
Adapted from https://codepen.io/anirugu/pen/xjjxvG
<script>
function fun(){
document.getElementById('menu').style.display="block";
}
</script>
<div id="menu" style="display: none"> menu items</div>
<body oncontextmenu="fun();return false;">
What I'm doing up here
Create your own custom div menu and set the position: absolute and display:none in case.
Add to the page or element to be clicked the oncontextmenu event.
Cancel the default browser action with return false.
User js to invoke your own actions.
You should remember if you want to use the Firefox only solution, if you want to add it to the whole document you should add contextmenu="mymenu" to the <html> tag not to the body tag.
You should pay attention to this.
<html>
<head>
<style>
.rightclick {
/* YOUR CONTEXTMENU'S CSS */
visibility: hidden;
background-color: white;
border: 1px solid grey;
width: 200px;
height: 300px;
}
</style>
</head>
<body>
<div class="rightclick" id="ya">
<p onclick="alert('choc-a-late')">I like chocolate</p><br><p onclick="awe-so-me">I AM AWESOME</p>
</div>
<p>Right click to get sweet results!</p>
</body>
<script>
document.onclick = noClick;
document.oncontextmenu = rightClick;
function rightClick(e) {
e = e || window.event;
e.preventDefault();
document.getElementById("ya").style.visibility = "visible";
console.log("Context Menu v1.3.0 by IamGuest opened.");
}
function noClick() {
document.getElementById("ya").style.visibility = "hidden";
console.log("Context Menu v1.3.0 by IamGuest closed.");
}
</script>
<!-- Coded by IamGuest. Thank you for using this code! -->
</html>
You can tweak and modify this code to make a better looking, more efficient contextmenu. As for modifying an existing contextmenu, I'm not sure how to do that... Check out this fiddle for an organized point of view. Also, try clicking the items in my contextmenu. They should alert you a few awesome messages. If they don't work, try something more... complex.
I use something similar to the following jsfiddle
function onright(el, cb) {
//disable right click
document.body.oncontextmenu = 'return false';
el.addEventListener('contextmenu', function (e) { e.preventDefault(); return false });
el.addEventListener('mousedown', function (e) {
e = e || window.event;
if (~~(e.button) === 2) {
if (e.preventDefault) {
e.preventDefault();
} else {
e.returnValue = false;
}
return false;
}
});
// then bind Your cb
el.addEventListener('mousedown', function (e) {
e = e || window.event;
~~(e.button) === 2 && cb.call(el, e);
});
}
if You target older IE browsers you should anyway complete it with the ' attachEvent; case

Categories

Resources