JS function only works properly after clicking on screen - javascript

I am building a title generator with HTML, CSS and JavaScript. The following code is supposed to do this:
Enter Edit-Mode with pressing of the "Enter"-Key (works correctly)
Turning down the opacity of the top left and top right box by clicking on the red buttons (works)
Hiding both items when exiting Edit-Mode by pressing "Enter" again. (works)
Enter Edit-Mode again and showing both hidden div boxes with opacity set to 20% (does not work)
Only the first box that was clicked on shows up again. It seems like the class "deactivated" is not safed for the last item being clicked on as it disappears on step 3.
However it does work when I click somewhere on the document before going to step 3.
Any help appreciated!
Full version can be found here
/*Switch between Display and Edit Mode*/
function toggleHideUI() {
var HideUI = document.getElementById("hiddenUI");
if (HideUI.style.display === "block") {
hideHiddenElements();
HideUI.style.display = "none";
} else {
showHiddenElements();
HideUI.style.display = "block";
}
};
/* EventListener for "Enter" Keybind */
document.addEventListener("keydown", (e) => {
if (e.code == "Enter") {
toggleHideUI();
}
});
/*Hide hidden elements (class = "deactivated") for Display Mode */
function hideHiddenElements() {
var HiddenElements = document.getElementsByClassName("deactivated");
for (i = 0; i < HiddenElements.length; i++) {
HiddenElements.item(i).style.display = "none";
}
};
/*Show hidden elements (class = "deactivated") for Edit Mode */
function showHiddenElements() {
var HiddenElements = document.getElementsByClassName("deactivated");
for (i = 0; i < HiddenElements.length; i++) {
HiddenElements[i].style.display = 'block';
}
}
/*Toggle DB Logo in upper left corner*/
document.getElementById("hide-db-logo").onclick = function toggleDBLogo() {
document.getElementById("db-box").classList.toggle("deactivated");
}
/*Toggle Campus Logo in upper right corner*/
document.getElementById("hide-campus-logo").onclick = function toggleCampusLogo() {
document.getElementById("campus-box").classList.toggle("deactivated");
}

I have updated the working script as:
The problem is when you click enter when the element is in focus, the event is propagating back.
<script>
/*Switch between Display and Edit Mode*/
function toggleHideUI() {
let HideUI = document.getElementById("hiddenUI");
if (HideUI.style.display === "block") {
hideHiddenElements();
HideUI.style.display = "none";
} else {
showHiddenElements();
HideUI.style.display = "block";
}
};
/* EventListener for "Enter" Keybind */
document.addEventListener("keydown", (e) => {
if (e.code == "Enter") {
e.preventDefault(); //<--- notice here
toggleHideUI();
}
});
/*Hide hidden elements (class = "deactivated") for Display Mode */
function hideHiddenElements() {
let HiddenElements = document.getElementsByClassName("deactivated"); //<--- notice here use let instead of var
for (let j = 0; j < HiddenElements.length; j++) {
HiddenElements[j].style.display = "none";
}
};
/*Show hidden elements (class = "deactivated") for Edit Mode */
function showHiddenElements() {
let HiddenElements = document.getElementsByClassName("deactivated");
//<--- notice here use let instead of var
for (let i = 0; i < HiddenElements.length; i++) {
HiddenElements[i].style.display = 'block';
}
}
/*Toggle DB Logo in upper left corner*/
document.getElementById("hide-db-logo").onclick = function toggleDBLogo() {
document.getElementById("db-box").classList.toggle("deactivated");
}
/*Toggle Campus Logo in upper right corner*/
document.getElementById("hide-campus-logo").onclick = function toggleCampusLogo() {
document.getElementById("campus-box").classList.toggle("deactivated");
}
</script>
Good Luck!

Related

Changing the image source when pressing the back button

I have a slider. When clicking next button image is loading.
var t=3
function next_btn(){
t+=3;
var imgEl = document.querySelectorAll('.lazy');
for (let a = 0; a < t; a++) {
if(imgEl[a].getAttribute('data-original')) {
imgEl[a].setAttribute('src',imgEl[a].getAttribute('data-original'));
imgEl[a].removeAttribute('data-original');
}
}
}
but when clicking previous button image is not loading.
function previous_btn(){
var imgEl = document.querySelectorAll('.lazy');
for (let a =imgEl.length; a >3; a--) {
if(imgEl[a].getAttribute('data-original')) {
imgEl[a].setAttribute('src',imgEl[a].getAttribute('data-original'));
imgEl[a].removeAttribute('data-original');
}
}
}
I tried other things but it didn't work. How can I fix?

I have a problem calling with my carousel codes, it keeps keeping variables for other conditions

I have tried so many method to stop this error but nothing seems to work, here is a link to my codepen: https://codepen.io/T_manuel/pen/PoKMYVx
when the page loads, I call the function but when I resize the page, Javascript seems to do the new logic also with previous logics...
const mediaQuery_1 = '(max-width:601px)';
const mediaQueryList1 = window.matchMedia(mediaQuery_1);
/carousel parent div -- to dynamically load the carousel items
// define media queries
const mediaQuery_1 = '(max-width:601px)';
// add matchMedia
const mediaQueryList1 = window.matchMedia(mediaQuery_1);
if (mediaQueryList1.matches) {
carouselFunc(); // dynamic loaded pictures
LeftArrow.classList.add("displayNone");
let indexOfImg = 0; //to be accessed for the carousel, index for first image
let endofImg = 3; //carousel use, index for next image to be displayed
otherCarouselLogic(indexOfImg, endofImg);
if (carouselPics.length > 3) {
for (i = 3; i < carouselPics.length; i++) {
carouselPics[i].classList.add("displayNone");
}
RightArrow.classList.remove("displayNone");
} else {
RightArrow.classList.add("displayNone");
}
}
else {
carouselFunc(); //dynamic loaded Pictures
LeftArrow.classList.add("displayNone");
let IndexOfImg = 0; //to be accessed for the carousel, index for first image
let EndOfImg = 4; //carousel use, index for next image to be displayed
otherCarouselLogic(IndexOfImg, EndOfImg);
if (carouselPics.length > 3) {
for (i = 4; i < carouselPics.length; i++) {
carouselPics[i].classList.add("displayNone");
}
}
// not to display carousel arrows if pics can be showed at once
if (carouselPics.length <= 4) {
RightArrow.classList.add("displayNone");
}
}
// add event Listener
mediaQueryList1.addEventListener("change", function carouselUx(event) {
if(event.matches) {
document.getElementById("carous").innerHTML = "";
carouselFunc(); //contains dynamic loaded pictures
LeftArrow.classList.add("displayNone");
let indexOfImg = 0; //to be accessed for the carousel, index for first image
let endofImg = 3; //carousel use, index for next image to be displayed
otherCarouselLogic(indexOfImg, endofImg);
if (carouselPics.length > 3) {
for (i = 3; i < carouselPics.length; i++) {
carouselPics[i].classList.add("displayNone");
}
RightArrow.classList.remove("displayNone");
} else {
RightArrow.classList.add("displayNone");
}
}
else {
document.getElementById("carous").innerHTML = "";
carouselFunc();
LeftArrow.classList.add("displayNone");
let IndexOfImg = 0; //to be accessed for the carousel, index for first image
let EndOfImg = 4; //carousel use, index for next image to be displayed
otherCarouselLogic(IndexOfImg, EndOfImg);
if (carouselPics.length > 3) {
for (i = 4; i < carouselPics.length; i++) {
carouselPics[i].classList.add("displayNone");
}
}
// not to display carousel arrows if pics can be showed at once
if (carouselPics.length <= 4) {
RightArrow.classList.add("displayNone");
}
}
})
function otherCarouselLogic(cpF, newImg) {
/* carousel code ends here */
carouselBtn.forEach(function (btns) {
btns.addEventListener("click", function (e) {
clickedArrow = e.currentTarget.id;
if (clickedArrow === "right") {
console.log(newImg);
carouselPics[cpF].classList.add("displayNone");
carouselPics[newImg].classList.remove("displayNone");
LeftArrow.classList.remove("displayNone");
cpF += 1;
newImg += 1;
}
if (clickedArrow === "left") {
cpF -= 1;
newImg -= 1;
carouselPics[newImg].classList.add("displayNone");
carouselPics[cpF].classList.remove("displayNone");
RightArrow.classList.remove("displayNone");
console.log(newImg);
}
// ux purpose, when we get to the last pics in the carousel, the right arrow is hidden
diffR = carouselPics.length - newImg;
// diffL
if (diffR === 0) {
RightArrow.classList.add("displayNone");
}
if (cpF === 0) {
LeftArrow.classList.add("displayNone");
}
});
});
/* carousel code ends here */
}
upon load,
newImg is set to 4 and all seems to work
after resize, it is set to either 3 or 4 depending on the logic, but instead of incrementing that value alone, it gives value for the load and also for the resize.

How to add window event to close an open nav dropdown, but keep toggle open/close nav dropdown behavior on nav-item?

I have worked on this for a couple of days and I feel like I am almost there. I inherited a navigation component that behaves like any navigation -- User clicks a nav item to show the dropdown menu and clicks the nav-item or dropdown menu to close it. HOWEVER, I now need to be able to close any open dropdown menu when the user clicks anywhere else on the page.
The issue I'm facing is that I need to get my window event to ignore the nav. Otherwise, clicking the window removes the users' ability to close the nav on nav-click.
I have pasted my JavaScript code below. Can someone please assist me? Thank you.
The navClick() function was already there. I have added closeMenuOnWindowClick().
function initNav() {
const primaryNavElement = document.querySelector("#dcom-nav-primary");
const secondaryNavElement = document.querySelector("#dcom-nav-secondary");
const secondaryNavLinks = document.querySelectorAll(".dcom-nav-secondary-links");
//These variables are defined in the markup and dumped at that level. Added eslint lines below so it doesn't scream at us.
// eslint-disable-next-line
let navigationArray = [];
if(primaryNavElement){
navigationArray = primaryNavElement.getElementsByTagName("li");
}
let i;
const navClick = function() {
let navElm = this;
//Navigation buttons are relying on the navlevel attribute in the markup to determine how they behave
if(navElm,navigationArray.length,secondaryNavLinks){
if(navElm.attributes.navlevel){
if(navElm.attributes.navlevel.nodeValue == 'primary'){
//Primary Nav Click
//Reset and apply active link tab
for(i = 0; i<navigationArray.length; i++){
navigationArray[i].desktopDOMs[0].classList.remove('dcom-c-navigation-bar__li--active');
navigationArray[i].desktopDOMs[1].classList.add('dcom-c-navigation-bar__secondary-row--hidden');
}
navigationArray[navElm.index].desktopDOMs[0].classList.add('dcom-c-navigation-bar__li--active');
navigationArray[navElm.index].desktopDOMs[1].classList.remove('dcom-c-navigation-bar__secondary-row--hidden');
} else if(navElm.attributes.navlevel.nodeValue == 'secondary'){
//Secondary Nav Click
let dropdown = navElm.querySelector(".dcom-c-navigation-bar__dropdown");
if(dropdown){
for(i = 0; i<secondaryNavLinks.length; i++){
for(let ii = 0; ii<secondaryNavLinks[i].children.length; ii++){
let sDropdown = secondaryNavLinks[i].children[ii].querySelector(".dcom-c-navigation-bar__dropdown");
if(sDropdown != dropdown){
sDropdown.classList.add('dcom-c-navigation-bar__dropdown--hidden');
}
}
}
if(dropdown.children.length > 0){ //In the event the secondary dropdown has no tertiary links, do nothing, let it navigate.
// If there are only 2 items, remove flex-wrap
if(dropdown.children.length < 3) {
dropdown.style.flexWrap = 'nowrap';
}
if(dropdown.classList.contains('dcom-c-navigation-bar__dropdown--hidden')) {
dropdown.classList.remove('dcom-c-navigation-bar__dropdown--hidden');
dropdown.style.width = "auto"; //Reset width
//Handle dropdown width
//First, find out how many columns we need;
let dropdownCols = [[],[],[]];
let c = 0;
let r = 0;
for(i = 0; i < dropdown.children.length; i++){
dropdownCols[c].push(dropdown.children[i]);
r++;
if(r > 5){
r = 0;
c++;
}
}
//Then step through the links we have, find the largest, and set the largest size in each column
let colWidths = [0,0,0];
for(i = 0; i<dropdownCols.length; i++){
for(let ii = 0; ii<dropdownCols[i].length; ii++){
let linkWidth = dropdownCols[i][ii].offsetWidth;
if(linkWidth > colWidths[i])colWidths[i]=linkWidth;
}
}
//Set the width of the dropdown to the size of the largest columns
dropdown.style.width = (colWidths[0]+colWidths[1]+colWidths[2]+20)+"px";
//For IE fix we have to manually set the height. It's stupid, I know.
let linkHeight = dropdownCols[0][0].offsetHeight + 3; //get the height of one link element
//Check if its less than 6 (which wraps)
if(dropdown.children.length < 6){
//If its less than 6, make the height the height of the number of children
dropdown.style.height = (linkHeight * dropdown.children.length)+"px";
} else {
//Otherwise, set it to 6
dropdown.style.height = linkHeight * 6+"px";
}
//Check if this div is going off the screen
dropdown.style.right = "";
dropdown.style.left = "";
var dropdownRect = dropdown.getBoundingClientRect();
if((dropdownRect.left + dropdown.offsetWidth) > window.innerWidth){
dropdown.style.right = 0;
dropdown.style.left = "auto";
}
} else {
dropdown.classList.add('dcom-c-navigation-bar__dropdown--hidden');
//hide it if its open
}
}
}
}
/* Note: Since we don't have a Single Page Application here (haha), the assumption is that tertiary links will cause a page reload/navigation.
* In the event this is used in a SPA framework, can add a check here for tertiary controls, and add a click handler above.
*/
} else {
//Otherwise, using a switch based on the element id (for now! have had success with custom attributes before to determine button purpose that has less risk of conflict)
switch(navElm.id) {
default:
//Do nothing
}
}
}
};
if(primaryNavElement,secondaryNavElement,secondaryNavLinks.length){ //check all elements exist
//Find and add click handlers to all primary nav links
for(i = 0; i<primaryNavElement.children.length; i++){
if(primaryNavElement.children[i].nodeName == "LI"){ //double checking I'm grabbing list items
navigationArray[i].desktopDOMs = [];
navigationArray[i].desktopDOMs.push(primaryNavElement.children[i]); //Assign to reference array for future use
primaryNavElement.children[i].index = i; //I add an index here for reference
primaryNavElement.children[i].addEventListener('click', navClick);
//each primary nav's secondary navs
}
}
//Find all secondary links bars, store reference
for(i = 0; i<secondaryNavElement.children.length; i++){
navigationArray[i].desktopDOMs.push(secondaryNavElement.children[i]);
secondaryNavElement.children[i].index = i;
//secondaryNavElement.children[i]
}
//For all links, add handler, push to desktopDOMS
//console.log(secondaryNavLinks);
for(i = 0; i<secondaryNavLinks.length; i++){
for(let ii = 0; ii<secondaryNavLinks[i].children.length; ii++){
secondaryNavLinks[i].children[ii].index = i;
secondaryNavLinks[i].children[ii].addEventListener('click', navClick);
}
}
}
function closeMenuOnWindowClick() {
//Get all dropdowns
let menus = document.getElementsByClassName('dcom-c-navigation-bar__dropdown');
//Convert to array
menus = [...menus];
let openMenu;
//Loop through to find secondary level menu that is currently open
menus.forEach(menu => {
//If it's a secondary level nav and it's showing
if(menu.attributes.navlevel = 'secondary' && !menu.classList.contains('dcom-c-navigation-bar__dropdown--hidden')){
//Get it and label it
openMenu = menu;
openMenu.classList.add('dcom-c-navigation-bar__dropdown--hidden');
}
})
}
window.addEventListener('mouseup', function() {
closeMenuOnWindowClick();
navClick();
}, false);
}
module.exports = initNav;
Thanks to stackoverflow, I found bits of snippets here and there and was able to succeed!
Here's how I accomplished the solution:
// Click anywhere on the page to close an open menu.
window.addEventListener('click', function (ev) {
// Click anywhere, excluding element with a class you want to ignore, to hide the dropdown.
if (ev.target.className !== 'ignoreThisClass') {
dropdown.classList.add('addYourOwnHideClass');
}
});

jscript for toggling a hamburger menu not working

I am trying to fix some stuff left over by the front-end developer and I am not expert in javascript (not at all).
On our staging system we use a hamburger menu and for reasons unknown to me while the hamburger menu toggles perfectly on opening, upon first closing it doesn't revert back from an "X" to the "Hamburger" subsequent changes instead work flawlessly just that the state is inverted ("X" where there should be a hamburger and hamburger where there should be an "X").
So I did it half right (but only half :D).
My rather not beautyful code:
<script type="text/javascript">
var headerMobile = document.getElementsByClassName('header-mobile')[0];
var openMobileMenuTrigger = document.getElementById('open-mobile-menu');
var closeMobileMenuTrigger = document.getElementById('close-mobile-menu');
var mobileMainMenu = document.getElementById('header-mobile_menu');
var submenus = document.getElementsByClassName('header-mobile_submenu');
var openMobileSubMenuTriggers = document.getElementsByClassName('open-mobile-submenu');
var closeMobileSubMenuTriggers = document.getElementsByClassName('close-mobile-submenu');
var hamburgerHeader = document.getElementById('open-mobile-menu');
var openSearchTrigger = document.getElementById('open-search-field')
function toggleHamburger(){
if (hamburgerHeader.classList.contains('is-active')){
hamburgerHeader.classList.remove('is-active');
} else {
hamburgerHeader.classList.add('is-active');
}
}
function toggleMobileMenu(){
if(mobileMainMenu.classList.contains('is-active') !== true){
if (openSearchTrigger)
{openSearchTrigger.classList.remove('is-active')}
mobileMainMenu.classList.add('is-active');
headerMobile.classList.add('is-active'); //remove shadow
document.getElementsByTagName('html')[0].classList.add('noscroll')// no scroll for html
document.getElementsByTagName('body')[0].classList.add('noscroll')// no scroll for body
} else {
setTimeout(
function(){
// headerMobile.classList.remove('is-active'); // NO MORE SHADOW IF WE KEEP ACTIVE SEARCH MENU
for (var i = submenus.length - 1; i >= 0; i--) {
submenus[i].classList.remove('is-active');
}
},
400
)
if(openSearchTrigger){
openSearchTrigger.classList.add('is-active')
}
hamburgerHeader.classList.remove('is-active')
mobileMainMenu.classList.remove('is-active')
document.getElementsByTagName('html')[0].classList.remove('noscroll')// no scroll for html
document.getElementsByTagName('body')[0].classList.remove('noscroll')// no scroll for body
}
}
function openMobileSubmenu(event){
var submenuId = event.currentTarget.getAttribute('data-submenu');
document.getElementById('header-mobile_submenu-' + submenuId).classList.add('is-active');
}
function closeMobileSubmenu(){
for (var i = submenus.length - 1; i >= 0; i--) {
submenus[i].classList.remove('is-active');
}
}
if (openSearchTrigger){
openSearchTrigger.addEventListener('click', toggleMobileMenu);
}
openMobileMenuTrigger.addEventListener('click', toggleMobileMenu);
// closeMobileMenuTrigger.addEventListener('click', closeMobileMenu);
hamburgerHeader.addEventListener('click', toggleHamburger);
for (var i = openMobileSubMenuTriggers.length - 1; i >= 0; i--) {
openMobileSubMenuTriggers[i].addEventListener('click', openMobileSubmenu);
}
for (var i = closeMobileSubMenuTriggers.length - 1; i >= 0; i--) {
closeMobileSubMenuTriggers[i].addEventListener('click', closeMobileSubmenu);
}

Can i create a javascript carousel which contains a flash file as well as static images?

I was wondering if it's possible to include an swf within a javascript carousel that currently just contains stagic images. What I'm looking to do is include a flash animation within the carousel.
I guess I've got two main questions:
Is it possible to cycle through flash files in the same way as an image?
How would I get the javascript and flash to interact so the flash file would know when it had been selected?
If it helps, here's the js we're using:
$(document).ready(function(){
var $looper = true;
var timer;
var currentSlide = 0;
var cell = 0;
var row = 1;
var hCycles = 0;
var aCycles = 0;
//no. of full cycles
var homecycles = 2;
var aboutcycles = 2;
//aboutSlide speed
var fast = 1200;
var slow = 4000;
//hide homepage slides
$('#slide2').fadeOut(0);
$('#slide3').fadeOut(0);
$('#slide4').fadeOut(0);
$('#slide5').fadeOut(0);
$('#slide6').fadeOut(0);
//hide about slides
$('.a-slide1').fadeOut(0);
$('.a-slide2').fadeOut(0);
$('.a-slide3').fadeOut(0);
$('.a-slide4').fadeOut(0);
$('#slide-c1 .a-slide1').fadeIn(1200);
runSlide(fast);
function runSlide(x) {
if ($('body').is('.about')) {
setTimeout(function() {
aboutSlides();
}, x);
} else {
if ($looper) {
setTimeout(function() {
slideShow();
}, 4000);
}
}
}
function slideShow() {
if ($looper) {
if (currentSlide++ < 6 && hCycles < homecycles) {
$('#slide'+ currentSlide).fadeOut(1200);
if (currentSlide == 6) {
$('#slide1').fadeIn(1200);
$('#slide-wrapper li').removeClass('active');
$('#btn1').addClass('active');
currentSlide = 0;
hCycles = hCycles+1;
} else {
$('#slide'+ (currentSlide+1)).fadeIn(1200);
$('#slide-wrapper li').removeClass('active');
$('#btn'+ (currentSlide+1)).addClass('active');
}
runSlide();
} else {
$looper = false;
}
}
};
$('#slide-wrapper li').each(function(index) {
$('#btn'+(index+1)).click(function(){
$looper = false;
$('.slide').fadeOut(1200);
$('#slide'+ (index+1)).fadeIn(1200);
$('#slide-wrapper li').removeClass('active');
$(this).addClass('active');
});
});
function aboutSlides() {
if (cell++ < 3 && aCycles < aboutcycles) {
if (cell == 3) {
if (row < 3) {
row = row+1;
} else {
row = 1;
aCycles = aCycles+1;
}
var hide = (row-1);
if ((row-1) == 0) {hide = 3}
$('#slide-c1 .a-slide'+ hide).fadeOut(1200);
$('#slide-c1 .a-slide'+row).fadeIn(1200);
cell = 0;
runSlide(fast);
} else {
$('#slide-c'+(cell+1)+' .a-slide'+ (row-1)).fadeOut(1200);
$('#slide-c'+(cell+1)+' .a-slide'+(row)).fadeIn(1200);
if (cell == 2) {
runSlide(slow);
} else {
runSlide(fast);
}
}
} else {
// create the final strip
$('#slide-c3 .a-slide3').fadeOut(1200);
$('#slide-c3 .a-slide4').fadeIn(1200);
}
}
});
Thanks!
There isn't any problem as to whatever content you want to put in your slides. As long as it is valid html, it's valid in a slide. Countless jquery/motools/etc plugins let you specify whatever you want for content.
flash is valid.
But you might want to revert to another revealing method. setting the opacity on a swf from javascript is complex and yields to different results, according to browser and flash version. If your flash file is custom made, then you can create a function that fades it to white for example, and call it from javascript. But from experience, changing the opacity of a swf is calling for trouble.
I don't know if this is relevant enough to be an answer, I wanted to post it as a comment, but there isn't any comment button. Oh well.

Categories

Resources