Background
I have a Blazor server-side app I’m building which will be a music sheets website. I’m having trouble running JavaScript code for a context menu. I’ve started adding a custom context menu, so users will be able to right-click on the page and I give them a list of custom actions they can take.
Problem
When I pull up the context menu on the UI, then click on one of the menu items, the script executes but it navigates back to the home page and I have no idea why. After putting in a bunch of console logging and using a sleep timer, it seems to just happen when the JavaScript finishes running, not on any particular action.
Code Details
Basically all the JavaScript code is doing is logging to the console and then closing the menu, I haven’t programmed any of the actions the menu will eventually take. Below is the code for NewSheet.razor. I’m only including relevant code for now, but I can add more details upon request.
@*HTML for context menu*@
<nav id="context-menu" class="context-menu">
<ul class="context-menu__items">
<li class="context-menu__item">
<a href="#" data-action="add-verse" class="context-menu__link"> Add Verse</a>
</li>
<li class="context-menu__item">
<a href="#" class="context-menu__link"> Add Chorus</a>
</li>
<li class="context-menu__item">
<a href="#" class="context-menu__link"> Add Bridge</a>
</li>
<li class="context-menu__item">
<a href="#" class="context-menu__link"> Add Line (notes and lyrics)</a>
</li>
</ul>
</nav>
<script>
var MenuOpen = false;
var ContextMenuActive = "context-menu--active";
var MenuElement = document.querySelector("#context-menu");
function clickInsideElement(e, className) {
var el = e.srcElement || e.target;
if (el.classList.contains(className)) {
return el;
} else {
while (el = el.parentNode) {
if (el.classList && el.classList.contains(className)) {
return el;
}
}
}
return false;
}
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
}
}
function init() {
contextListener();
clickListener();
keyupListener();
resizeListener();
}
function contextListener() {
document.addEventListener("contextmenu", function(e) {
//var taskItemInContext = clickInsideElement(e, "task"); // this should check if the click is on one of the context menu items, but instead causes the menu to never open.
//if (taskItemInContext) {
if (MenuOpen) {
toggleMenuOff();
} else {
e.preventDefault();
toggleMenuOn();
positionMenu(e);
}
});
}
function clickListener() {
document.addEventListener("click", function(e) {
var clickeElIsLink = clickInsideElement(e, "context-menu__link");
if (clickeElIsLink) {
e.preventDefault();
menuItemListener(clickeElIsLink); // logs the data attribute to the console. This essentially tells you which menu option was selected.
} else {
var button = e.which || e.button;
if (button === 1) {
toggleMenuOff();
}
}
});
}
// If user presses esc button then close the menu
function keyupListener() {
window.onkeyup = function(e) {
if (e.keyCode === 27) {
toggleMenuOff();
}
}
}
// If the user is resizing the browser window then close the context menu for now.
function resizeListener() {
window.onresize = function(e) {
toggleMenuOff();
};
}
// Safe method for toggling on the context MenuElement. Does check first to make sure menu is closed before attempting to open.
function toggleMenuOn() {
if (!MenuOpen) {
MenuElement.classList.add(ContextMenuActive);
MenuOpen = true;
}
}
// Safe method for toggling off the context MenuElement. Does check first to make sure menu is open before attempting to close.
function toggleMenuOff() {
if (MenuOpen) {
MenuElement.classList.remove(ContextMenuActive); // this doesn't seem to be causing an issue. Page still redirects, even when this is commented out.
MenuOpen = false;
}
}
function positionMenu(e) {
var clickCoords = getPosition(e);
var clickCoordsX = clickCoords.x;
var clickCoordsY = clickCoords.y;
var menuWidth = MenuElement.offsetWidth + 4;
var menuHeight = MenuElement.offsetHeight + 4;
var windowWidth = window.innerWidth;
var windowHeight = window.innerHeight;
if ((windowWidth - clickCoordsX) < menuWidth) {
MenuElement.style.left = windowWidth - menuWidth + "px";
} else {
MenuElement.style.left = clickCoordsX + "px";
}
if ((windowHeight - clickCoordsY) < menuHeight) {
MenuElement.style.top = windowHeight - menuHeight + "px";
} else {
MenuElement.style.top = clickCoordsY + "px";
}
}
// Function called to take an action from clicking on one of the menu items. After action is taken, closes the menu.
function menuItemListener(link) {
console.log(link.getAttribute("data-action")); // this is where the data action attribute is logged to the console.
}
</script>
Main Question:
Why does the app keep navigating back to the home page when the script runs?