Menu contestuale (tasto destro del mouse) personalizzato con javascript

Nella realizzazione di una pagina web, soprattutto se si tratta di un’applicazione, può essere molto utile richiamare delle funzioni specifiche usando il menu contestuale.

Normalmente nella pagina in qualunque punto si clicchi col tasto destro del mouse verrà attivato il menu contestuale di default del browser. Ma se noi vogliamo che, cliccando col tasto destro del mouse, si attivi un menu contestuale con funzioni personalizzate e specifiche della nostra applicazione, ecco che ci viene in aiuto javascript.

Di per sé la personalizzazione del menu contestuale non è un’operazione particolarmente complicata. Se cercate su internet potrete certamente trovare soluzioni persino sin troppo sofisticate, ma che risolvono sempre e solo il problema generale: un menu contestuale personalizzato per l’intera pagina oppure specifico per una zona della pagina. Bene, direte questo basta, perché se ho bisogno di voci diverse in aree diverse, basterà duplicare il codice relativo alle diverse zone. Ma se non sapete quanti siano gli elementi sui quali il tasto destro del mouse deve presentare un menu personalizzato che agisca specificatamente su quell’elemento e non su altri? A titolo di esempio, se abbiamo una galleria di immagini che varia nel numero a seconda della pagina e, se per esempio nel menu contestuale vogliamo voci tipo ‘Cancella questa immagine’, come possiamo scrivere una routine che funzioni indipendentemente dal numero delle immagini?
Esempio di menu contestuale per aggiungere, modificare o cancellare un immagine (indipendentemente dal numero di immagini caricate nella pagina)

Nel nostro esempio avremo un programma php che carica da disco un certo numero di immagini per le quali si vuole attivare un menu contestuale personalizzato con 3 voci:

  • Aggiungi immagine
  • Sostituisci immagine
  • Cancella immagine

Vi mostriamo subito quello che sarà l’esito finale del nostro esempio:

 

 

Il programma principale che chiameremo index.php altro non fa che:

  • Caricare le immagini in un array
  • Portare a video le immagini
  • Definire le voci del menu contestuale
  • Per ogni immagine si dovrà quindi richiamare la funzione che permette la visualizzazione del menu

Qui di seguito vi mostriamo il contenuto di index.php

<?php
//***********************************************************************************
//	Personalizzare la cartella delle immagini definita in IMG_PATH
//	Personalizzare le voci del proprio menu contestuale ed aggiungere i propri link
//***********************************************************************************
	session_start();
	define ("IMG_PATH", $_SERVER['DOCUMENT_ROOT']."/images/");
	$exts=array("jpg","jpeg");
	$images=wwGetFilesExt(IMG_PATH,$exts);
?>
<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title>Custom Context Menu (multi-images)</title>
		<link rel="stylesheet" href="css/cmenu.css">
	</head>
	<body>
		<header>
			<div>
				<h1>Prova di Menu Contestuale Personalizzato (multi-images)</h1>
			</div>
		</header>
		<section style="width:100%; height:280px;">
			<div id="areamenu" class="areamenu">
				<?php
				$TotImg=count($images);
				for($x = 0; $x < $TotImg; $x++) {
					$img="images/".$images[$x];
					echo '<div class="CellImg" id="img-'.$x.'" onmousedown="ContextM('.$x.', '.$TotImg.')">';
						echo '<img src="'.$img.'" alt="" style="max-height:280px; height:280px;">';
					echo '</div>';
				}
				?>
			</div>
			<div>
				<?php
				for($x = 0; $x < $TotImg; $x++) {
					$img="images/".$images[$x];
					?>
					<div class="cmenu" id="cmenu<?php echo $x;?>">
						<ul class="menu-options">
							<li class="menu-option"><a href="#">Add New Image</a></li>
							<li class="menu-option"><a href="#">Replace Image <b><i><?php echo $img;?></i></b></a></li>
							<li class="menu-option"><a href="#">Delete Image</a></li>
						</ul>
					</div>
					<?php
				}
				?>
			</div>
		</section>
		<script src="js/cmenu.js" type="text/javascript"></script>
	</body>
	<?php 
	function wwGetFilesExt($dir, $exts) {
	//-----------------------------------------------------------------------------
	// Ritorna un array con i files di $dir con estension inclusa nell'array $exts
	//-----------------------------------------------------------------------------
		$filesarray=array();
		$path = pathinfo($dir);
		if (is_dir($dir)) {	// Verifica che $dir sia una directory
			if ($dh = opendir($dir)) {	// apre la directory
				$n = 0;
				while (($file = readdir($dh)) !== false) {
					$extension = pathinfo($file, PATHINFO_EXTENSION);
					if (in_array(strtolower($extension), $exts)) {
						$filesarray[$n] = $file;
						$n++;
					}	
				}
				closedir($dh);
			}
		}
		return $filesarray;
	}	
	?>
</html>

Il programma andrà rivisto per adattarlo alla vostra situazione. In particolare per la cartella delle immagini e le voci di menu.

Nel foglio di stile cmenu.css abbiamo incluso le poche personalizzazioni dello stile che abbiamo ritenuto utili. Può essere modificato come più vi aggrada.

Infine occorre la funzione javascript che in index.php abbiamo chiamato ContextM() che permette la visualizzazione del menu contestuale personalizzato alla pressione del tasto destro del mouse.

 

function ContextM(n, tot) {
	let menuVisible = false;
	var menu=document.getElementById("cmenu"+n);
	document.getElementById("img-"+n).addEventListener("contextmenu", e => {
		e.preventDefault();
		for (var i = 1, len = tot; i <= len; i++) {
			if (i !=n) document.getElementById("cmenu"+i).style.display ="none";
		}
		var left = e.pageX;
		var top = e.pageY;
		setPosition(left, top);
		return false;
	});
	
	function setPosition(left, top) {
		menu.style.left = `${left}px`;
		menu.style.top = `${top}px`;
		menu.style.display = "block";
		menuVisible = true;
	}

	window.addEventListener("click", e => {
		if(menuVisible) {
			menu.style.display ="none";
			
		}
	})
}

Noi la abbiamo inserita in un file a parte chiamato cmenu.js. Potete ovviamente inserirla in index.php in uno script.

Va notato che le due righe

		var left = e.pageX;
		var top = e.pageY;

che identificano il vertice della finestra del menu contestuale potrebbe essere necessario che vengano modificate per posizionare correttamente la finestra a seconda della vostra pagina. Ad esempio potrebbe essere necessario una modifica tipo:

		var left = e.pageX - 200;
		var top = e.pageY - 200;

Il file che trovate qui contiene l’intero esempio.

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *