Combine multiple for loops to remove classes on click - javascript

I'm looking for some advice regarding having 2-3 for loops in one javascript statement to find elements with a particular class then add and remove classes. I'm fairly new to javascript so bear with me.
What I have so far works but I just don't want to get into bad habits down the line. As an example I have a navigation link that has a class of to--kenya, there is also another element with the same class and when either of these 2 elements are clicked i want the same thing to happen which will be to add an active--section class to the associated section named kenya.
The first for loop will look for all the elements with the class name to--kenya and add a click listener to them. If neither of these 2 elements has the class active--section it then runs another for loop looking for all the sections that have a class called active--section and removes it if it has the class. Then a third for loop runs checking all the navigation links to find a link with the active--link class then removes it if it has it. Once this is complete i just add a class to my new active navigation link as well as add the active--section class to the now active section.
Hope this makes sense, I'm just looking for the cleanest way of doing this.
<main class="main__wrapper">
<nav class="navigation">
<div class="navigation__inner">
<div class="navigation__logo">
Safari
</div>
<ul class="navigation__destinations">
<li class="navigation__destinations--item">
Home
</li>
<li class="navigation__destinations--item">
Kenya
</li>
<li class="navigation__destinations--item">
Botswana
</li>
<li class="navigation__destinations--item">
South Africa
</li>
<li class="navigation__destinations--item">
</li>
</ul>
<ul class="navigation__list">
<li class="navigation__item">
Contact
</li>
</ul>
</div>
</nav>
<div class="up__next">
<div class="up__next__box up__next--kenya to--kenya up__next__box--active">
<div class="up__next__content">
<div class="up__next__info">
<h4 class="up__next__heading">Next</h4>
<span class="up__next__text">Kenya - Maasai Mara National Reserve</span>
</div>
</div>
<div class="up__next__img">
<div class="up__next__img--kenya"></div>
</div>
</div>
</div>
<section class="home sections active--section">
<div class="home__info__box">
<h2 class="heading__primary home__heading--primary">Heading</h2>
<span class="home__info__box--text">text</span>
</div>
</section>
<section class="kenya sections">
<div class="kenya__info__box">
<h2 class="heading__primary kenya__heading--primary">Masai Mara</h2>
<span class="kenya__info__box--text">text</span>
</div>
</section>
</main>
//Global variables
var sections = document.querySelectorAll('.sections');
var navLink = document.querySelectorAll('.navigation__link');
var navHome = document.querySelector('.navigation__link--home');
var navKenya = document.querySelector('.navigation__link--kenya');
var home = document.querySelector('.home');
var kenya = document.querySelector('.kenya');
var toKenya = document.querySelectorAll('.to--kenya');
var upNextKenya = document.querySelector('.up__next--kenya');
//Event listeners
for (var i = 0; i < toKenya.length; i++) {
toKenya[i].addEventListener('click', function () {
if (!kenya.classList.contains('active--section')) {
for (var s = 0; s < sections.length; s++) {
sections[s].classList.remove('active--section');
}
for (var l = 0; l < navLink.length; l++) {
navLink[l].classList.remove('active--link');
}
kenya.classList.add('active--section');
navKenya.classList.add('active--link');
upNextKenya.classList.remove('up__next__box--active');
}
});
}

Related

get ul li elements inside other ul li Javascript

I'm having trouble getting elements that are inside other elements. I want to overwrite a text that was already written in my HTML document.
My HTML code:
<div class="row">
<div class="col-12 col-md-6">
<h3 class="h3 generalfont">Industry Experience</h3>
<article>
<ul>
<li>
Project FIUBA, Algorithms and Programming I, Argentina, 2021
<ul>
<li>Project FIUBA, Algorithms and Programming I, Argentina, 2022</li>
</ul>
</li>
</ul>
</article>
<div>
<input id="edit-aboutme" type="text" oninput="asignar_palabras_2(this.value)" style="display: none;">
</div>
</div>
</div>
My Javascript code:
function cambiar_parrafo_2(){
document.querySelector("input").style.display = "inline";
let container = document.querySelector(".col-12");
let texto = container.querySelectorAll("article > ul > li");
for (let i = 0; i < texto.length; i++) {
texto[i].textContent = "";
}
}
The Javascript code before only delete text into li elements, the function is call when user click an image (I didn't add that piece of code to avoid making it extensive)...
So, after deleting the text, I want to write something new given by the user on input but it doesn't overwrite it.
This is the code that I thought:
function asignar_palabras_2(value) {
let container = document.querySelector(".col-12");
let texto = container.querySelectorAll("article > ul > li > ul > li");
for (let i = 0; i < texto.length; i++) {
texto[i].textContent = value;
}
}
Thanks in advance for your answers.
It would be much more helpful to give them useful classnames, so that you can select them directly.
eg: outer and inner.
function cambiar_parrafo_2(value) {
document.querySelector("input").style.display = "inline"
let container = document.querySelector(".col-12")
let texto = container.querySelectorAll("article ul.inner li")
for (let i = 0; i < texto.length; i++) {
texto[i].textContent = value
}
}
cambiar_parrafo_2('sdfsdfds')
<div class="row">
<div class="col-12 col-md-6">
<h3 class="h3 generalfont">Industry Experience</h3>
<article>
<ul class="outer">
<li>
Project FIUBA, Algorithms and Programming I, Argentina, 2021
<ul class="inner">
<li>Project FIUBA, Algorithms and Programming I, Argentina, 2022</li>
</ul>
</li>
</ul>
</article>
<div>
<input id="edit-aboutme" type="text" oninput="cambiar_parrafo_2(this.value)" style="display: none;">
</div>
</div>
</div>

How to click on a link on one page and change the location of a specific class on another page at the same time?

I designed two pages on the website.I want the second tab - btn, instead of the first tab - btn, to have id = "default" and accept the activate class when the link on page 1 is clicked and goes to page 2. As you can see in the html code, there is normally id = "default" and the activate class in tab1.But when the link on page 1 is clicked and page 2 appears, instead of tab1, the second tab has id = "default" and an activate class. Meanwhile, tab1 lacks id = "default" and the class is activated. Can I manage this with JavaScript?
Thank you in advance for your cooperation, friends
//codes of javascript for page: 2
function tabs(e,name){
var tab_btn = document.getElementsByClassName('tab--btn');
var tab_content = document.getElementsByClassName('tab--content');
var supporItemsCard = document.querySelector('.support--items__card');
var i;
for( i = 0 ; i<tab_btn.length ; i++){
tab_btn[i].classList.remove('active');
}
for(i = 0 ; i<tab_content.length ; i++){
tab_content[i].style.display = 'none';
}
document.getElementById(name).style.display = 'block';
e.currentTarget.classList.add('active');
}
document.getElementById('default').click();
page: 1
link page 1
page: 2
<ul class="support--items__cards">
<li class="support--items__card tab--btn" id="default" onclick="tabs(event,'tab1')">
<h4 class="support--items__card__title">TAB 1</h4>
</li>
<li class="support--items__card tab--btn" onclick="tabs(event,'tab2')">
<h4 class="support--items__card__title">TAB 2</h4>
</li>
<li class="support--items__card tab--btn" onclick="tabs(event,'tab3')">
<h4 class="support--items__card__title">TAB 3</h4>
</li>
<ul>
<div class="content">
<div id="tab1" class="tab--content">
content tab 1
</div>
<div id="tab2" class="tab--content">
content tab 2
</div>
<div id="tab3" class="tab--content">
content tab 3
</div>
</div>
You can check the referrer page on page 2 and execute your already existing function tabs to go to second tab. At that time remove id from first tab and add that attribute to the second li. I removed event from tab function and used tabid only.
<ul class="support--items__cards">
<li class="support--items__card tab--btn" id="default" onclick="tabs('tab1')">
<h4 class="support--items__card__title">TAB 1</h4>
</li>
<li class="support--items__card tab--btn" onclick="tabs('tab2')">
<h4 class="support--items__card__title">TAB 2</h4>
</li>
<li class="support--items__card tab--btn" onclick="tabs('tab3')">
<h4 class="support--items__card__title">TAB 3</h4>
</li>
</ul>
<div class="content">
<div id="tab1" class="tab--content">
content tab 1
</div>
<div id="tab2" class="tab--content">
content tab 2
</div>
<div id="tab3" class="tab--content">
content tab 3
</div>
</div>
<script>
var referrer = document.referrer;
//alert(referrer);
if(referrer === "page1.html"){
tabs('tab2');
var supporItemsCard = document.getElementsByClassName('support--items__card');
supporItemsCard[0].removeAttribute("id");
supporItemsCard[1].setAttribute("id", "default");
}
//codes of javascript for page: 2
function tabs(name){
var tab_btn = document.getElementsByClassName('tab--btn');
var tab_content = document.getElementsByClassName('tab--content');
var supporItemsCard = document.querySelector('.support--items__card');
var i;
for( i = 0 ; i<tab_btn.length ; i++){
tab_btn[i].classList.remove('active');
}
for(i = 0 ; i<tab_content.length ; i++){
tab_content[i].style.display = 'none';
}
document.getElementById(name).style.display = 'block';
document.getElementById(name).classList.add('active');
}
</script>

dynamic change of the displayed HTML div class.

My html file looks like this:
<div class="nav">
<ul>
<li>
Home
</li>
<li>
Work
</li>
</ul>
</div>
<div id="Home">
<p>My content one</p>
</div>
<div id="Work">
<p>My content two</p>
</div>
And I want always to display only one div id on my page.
If I press 'Home', display div id: Home.
Else I press a Work, display div id: Work.
I would like this change to be dynamic (without reloading the page) because then I want to add transition.
Like i said in my comment to your question i strongly recommend to use something like https://angular.io/guide/quickstart
But if you still want to solve it native you could do the following:
function changeMenuState(state) {
for (var i = 0; i < document.getElementsByClassName('content').length; i++) {
document.getElementsByClassName('content')[i].style.visibility = "hidden"
}
document.getElementById(state).style.visibility = "visible"
}
document.getElementById('link1').addEventListener("click", function() {
changeMenuState('Home')
})
document.getElementById('link2').addEventListener("click", function() {
changeMenuState('Work')
})
https://jsfiddle.net/xcqe323e/

Grabbing parent pages css with postMessage

I have the following JavaScript which lies on a page within an iframe, and grabs the parent pages css to make the page have a seamless look to the rest of the page. I'm having an issue with it picking up the wrong styling however. How can I target specific tags(such as h1, h3`, etc to use on the page within the iframe?
var getFontFamily = function(){
for(var i = 0; i < document.styleSheets.length; i++){
for(var j = 0; j < document.styleSheets[i].rules.length; j++){
if(document.styleSheets[i].rules[j].style.fontFamily){
return document.styleSheets[i].rules[j].style.fontFamily;
}
}
}
return 'not-found';
};
window.addEventListener('load', function(){
var data = getFontFamily();
window.frames[0].postMessage(data, 'http://localhost:3000');
console.log('Message sent -->');
});
Current version: jsfiddle
This is the HTML that the css of the parent page needs to be applied to:
<div class="info">
<div class="lead">Message Lead</div>
<h2>Title</h2>
<div class="ticker">
<div class="ticker__also">Also</div>
<ul class="ticker__list">
<li>sub headline</li>
<li>sub headline</li>
<li>sub headline</li>
</ul>
</div>
</div>
<div class="extras">
<div class="title">Extra info</div>
<a class="link" href="http://www.url.tv" target="_blank">Link</a>
<div class="share">
<a class="twitter">Twitter</a>
<a class="facebook">Facebook</a>
<a class="email">E-mail</a>
</div>
</div>
You can get styles from elements directly via the style attribute and the window.getComputedStyle method. This is more accurate than just taking the first result that appears in the list of CSS rules (where you also just find selectors, not actual elements the style is applied to).
The MDN page about the style attribute has some easy examples, for your purpose, it could be look like this.
var getFontFamily = function() {
var el = document.getElementById(id);
var cs = window.getComputedStyle(el, null);
return cs.fontFamily || '';
}

Change div content by clicking on a button - without jQuery, please

There is an i button in the middle of my website. I'd ask you to click it—you would see a button—contact.
When the user clicks on it, I want the content of the div above to be changed.
This is the code:
<section id="about" class="wrapper about accelerate hide">
<div class="cell accelerate">
<div class="cables center accelerate">
<div class="panel accelerate">
<header>
<h1>gog<em>sem</em>cel</h1>
</header>
<p><strong>gogsemcel </strong>is a trademark of <i font-family="Trebuchet MS">Company</i>.</p>
<p>This project is a collaboration between<br>Company name & gogsemcels.</p>
<ul class="links">
<li><a class="download" href="info/info.html">More Info</a></li>
<li><a class="github" target="_blank" href="contact.html">Contact</a></li>
</ul>
</div>
</div>
</div>
</section>
The button's class is github.
Any suggestions?
Gigantic thanks.
I see you have jQuery on your page so you could use this:
$('#about a.github').on('click', function(e){
e.preventDefault();
var content = $(this).closest('.panel').find('p');
content[0].innerHTML = 'This is a new text!'
content[1].innerHTML = 'This is the second line!'
});
Example
I am not a fan of disabling right-click. Just FYI I can see the whole content anyway...
If you want to do it with vanilla JS you can use this (credits do Chris's nice function):
function collectionHas(a, b) { //helper function (see below)
for (var i = 0, len = a.length; i < len; i++) {
if (a[i] == b) return true;
}
return false;
}
function findParentBySelector(elm, selector) {
var all = document.querySelectorAll(selector);
var cur = elm.parentNode;
while (cur && !collectionHas(all, cur)) { //keep going up until you find a match
cur = cur.parentNode; //go up
}
return cur; //will return null if not found
}
var git = document.querySelector('#about a.github');
git.addEventListener('click', function (e) {
e.preventDefault();
var content = findParentBySelector(git, '.panel').querySelectorAll('p');
content[0].innerHTML = 'This is a new text!'
content[1].innerHTML = 'This is the second line!'
});
Example
You should add href attribute to Contact link.
<a class="github" target="_blank" href="#contact">Contact</a>
Then, add id attribute to 2 p elements for easily selecting.
<section id="about" class="wrapper about accelerate hide">
<div class="cell accelerate">
<div class="cables center accelerate">
<div class="panel accelerate">
<header>
<h1>viva<em>stem</em>cell</h1>
</header>
<p id="abc"><strong>vivastemcell </strong>is a trademark of <i font-family="Trebuchet MS">Tsovn Tsirani Company</i>.</p>
<p id="def">This project is a collaboration between<br>Tsovn Tsirani & vivastemcells.</p>
<ul class="links">
<li><a class="download" href="info/info.html">More Info</a></li>
<li><a class="github" target="_blank" href="contact.html">Contact</a></li>
</ul>
</div>
</div>
</div>
</section>
Now, in onload event of your page, add following code. This use pure Javascript that you want.
// You can use document.querySelector -> returns the first element found.
var gh = document.querySelectorAll('#about .github')[0];
if (gh) {
gh.addEventListener('click', function (e) {
e.preventDefault();
document.getElementById('abc').textContent = new Date().getTime();
document.getElementById('def').textContent = new Date().getTime();
})
}

Categories

Resources