How to set a smooth scrolling to my JS navigation bar? - javascript

I have coded a nav bar using JS, I need to add a smooth scroll active when a user clicks on one of the section written in pure JS (and not CSS's smooth scrolling)
I was thinking something with scrollIntoView or scrollTo but each time I code it it either makes the navbar disappear or not work at all.
Here's my navbar code. Any help is appreciaited.
function navBar() {
const section = document.getElementsByTagName('section');
for (let i = 0; i < section.length; i++) {
let navBarUL = document.getElementById("navBarULID");
let link = `<a href='#' onclick="console.log(${i})" id='link_no${i+1}'> Section ${i+1} </a>`;
let newLI = document.createElement("li")
newLI.innerHTML = link
navBarUL.appendChild(newLI)
let j = i
}
for (let i = 0; i < section.length; i++) {
document.getElementById( 'link_no' + (i + 1)).addEventListener('click', function(e) {
e.preventDefault();
let allActiveLinks = document.getElementsByClassName('active-link');
for (let i = 0; i < allActiveLinks.length; i++) {
const element = allActiveLinks[i];
element.classList.remove('active-link');
}
Here's an HTML sample
<ul id="navBarULID"></ul>
</nav>
</header>
<main>
<header class="main__hero">
<h1 id="p1">Landing Page </h1>
</header>
<section id="section1" class="your-active-class">
<div class="landing__container">
<h2 id="section1ID">Section 1</h2>
<p>test.</p>
</div>
</section>
<section id="section2" >
<div class="landing__container">
<h2 id="section2ID">Section 2</h2>
<p>test.</p>
</div>
</section>
<section id="section3" >
<div class="landing__container">
<h2 id="section3ID">Section 3</h2>
<p>test.</p>
</div>
</section>

use this CSS code
html { scroll-behavior: smooth; }

Related

How to hide DIV's parent in JS with a specific content

I'm trying to hide a DIV's parent when a certain DIV contains a specific text.
An example. This DIV I want to stay:
<div class="report-per-day">
<div class="report-day">26 May 2022</div>
<div class="status-report-rows">
<p class="report__headline">This is our report</p>
</div>
</div>
</div>
But I want to hide this whole DIV, because there's a DIV .mt-2, which contains "No new incident."
<div class="report-per-day">
<div class="report-day">25 May 2022</div>
<div class="mt-2" style="display: none;">
<small class="text-muted">No new incident.</small>
</div>
</div>
</div>
I have this Java Script, but it only hides the .mt-2. I'd also like to hide its 2 parents, .report-per-day and .report-day
Do you guys happen to have any suggestions? Thanks a lot!
const divs = document.getElementsByClassName('mt-2');
for (let x = 0; x < divs.length; x++) {
const div = divs[x];
const content = div.textContent.trim();
if (content == 'No incidents reported.') {
div.style.display = 'none';
}
}
Loop the parent div you want to hide instead of mt-2 and check the content of mt-2 inside the loop. Try:
const divs = document.getElementsByClassName('report-per-day'); // report-per-day instead of mt-2
for (let x = 0; x < divs.length; x++) {
const div = divs[x].querySelector('.mt-2'); // add a selector for .mt-2
const content = div.textContent.trim();
if (content == 'No incidents reported.') {
div.style.display = 'none';
}
}
You can use parentElement
const divs = document.getElementsByClassName('mt-2');
for (let x = 0; x < divs.length; x++) {
const div = divs[x];
const content = div.textContent.trim();
if (content === 'No new incident.') {
div.parentElement.style.display = 'none';
}
}
<div class="report-per-day">
<div class="report-day">26 May 2022</div>
<div class="status-report-rows">
<p class="report__headline">This is our report</p>
</div>
</div>
<div class="report-per-day">
<div class="report-day">25 May 2022</div>
<div class="mt-2">
<small class="text-muted">No new incident.</small>
</div>
</div>

Get Element and append multiple times Javascript

I need to get an element and append it multiple times inside its parent.
HTML
<main>
<div class="wrapper">
<img src="https://placeimg.com/300/300/arch?t=1493746896324/" />
<div class="cover"></div>
</div>
</main>
JS
const main = document.querySelector("main");
const wrapper = document.querySelector(".wrapper");
for (let index = 0; index < 10; index++) {
main.innerHTML += wrapper;
}
RESULT
[object HTMLDivElement] is inserted instead.
Cloning a Node
ParentNode.append()
Node.cloneNode()
const main = document.querySelector("main");
const wrapper = document.querySelector(".wrapper");
for (let index = 0; index < 10; index++) {
main.append(wrapper.cloneNode(true));
}
<main>
<div class="wrapper">
<img src="https://placeimg.com/300/300/arch?t=1493746896324/" />
<div class="cover"></div>
</div>
</main>
Concatenate using outerHTML
Otherwise, given innerHTML and manipulating Strings you could do:
Element.innerHTML
Element.outerHTML
const main = document.querySelector("main");
const wrapper = document.querySelector(".wrapper");
for (let index = 0; index < 10; index++) {
main.innerHTML += wrapper.outerHTML;
}
<main>
<div class="wrapper">
<img src="https://placeimg.com/300/300/arch?t=1493746896324/" />
<div class="cover"></div>
</div>
</main>
Pros Cons
Both the above results will end up in the same markup
<main>
<div class="wrapper">...</div>
......
<div class="wrapper">...</div>
</main>
with the only difference that by using cloning with true, every originally assigned listeners or data will be cloned as well;
whilst using concatenation += with .outerHTML() is basically a simple HTML markup concatenation with not much other benefits.

Javascript scroll to element

I am trying to make a little slide menu. Each slide is 100vh and I want to scroll to each slide with my menu.
I did the query and the listeners and now I try to make each click go to the right #slide.
The number of slides will be dynamic.
I am not a javascript superhero so I hope I started all good !
Thanks in advance for your help and advices.
let sections= document.querySelectorAll('.slide')
let nbrMenuLinks = sections.length;
for(i = 0; i < nbrMenuLinks; i++) {
const li = document.createElement('li');
li.className = 'scroll-item';
li.id = 'btn'+(i+1);
li.appendChild(document.createTextNode((i+1)));
document.querySelector('#slide-menu').appendChild(li);
li.addEventListener('click', ()=> {
window.scroll(0,findPos(document.getElementById(`slide3`)));
});
}
function findPos(obj) {
var curtop = 0;
if (obj.offsetParent) {
do {
curtop += obj.offsetTop;
} while (obj = obj.offsetParent);
return [curtop];
}
}
<ul id="slide-menu"></ul>
<div id="slide1" class="slide">
<h2>Slide 1</h2>
</div>
<div id="slide2" class="slide">
<h2>Slide 2</h2>
</div>
<div id="slide3" class="slide">
<h2>Slide 3</h2>
</div>
<div id="slide4" class="slide">
<h2>Slide 4</h2>
</div>
Thanks, now it works, I just need to access to the ID of the slide dynamically...

select elements by class that have a specific child element with javascript

I have a product list that is structured like the below HTML.
I am trying to select the elements with the class="www-components-menu-product-list--item_DgfZL" that contain the elements with the class name class="www-components-product-card--cbd_2luC9".
Then I want to hide those elements in a click function.
Please note. I have a lot of these items on the page, the function should apply to all the potential elements not just the two I have in the example.
I already understand how to do this with Jquery, but I am trying to avoid Jquery here.
This my attempt with javascript.
var itemClass = document.getElementsByClassName("www-components-menu-product-list--item_DgfZL");
for (i = 0; i < itemClass.length; i++) {
var insideItemClass = itemClass.getElementsByClassName("www-components-product-card--hybrid_2AD7v");
for (i = 0; i < insideItemClass.length; i++) {
insideItemClass.style.display = "none";
}
}
HTML Structure:
<div class="www-components-menu-product-list--item_DgfZL">
<div class="www-components-product-card--card_2mjWk">
<div>
<div class="www-components-product-card--hybrid_2AD7v www-components-product-card--backdrop_Nq0th" style="opacity: 1; transform: translateY(62%);">
</div>
<div class="www-components-product-card--description_3un8n" style="height: 38%;">
</div>
</div>
</div>
</div>
<div class="www-components-menu-product-list--item_DgfZL">
<div class="www-components-product-card--card_2mjWk">
<div>
<div class="www-components-product-card--cbd_2luC9 www-components-product-card--backdrop_Nq0th" style="opacity: 1; transform: translateY(62%);">
</div>
<div class="www-components-product-card--description_3un8n" style="height: 38%;">
</div>
</div>
</div>
</div>
<div class="www-components-menu-product-list--item_DgfZL">
<div class="www-components-product-card--card_2mjWk">
<div>
<div class="www-components-product-card--cbd_2luC9 www-components-product-card--backdrop_Nq0th" style="opacity: 1; transform: translateY(62%);">
</div>
<div class="www-components-product-card--description_3un8n" style="height: 38%;">
</div>
</div>
</div>
</div>
MY ERROR
01:26:25.549 menubest.html:2923 Uncaught TypeError: itemClass.getElementsByClassName is not a function
at HTMLDivElement.<anonymous> (menubest.html:2923)
use this:
itemClass[i].getElementsByClassName
insideItemClass[i].style.display = "none";
instead of
itemClass.getElementsByClassName
insideItemClass.style.display = "none";
Full code:
var itemClass = document.getElementsByClassName("www-components-menu-product-list--item_DgfZL");
for (i = 0; i < itemClass.length; i++) {
var insideItemClass = itemClass[i].getElementsByClassName("www-components-product-card--hybrid_2AD7v");
if(insideItemClass.length > 0){
itemClass.item(i).style.display = "none";
}
}
Here is the fiddle: https://jsfiddle.net/jeL0fezh/8/

toggle div while hiding other divs

I have a side nav on the left hand side with different types of surgeries. They are all in an ul.
When you click on a surgery (ul li), a div will show up on the right hand side, displaying FAQ's for that specific surgery. Clicking on another link in the ul will hide the currently open div and display the one you've just clicked on.
I've managed to do this, but I would also like to toggle the visibility of the FAQ div when I click the same ul li link again.
<html>
<head>
<style>
#popup div { display:none; }
#popup div.show { display:block; }
ul#links li { cursor:pointer;}
</style>
</head>
<body>
<div class="sidenav">
<ul id="links">
<li id="armlift">Arm Lift</li>
<li id="liposuction">Liposuction</li>
<li id="tummytuck">Tummy Tuck</li>
<li id="postgastric">Post-Gastric Bypass Surgery</li>
</ul>
</div>
<div id="popup">
<div id="a_armlift">
<span class="faq_header">Arm Lift</span>
<p class="treatment_question">What is a an Arm Lift?</p>
<div class="treatment_answer">This surgery removes excess...</div>
<p class="treatment_question">What should I know?</p>
<div class="treatment_answer">An incision is made...</div>
</div>
<div id="a_liposuction">
<span class="faq_header">Liposuction Lift</span>
<p class="treatment_question">What is a Liposuction?</p>
<div class="treatment_answer">Liposuction is the removal...</div>
<p class="treatment_question">What should I know?</p>
<div class="treatment_answer">Ideal candidates for...</div>
</div>
<div id="a_tummytuck">
<span class="faq_header">Tummy Tuck</span>
<p class="treatment_question">What is a Tummy Tuck?</p>
<div class="treatment_answer">A tummy tuck tightens...</div>
<p class="treatment_question">What is a Mini Tummy Tuck?</p>
<div class="treatment_answer">A mini-tuck is a...</div>
</div>
<div id="a_postgastric">
<span class="faq_header">Post-Gastric Bypass Surgery</span>
<p class="treatment_question">What is a Post-Gastric Bypass Surgery?</p>
<div class="treatment_answer">Gastric bypass surgery removes...</div>
<p class="treatment_question">What should I know?</p>
<div class="treatment_answer">Each patient has...</div>
</div>
</div>
<script type="text/javascript">
var links_ul = document.getElementById('links');
for (var i = 0; i < links_ul.children.length; i++) {
links_ul.children[i].onclick = function(ev) {
s = document.getElementById('a_' + this.id);
popup = document.getElementsByClassName('show');
for (var j = 0; j < popup.length; j++) {
popup[j].className = '';
}
s.className = 'show';
};
}
</script>
</body>
</html>
I would recommend looking into doing this differently. There are many plugins available that do this sort of thing.
But, here's the answer to your question: http://jsfiddle.net/6Vku8/1/
for (var i = 0; i < links_ul.children.length; i++) {
links_ul.children[i].onclick = function(ev) {
s = document.getElementById('a_' + this.id);
popup = document.getElementsByClassName('show');
var shown = s.className == 'show';
for (var j = 0; j < popup.length; j++) {
popup[j].className = '';
}
s.className = shown ? '' : 'show';
};
}​
You need to find out whether or not the div is "shown" before hiding all of the divs.

Categories