I have a woking accessible responsive navigation which for DEMO perpuses I have to make it reusable so I can show different sort of senarios. However tho, the click burger menu is not working.
This header with responsive navigation should work indipenently multiple times.
On click and matchMedia
typial responsive nav behavious with an extra touch of matchMedia in case user moves the window.
open navigation on click and remove navigation if > 900
navigation remove Attribute hidden on desktop and on click.
All of this should work multiple times.
if (navBlocks.length > 0){
Array.prototype.forEach.call(navBlocks, function(el) {
the forEach function shoud do the work right? how come is not really working?
DEMO HERE
const navBlocks = document.querySelectorAll('.nav-container');
const nav = document.querySelector('.sliding-nav');
const menu = document.querySelector(".sliding-nav ul");
const toggleMenu = document.querySelector(".nav-container .nav-cta");
const mediaQuery = window.matchMedia('(min-width: 900px)');
let isMenuOpen = false;
if (navBlocks.length > 0) {
Array.prototype.forEach.call(navBlocks, function(el) {
el.addEventListener('click', e => {
e.preventDefault();
isMenuOpen = !isMenuOpen;
toggleMenu.setAttribute('aria-expanded', String(isMenuOpen));
menu.hidden = !isMenuOpen;
if (isMenuOpen) {
nav.classList.add('is-open');
document.body.classList.add("is-no-scroll", "is-fixed");
//console.log(isMenuOpen);
} else {
nav.classList.remove('is-open');
document.body.classList.remove("is-no-scroll", "is-fixed");
//console.log(!isMenuOpen);
}
});
function handleTabletChange(e) {
// Check if the media query is true
if (e.matches) {
toggleMenu.setAttribute("aria-expanded", false);
menu.removeAttribute("hidden");
nav.classList.remove('is-open');
document.body.classList.remove("is-no-scroll", "is-fixed");
} else {
toggleMenu.setAttribute("aria-expanded", false);
//nav.removeAttribute("aria-expanded");
}
}
// Register event listener
mediaQuery.addListener(handleTabletChange);
// Initial check
handleTabletChange(mediaQuery);
});
}
I think you should do something like this,
add event listener on burger menu icon to toggle an active class in nav bar and you should write css for that active class that if nav contains "active" class it should be set to display or else it should display none!
Related
I have multiple scrollbars to my page, but can't make them working properly :
<div class="dates-container" v-for="id in ids">
<overlay-scrollbars
:ref="`datesHeader`+id"
:options="datesScrollOptions"
:key="id"
>
</div>
......
resetScroller() {
this.$nextTick(() => {
if (this.$refs[`datesHeader${this.currentRoom}`][0]) {
const inst = this.$refs[`datesHeader${this.currentRoom}`][0].osInstance();
if (inst == null) return;
const state = inst.getState();
if (state.hasOverflow.x) {
inst.scroll({ x: 0 });
}
this.updateScrollButtons();
}
});
},
Like that is working fine; The problem is when I tried to identify which scrollbar was moved and how I can update this.currentRoom when scrollbar is moved;
Firsty u have wrong :ref value - should be :ref="`datesHeader-${id}`"
then on onMounted you can add event listners to $refs
onMounted() {
this.$refs['datesHeader-0'].addEventLister('scroll', watchFunc)
}
DOCS:
https://developer.mozilla.org/pl/docs/Web/API/EventTarget/addEventListener
remember to remove event listeners in onBeforeUnmount
also, IntersectionObserver could be good for tracking scroll
DOCS: https://developer.mozilla.org/enUS/docs/Web/API/Intersection_Observer_API
I've made a dark mode toggle button for my demo website that adds a class to change the background color. The button works, but I want to swap out the image the button is using depending on if the class is present. It's not working. I think I've messed up MutationObserver somehow, can anyone help?
Javascript
let buttonIMG = document.getElementById("darkButtonIMG");
const observer = new MutationObserver(darkImage);
observer.observe(buttonIMG, {
attributes: true
});
function darkImage() {
let buttonIMG = document.getElementById("darkButtonIMG");
let buttonSRC = buttonIMG.hasAttribute("dark");
if (buttonSRC === true) {
buttonIMG.setAttribute("src", "images/Sun_Icon.png");
} else {
buttonIMG.setAttribute("src", "images/Moon_Icon.png");
}
}
HTML
<nav>
<div class="row">
<button class="buttonHide" id="hamburgerBtn">☰</button>
<ul id="navOpen">
...
<li><button id="darkButton" type="button" class=""><img id="darkButtonIMG"src="images\Moon_Icon.png" alt="Dark mode icon"></button></li>
</ul>
</div> <!-- End of Navbar Row -->
</nav>
I want to swap out the image the button is using depending on if the
class is present.
I'm assuming that when you click the button you're adding class dark to it.
In your callback method you're checking for the presence of dark attribute, but you should check for the presence of a class instead.
let buttonSRC = buttonIMG.classList.contains("dark");
You need to setAttribute for check hasAttribute
let buttonIMG = document.getElementById("darkButtonIMG");
const observer = new MutationObserver(darkImage);
observer.observe(buttonIMG, {
attributes: true
});
function darkImage() {
let buttonIMG = document.getElementById("darkButtonIMG");
let buttonSRC = buttonIMG.hasAttribute("dark");
if (buttonSRC === true) {
buttonIMG.setAttribute("src", "images/Sun_Icon.png");
buttonIMG.removeAttribute("dark");
} else {
buttonIMG.setAttribute("src", "images/Moon_Icon.png");
buttonIMG.setAttribute("dark", "dark");
}
}
I have created a function that allows a user to click a visible div that drops down a "hidden" div/submenu. To the right of the visible div there is an arrow image. In total there are 5 visible divs and 5 arrows. I am needed to have the arrows rotate 180 when the "hidden" div is opened, and rotate back to 0 deg when closed. With the current code written, I am able to select the first arrow image to rotate. If I am to click on the second div, which I would like the second arrow to rotate, the first arrow is getting the script. I would believe to use querySelectorAll, but the console does not pick it up. Any tips are always greatly appreciated!
//
const questionBox = document.getElementsByClassName("question__container");
const arrows = document.querySelector(".question__container--img");
[...questionBox].forEach((el) =>
el.addEventListener("click", (event) => {
const subMenu = event.target.parentElement.parentElement.querySelector(
".options__container"
);
subMenu.classList.toggle("open");
if (subMenu.classList.contains("open")) {
arrows.style.transform = "rotate(180deg)";
} else {
arrows.style.transform = "rotate(0deg)";
}
})
);
//
Building on your current logic, here's what you could do.
Get all arrows with querySelectorAll
Create a function collapseAllArrows that basically loops through all arrows and collapses them.
When any of the div element is clicked and the subMenu for that element is toggled to open then call the collapseAllArrows function to collapse all expanded arrows.
The find the arrow for the clicked div element and expand it.
Your code should look something like this
const questionBox = document.getElementsByClassName("question__container");
const arrows = document.querySelectorAll(".question__container--img");
const collapseAllArrows = () => {
arrows.forEach(arrow => arrow.style.transform = "rotate(0deg)";)
}
[...questionBox].forEach((el) =>
el.addEventListener("click", (event) => {
const subMenu = event.target.parentElement.parentElement.querySelector(
".options__container"
);
subMenu.classList.toggle("open");
if (subMenu.classList.contains("open")) {
collapseAllArrows();
const currentArrow = el.querySelector(".question__container--img");
currentArrow.style.transform = "rotate(180deg)";
}
})
);
Goal
I'm trying to remove the Help menu from Electron app's menu.
I don't want to setApplicationMenu of my own because it's fine to use the default menu except for the help, which points to Electron's own help pages.
Attempts
I've tried the following ways and failed in each case:
Remove the tail item, i.e., the Help
var menu = Menu.getApplicationMenu();
menu.items.pop();
Make it invisible
var menu = Menu.getApplicationMenu();
for(var i=0; i<menu.items.length; i++) {
if (menu.items[i].role == 'help') {
menu.items[i].visible = false;
break;
}
}
Remove the menu
mainWindow.removeMenu();
This just doesn't work on macOS with my electron version: 10.1.0.
Question
What's wrong? Should I create a template instead?
You must use Menu.setApplicationMenu after you modify the default menu
const menu = Menu.getApplicationMenu(); // get default menu
menu.items.find((item) => item.role === "help").visible = false; // modify it
Menu.setApplicationMenu(menu); // set the modified menu
Note: From my experience, Menu.getApplicationMenu() will return null if it's called before the app ready event
menuItem.visible does not work in Electron 13. Instead, I build a new menu without the Help item.
const menu = Menu.getApplicationMenu()
const items = menu?.items.filter((item) => item.role !== 'help')
Menu.setApplicationMenu(Menu.buildFromTemplate(items))
I'm using InboxSDK to add sidebar to thread view on GMail.
I do it like this:
InboxSDK.load(2, 'MY_KEY').then(sdk => {
sdk.Conversations.registerThreadViewHandler(threadView => {
const el = document.createElement("div");
el.id = 'mySidebar';
ReactDOM.render(<App />, el);
threadView.addSidebarContentPanel({
title: 'Sidebar Example',
iconUrl:chrome.extension.getURL('icon.png'),
hideTitleBar:true,
el:el
});
});
});
But I couldn't find any setting in InboxSDK docs that would enable me to show this panel as collapsed after it's created. Is it possible, or should I do it the dirty way, by adding/removing classes from elements manually?
How about trigger a click event on the button programmatically if the sidebar is opened?
if ($('.companion_app_sidebar_wrapper_visible').length > 0) {
$('.sidebar_thread_iconArea button[data-tooltip="Sidebar Example"]').trigger('click');
}