Javascript: Issue with && statement not working properly - javascript

I'm trying to allow users to click within .dropdown-content and the menu remains open. However, I also need to leave the .dropbtn available to click otherwise they cannot open the menu.
I originally attempting to use || in the following code: !e.target.matches('.dropbtn') || !e.target.matches('.dropdown-content').
After a discussion in the comments I was informed that I should be using &&. I updated that section of code and still had some issues with getting the code to work properly. The snippet has been updated below.
Below you can see the area that I believe the focus should be. I am gathering all of the sections that would need to toggle between active and non-active states. Then trying to validate the following:
While a user is within .dropdown-content or any of its children it should not close.
Once the user clicks outside of the drop down button or .dropdown-content (not including DIVs that reside within it, aka. children) the menu should close.
Problem Area:
var ourCompany = document.getElementById("our-company");
var services = document.getElementById("services");
var products = document.getElementById("products");
var resources = document.getElementById("resources");
var goTo = document.getElementById("go-to");
// Close the dropdown(s) if the user clicks outside of it
window.onclick = function (e) {
if (!e.target.matches('.dropbtn') && !e.target.matches('.dropdown-content')) {
ourCompany.classList.remove('active-drop');
services.classList.remove('active-drop');
products.classList.remove('active-drop');
resources.classList.remove('active-drop');
goTo.classList.remove('active-drop');
}
}
Code:
/* Navigation Scroll */
var startPos = -1;
window.onscroll = function() {
var bar = document.getElementById('pm-nav');
var ourCompany = document.getElementById("our-company");
var services = document.getElementById("services");
var products = document.getElementById("products");
var resources = document.getElementById("resources");
var goTo = document.getElementById("go-to");
if (startPos < 0) startPos = findPosY(bar);
if (pageYOffset > startPos) {
bar.style.position = 'fixed';
bar.style.top = 0;
ourCompany.classList.add("dropdown-content-scroll");
services.classList.add("dropdown-content-scroll");
products.classList.add("dropdown-content-scroll");
resources.classList.add("dropdown-content-scroll");
goTo.classList.add("dropdown-content-scroll");
} else {
bar.style.position = 'relative';
ourCompany.classList.remove('dropdown-content-scroll');
services.classList.remove('dropdown-content-scroll');
products.classList.remove('dropdown-content-scroll');
resources.classList.remove('dropdown-content-scroll');
goTo.classList.remove('dropdown-content-scroll');
}
};
function findPosY(obj) {
var curtop = 0;
if (typeof(obj.offsetParent) != 'undefined' && obj.offsetParent) {
while (obj.offsetParent) {
curtop += obj.offsetTop;
obj = obj.offsetParent;
}
curtop += obj.offsetTop;
} else if (obj.y)
curtop += obj.y;
return curtop;
}
/* When the user clicks on the button, toggle between hiding and showing the dropdown(s) content */
function toggleDrop(drop) {
var i = 0;
while (i < 5) {
document.getElementById(document.getElementsByClassName('dropdown-content')[i].id).classList.remove('active-drop');
i++;
}
switch (drop) {
case "our-company":
document.getElementById("our-company").classList.add("active-drop");
break;
case "services":
document.getElementById("services").classList.add("active-drop");
break;
case "products":
document.getElementById("products").classList.add("active-drop");
break;
case "resources":
document.getElementById("resources").classList.add("active-drop");
break;
case "go-to":
document.getElementById("go-to").classList.add("active-drop");
break;
default:
//make this unknown...
}
}
var ourCompany = document.getElementById("our-company");
var services = document.getElementById("services");
var products = document.getElementById("products");
var resources = document.getElementById("resources");
var goTo = document.getElementById("go-to");
// Close the dropdown(s) if the user clicks outside of it
window.onclick = function(e) {
if (!e.target.matches('.dropbtn') && !e.target.matches('.dropdown-content')) {
ourCompany.classList.remove('active-drop');
services.classList.remove('active-drop');
products.classList.remove('active-drop');
resources.classList.remove('active-drop');
goTo.classList.remove('active-drop');
}
}
<link href="https://www.paymaster.com/net4/css/pm-main.css" rel="stylesheet" />
<!-- Website Header -->
<header class="pm-mainHeader">
<div class="maxWidth-1440">This is a Header</div>
</header>
<!-- Website header :END -->
<!-- Website Navigation -->
<div id="pm-nav" class="pm-mainNav">
<div class="maxWidth-1440">
<div class="pm-row pm-box-sizing">
<div class="dropdown pm-col-5">
<button onclick="toggleDrop('our-company');return false;" class="dropbtn">Our Company</button>
<div id="our-company" class="dropdown-content">
<div class="pm-row">
<div class="column">
<h3>Category 1</h3>
Link 1
Link 2
Link 3
</div>
<div class="column">
<h3>Category 2</h3>
Link 1
Link 2
Link 3
</div>
<div class="column">
<h3>Category 3</h3>
Link 1
Link 2
Link 3
</div>
</div>
<div class="mFooter redBg">
<h2>Menu our-company</h2>
</div>
</div>
</div>
<div class="dropdown pm-col-5">
<button onclick="toggleDrop('services');return false;" class="dropbtn">Services</button>
<div id="services" class="dropdown-content">
<div class="pm-row">
<div class="column">
<h3>Category 4</h3>
Link 1
Link 2
Link 3
</div>
<div class="column">
<h3>Category 5</h3>
Link 1
Link 2
Link 3
</div>
<div class="column">
<h3>Category 6</h3>
Link 1
Link 2
Link 3
</div>
</div>
<div class="mFooter blueBg">
<h2>Menu services</h2>
</div>
</div>
</div>
<div class="dropdown pm-col-5">
<button onclick="toggleDrop('products');return false;" class="dropbtn">Products</button>
<div id="products" class="dropdown-content">
<div class="pm-row">
<div class="column">
<h3>Category 1</h3>
Link 1
Link 2
Link 3
</div>
<div class="column">
<h3>Category 2</h3>
Link 1
Link 2
Link 3
</div>
<div class="column">
<h3>Category 3</h3>
Link 1
Link 2
Link 3
</div>
</div>
<div class="mFooter greenBg">
<h2>Menu products</h2>
</div>
</div>
</div>
<div class="dropdown pm-col-5">
<button onclick="toggleDrop('resources');return false;" class="dropbtn">Resources</button>
<div id="resources" class="dropdown-content">
<div class="pm-row">
<div class="column">
<h3>Category 1</h3>
Link 1
Link 2
Link 3
</div>
<div class="column">
<h3>Category 2</h3>
Link 1
Link 2
Link 3
</div>
<div class="column">
<h3>Category 3</h3>
Link 1
Link 2
Link 3
</div>
</div>
<div class="mFooter orangeBg">
<h2>Menu resources</h2>
</div>
</div>
</div>
<div class="dropdown pm-col-5">
<button onclick="toggleDrop('go-to');return false;" class="dropbtn">Go To</button>
<div id="go-to" class="dropdown-content">
<div class="pm-row">
<div class="column">
<h3>Category 1</h3>
Link 1
Link 2
Link 3
</div>
<div class="column">
<h3>Category 2</h3>
Link 1
Link 2
Link 3
</div>
<div class="column">
<h3>Category 3</h3>
Link 1
Link 2
Link 3
</div>
</div>
<div class="mFooter purpleBg">
<div class="closeBtnContainer">
<span class="closeBtn"><i class="material-icons">arrow_drop_up</i><i class="material-icons">menu</i></span>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- Website Navigation :END -->
<!-- Main Content -->
<div style="padding: 300px;">Test</div>
<!-- Main Content :END -->
<!-- Main Footer -->
<footer class="pm-mainFooter">
<div class="maxWidth-1440">This is a Footer</div>
</footer>
<!-- Main Footer :END -->

There was a lot of hate during the start of this question but I'm thankful for those who stuck around and helped out. The combination of different inputs lead me to figure out what the issue was, it was very simple, adding * to the end of .dropdown-content. Adding * tells the code to look at .dropdown-content and all of its children.
One of the original issue was solved by #Carcigenicate, they informed me I was using || instead of && combining this information with the data above lead me to the answer I was seeking, but my code was still not efficient. So, #rockstar pointed out some key things I could do to help improve my code and is responsible for half of the answer. Thanks again man!
Thanks everyone for the help, without further ado here is the...
ANSWER:
var elems = [
document.getElementById("our-company"),
document.getElementById("services"),
document.getElementById("products"),
document.getElementById("resources"),
document.getElementById("go-to")
];
window.onclick = function (e) {
if (!e.target.matches('.dropbtn') && !e.target.matches('.dropdown-content *')) {
elems.forEach(function (el) {
el.classList.remove("active-drop");
})
}
}

Related

How to make content open and transfer elements only for a specific block?

I have tabs. All of these tabs have their own slider. These sliders have cases (slide) during the discussion according to the "More" scheme, a block should open in full screen with this case absorbed, and it should switch between the "contents" of the slider cases.
I have tabs. All of these tabs have their own slider. These sliders have cases (slide) during the discussion according to the "More" scheme, a block should open in full screen with this case absorbed, and it should switch between the "contents" of the slider cases.
How to make a slider so that the content opens only on pointers, and the elements are transferred exactly on this slider in a tab.
enter image description here
enter image description here
[...document.querySelectorAll('.portfoliobtn')].forEach(function(item){
const caseBtn = item.querySelector('.btn-more');
const caseCloseBtn = item.querySelector('.close__content');
const caseContent = item.querySelector('.portfolio__content');
caseBtn.addEventListener('click', (event) => {
event.stopPropagation();
caseContent.classList.add('case__active');
document.body.classList.add('overflowhidden');
$('.portfolio__content').appendTo('body');
$('ul.tabs#portfolio').appendTo('.portfolio__content .pc__container .pc__header');
$('.swiper-button-next').appendTo('.portfolio__content .pc__container .sbc__wrapp');
$('.swiper-button-prev').appendTo('.portfolio__content .pc__container .sbc__wrapp');
});
caseCloseBtn.addEventListener('click', (event) => {
event.stopPropagation();
caseContent.classList.remove('case__active');
document.body.classList.remove('overflowhidden');
});
});
$('.services__content').each(function(){
let tabTabs = $(this).find('ul.tabs li');
let tabItems = $(this).find('.tab_content').hide();
$(".tab_container .tab_content.active").show();
tabTabs.each(function(i){
$(this).click(function(){
$(this).addClass('active').show();
tabTabs.not(this).removeClass('active');
$(tabItems[i]).addClass('active').show();
tabItems.not(tabItems[i]).removeClass('active').hide();
});
});
});
<div class="services__content">
<ul class="tabs" id="portfolio">
<li class="active"><a>Сайты</a></li>
<li><a>SMM</a></li>
<li><a>Контекст</a></li>
<li><a>Брендинг</a></li>
<li><a>Презентация</a></li>
<li><a>Полиграфия</a></li>
</ul>
<div class="tab_container">
<div class="tab_content active">
<div class="slider__wrapper">
<div class="swiper slider">
<div class="swiper-wrapper">
<div class="swiper-slide">
Слайд 1
<div class="portfoliobtn">
<button class="btn-more">подробнее</button>
<div class="portfolio__content">
<div class="pc__container">
<div class="pc__header">
</div>
<div class="sbc__wrapp">
</div>
<div class="close__content"></div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="tab_content">Остальные табы</div>
</div>
</div>
Link codepen

Trigger Jquery when user scrolls through it

I want to trigger a JQuery event when the user scrolls across a div for the firs time.
I have tried using waypoint. It is not working. Here is the code, it gives no error.
var waypoints = $('#main').waypoint({
handler: function(direction) {
alert("Main div");
}
})
HTML code:
<body>
<!-- main content -->
<div id="push"></div>
<section class="grey darken-4 valign-wrapper">
<div class="container valign">
<div class="col s12">
<h2 class="center-align white-text">Hey!</h2>
<div class="divider"></div>
<p class="center-align white-text flow-text developer"></p>
</div>
</div>
</div>
</section>
<div id="main">
<div class="container" style="padding-top:8px">
<h2 class="center black-text darken-4">Profile</h2>
<h4 class="center teal-text darken-4">
I love to Code <a class="pulse btn-floating"><i class="material-icons">favorite</i></a>
</h4>
<div class="divider"></div>
<div class="row" style="padding-top:5%">
<div class="col s4">
<h4 class=" teal-text darken-4">About me</h4>
<p class="flow-text me" style="font-size:20px">
</p>
</div>
<div class="col s4">
<img src="Images/Aarth.jpg" alt="" class="circle responsive-img">
</div>
<div class="col s4">
<h4 class="teal-text darken-4" style="padding-left:11%">Details</h4>
<p style="padding-left:11%; font-size:20px;" class="flow-text"><strong>Name:</strong>
<span class="name "></span>
</p>
<p style="padding-left:11%; font-size:20px;" class="flow-text"><strong>Age:</strong>
<span class="age"></span>
</p>
<p style="padding-left:11%; font-size:20px;" class="flow-text"><strong>Location:</strong>
<span class="location"></span>
</p>
</div>
</div>
</div>
</div>
</body>
Here are the approaches I have used till now, but nothing worked
function Utils() {
}
Utils.prototype = {
constructor: Utils,
isElementInView: function (element, fullyInView) {
var pageTop = $(window).scrollTop();
var pageBottom = pageTop + $(window).height();
var elementTop = $(element).offset().top;
var elementBottom = elementTop + $(element).height();
if (fullyInView === true) {
return ((pageTop < elementTop) && (pageBottom > elementBottom));
} else {
return ((elementTop <= pageBottom) && (elementBottom >= pageTop));
}
}
};
var Utils = new Utils();
Help would be great!
To use waypoints, bear in mind there needs to be enough scroll room for the top of the "main" div to hit the top of the viewport. This will vary depending on the size of the browser window the user has open. You can set a % offset from the top of the viewport to make it trigger when the element is a certain distance from the top.
If your "main" div is the last element, you can also use the special "bottom-in-view" offset to make it work once the scroll hits the bottom of the page, even if the top of "main" can't reach the top of the viewport:
var waypoints = $('#main').waypoint({
handler: function(direction) {
alert("Main div");
},
offset: "bottom-in-view"
});
All of this information is available in the documentation. See http://imakewebthings.com/waypoints/api/offset-option/ for more details

Multiple tabs in a single page, but the content of other tabs are also displaying in the first tab

This is my HTML code:
<div class="tab-content">
<div id="tab1" class="tab active">
<p>Hotels In Asia</p> <br>
<div class="asia1">
<p class="para1">$499 for 1 night</p>
<button>Book Now</button>
<p class="para2">See Photo</p>
</div>
<div class="asia1">
<p class="para1">$499 for 1 night</p>
<button>Book Now</button>
<p class="para2">See Photo</p>
</div>
<div class="asia1">
<p class="para1">$499 for 1 night</p>
<button>Book Now</button>
<p class="para2">See Photo</p>
</div>
<div class="tab11">
<div class="place active">
<p>Places In Asia</p>
<div class="asia">
<img src="../images/asia_hotel_1.jpg" alt="Asia hotel">
</div>
<div class="asia">
<img src="../images/asia_hotel_2.jpg" alt="Asia hotel">
</div>
<div class="asia">
<img src="../images/asia_hotel_3.jpg" alt="Asia hotel">
</div>
</div>
</div> <!-- tab11 end-->
</div><!-- tab1 end-->
<div id="tab2" class="tab">
<p>Hotels In Europe</p>
<p>para of tab2</p>
</div>
<div id="tab3" class="tab">
<p>Tab 3 content here!</p>
<p>para of tab3</p>
</div>
<div id="tab4" class="tab">
<p>Tab 4 content here!</p>
<p>para of tab4</p>
</div>
</div>
</div>
And this is my jquery which i used for multiple tabs within a single page.
<script type="text/javascript">
$(document).ready(function() {
$('.tab-links a').on('click', function(e) {
var currentAttrValue = $(this).attr('href');
// Show/Hide Tabs
$('.tabs ' + currentAttrValue).delay(400).slideDown(400);
$('.tabs ' + currentAttrValue).siblings().slideUp(400);
// Change/remove current tab to active
$(this).parent('li').addClass('active').siblings().removeClass('active');
e.preventDefault();
});
});
</script>
When I open my html page, all the content of other tabs also displaying in first tab. But when I switch to other tabs, contents are displayed fine.
Hope this piece of code will work. Please test it once.
$(document).ready(function() {
$(".tab").hide(); // first hide all the tabs
$(".tab").first().show(); // show only first tab by default
$('.tab-links a').on('click', function(e) {
e.preventDefault();
var currentAttrValue = $(this).attr('href');
currentAttrValue = currentAttrValue.substring(1); // Remove # from the href
// Show/Hide Tabs
$('#' + currentAttrValue).delay(400).slideDown(400); //add # to get the element id with specific id.
$('#' + currentAttrValue).siblings().slideUp(400);
// Change/remove current tab to active
$(this).parent('li').addClass('active').siblings().removeClass('active');
});
});
You have to specify the tab id when you got to the landing page so that other page contents would not come.

Change "selected" on scroll in page

I've been trying to get the automatic update on my navbar but i cant get it to work.
Here is my code: http://pastebin.com/YTHaBD0i
<div id="header">
<ul class="nav-list">
<li class="download selected">Download</li>
<li class="features">Features</li>
<li class="method">Method</li>
<li class="purchase">Purchase</li>
</ul>
</div>
<div id="footer">yey productions © 2016</div>
<div id="fullpage">
<div class="section " id="section0">
<div class="intro">
<h1>Download</h1>
<p>Lorem Ipsum</p>
</div>
</div>
<div class="section" id="section1">
<div class="slide" id="slide1">
<div class="intro">
<h1>Features</h1>
<p>Cheese.</p>
</div>
</div>
<div class="slide" id="slide2">
<h1>Cheese2</h1>
</div>
</div>
<div class="section" id="section2">
<div class="intro">
<h1>Yey</h1>
</div>
</div>
<div class="section" id="section3">
<div class="intro">
<h1>Yey2</h1>
</div>
</div>
</div>
Help would be much appreciated!
Greetz,
Assuming you are using jQuery, you will need a function that fires every time you scroll.
From there, you need to detect which elements are in view.
Once you know which elements are in view, clear any currently active elements with the .selected class, then choose which one you want to be .selected and add the .selected class.
Edit for more detail:
Below is a pure JavaScript solution, which I found here. This should be close to a drop-in solution!:
(function() {
'use strict';
var section = document.querySelectorAll(".section");
var sections = {};
var i = 0;
Array.prototype.forEach.call(section, function(e) {
sections[e.id] = e.offsetTop;
});
window.onscroll = function() {
var scrollPosition = document.documentElement.scrollTop || document.body.scrollTop;
for (i in sections) {
if (sections[i] <= scrollPosition) {
document.querySelector('.selected').setAttribute('class', ' ');
document.querySelector('a[href*=' + i + ']').setAttribute('class', 'selected');
}
}
};
})();

How do I open javascript div tabs with a link on the page

I am trying to use a link to open a specific tab that is created using divs and the tabs open and close using javascript.
Here are the tabs and the javascript is within the script tags at the bottom:
<div class="span12 module_cont module_tabs">
<div class="shortcode_tabs">
<div class="all_heads_cont">
<div class="shortcode_tab_item_title it1 head1 active" data-open="body1">%%LNG_ProductDescription%%</div>
<div class="shortcode_tab_item_title it2 head2" id="reviews" data-open="body2">%%LNG_JS_Reviews%%</div>
<div class="shortcode_tab_item_title it3 head3" data-open="body3">%%LNG_JS_ProductVideos%%</div>
<div class="shortcode_tab_item_title it4 head4" data-open="body4">%%LNG_JS_SimilarProducts%%</div>
</div>
<div class="all_body_cont">
<div class="shortcode_tab_item_body body1 it1">
<div class="ip">
%%Panel.ProductDescription%%
</div>
</div>
<div class="shortcode_tab_item_body body2 it2">
<div class="ip">
%%Panel.ProductReviews%%
</div>
</div>
<div class="shortcode_tab_item_body body3 it3">
<div class="ip">
%%Panel.ProductVideos%%
</div>
</div>
<div class="shortcode_tab_item_body body4 it4">
<div class="ip">
%%Panel.SimilarProductsByTag%%
%%Panel.ProductByCategory%%
%%Panel.ProductVendorsOtherProducts%%
%%Panel.SimilarProductsByCustomerViews%%
</div>
</div>
</div>
</div><!-- .shortcode_tabs -->
<script type="text/javascript">
jQuery('.shortcode_tabs').each(function(index) {
/* GET ALL HEADERS */
var i = 1;
jQuery('.shortcode_tab_item_title').each(function(index) {
jQuery(this).addClass('it'+i); jQuery(this).attr('whatopen', 'body'+i);
jQuery(this).addClass('head'+i);
jQuery(this).parents('.shortcode_tabs').find('.all_heads_cont').append(this);
i++;
});
/* GET ALL BODY */
var i = 1;
jQuery('.shortcode_tab_item_body').each(function(index) {
jQuery(this).addClass('body'+i);
jQuery(this).addClass('it'+i);
jQuery(this).parents('.shortcode_tabs').find('.all_body_cont').append(this);
i++;
});
});
jQuery('.shortcode_tabs .all_body_cont div:first-child').addClass('active');
jQuery('.shortcode_tabs .all_heads_cont div:first-child').addClass('active');
jQuery('.shortcode_tab_item_title').live('click', function(){
jQuery(this).parents('.shortcode_tabs').find('.shortcode_tab_item_body').removeClass('active');
jQuery(this).parents('.shortcode_tabs').find('.shortcode_tab_item_title').removeClass('active');
var whatopen = jQuery(this).attr('data-open');
jQuery(this).parents('.shortcode_tabs').find('.'+whatopen).addClass('active');
jQuery(this).addClass('active');
});
jQuery('reviews').live('click', function(){
jQuery(this).parents('.shortcode_tabs').find('.shortcode_tab_item_body').removeClass('active');
jQuery(this).parents('.shortcode_tabs').find('.shortcode_tab_item_title').removeClass('active');
var whatopen = jQuery(this).attr('data-open');
jQuery(this).parents('.shortcode_tabs').find('.'+whatopen).addClass('active');
jQuery(this).addClass('active');
});
</script>
</div><!-- .module_cont -->
All I want to do is have a link on the same page that activates the reviews tab (id="reviews") and is also known as the body2.
all I have so far for my link is:
Reviews
Help. My brain hurts...
You just need to set the link up so that it doesn't take the user to a new page, and then setup a click event to open the tab up. Example:
HTML:
<a href='javascript:void(0);' id='reviewLink'>Review Tab</a>
JavaScript:
$('#reviewLink').click(function() {
$('.shortcode_tab_item_body').css({display:'none'});
$('.body2').css({display:'none'});
});
Or a jsfiddle here: http://jsfiddle.net/tKLhn/

Categories

Resources