Hiding /Showing Div - javascript

I want the (".aboutPage") to show and hide when (".about") is clicked. On start the div is showing. How do I incorporate the hide() with this as it is not hidden once the page loads. Please help. I am aware that the div has not been sized or anything, I'll do that after I get all three working.
.aboutPage {
height: 50px;
width: 50px;
background-color: red;
}
<div class="container">
<h1 class="title">Name Goes Here</h1>
<br>
<div class="menu">
<h1 class="about">About Me</h1>
<h1 class="projects">Projects</h1>
<h1>Contact Me</h1>
</div>
<div class="aboutPage"> Here it Is</div>
</div>

You have to use toggle method in order to display or hide the matched elements.
Also, you need to bind a click event handler to .about element.
To hide div when page loads: $('.aboutPage').hide();
or using css:
.aboutPage{
display:none;
}
$('.aboutPage').hide();
$('.about').click(function(){
$('.aboutPage').toggle();
});
.aboutPage{
height: 50px;
width: 50px;
background-color: red;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<body>
<div class="container">
<h1 class="title">Name Goes Here</h1>
<br>
<div class="menu">
<h1 class="about">About Me</h1>
<h1 class="projects">Projects</h1>
<h1>Contact Me</h1>
</div>
<div class="aboutPage"> Here it Is</div>
</div>
</body>

You can use jQuery to toggle a class that hides the element.
$('.about').on('click',function() {
$('.aboutPage').toggleClass('hide');
})
.hide {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
<h1 class="title">Name Goes Here</h1>
<br>
<div class="menu">
<h1 class="about">About Me</h1>
<h1 class="projects">Projects</h1>
<h1>Contact Me</h1>
</div>
<div class="aboutPage"> Here it Is</div>
</div>
And here's how you would do it in vanilla JS
document.getElementsByClassName('about')[0].addEventListener('click',function() {
document.getElementsByClassName('aboutPage')[0].classList.toggle('hide');
})
.hide {
display: none;
}
<div class="container">
<h1 class="title">Name Goes Here</h1>
<br>
<div class="menu">
<h1 class="about">About Me</h1>
<h1 class="projects">Projects</h1>
<h1>Contact Me</h1>
</div>
<div class="aboutPage"> Here it Is</div>
</div>

You certainly "can" use JQuery to do this, but it is not necessary.
See comments inline for explanation (Note: I've changed the last 3 h1 elements to p elements just so they will fit into the code snippet window here.):
// Get references to DOM objects needed to work the problem:
var a = document.querySelector(".about");
var ap = document.querySelector(".aboutPage");
// Add a "click" event handler to the .about element
a.addEventListener("click", function(){
// If .aboutPage is hidden, show it - otherwise hide it.
// Do this by adding or removing the .hide class.
if(ap.classList.contains("hide")){
ap.classList.remove("hide");
} else {
ap.classList.add("hide");
}
});
.aboutPage{
height: 50px;
width: 50px;
background-color: red;
}
.hide { display:none; }
<div class="container">
<h1 class="title">Name Goes Here</h1>
<div class="menu">
<p class="about">About Me</p>
<p class="projects">Projects</p>
<p>Contact Me</p>
</div>
<div class="aboutPage hide"> Here it Is</div>
</div>

Related

Get next element with class (that's not a child or sibling)

With the press of a button, I want to toggle the class .active on the next div.bottom. These are basically accordions, but with a different structure.
Using nextElementSibling I guess won't work here to select the target element. How would one select such an element, that's neither a child nor a sibling (in plain JS)?
<div class="wrapper">
<div class="top">
<div class="inner">
<div><button></button></div>
</div>
</div>
<div class="bottom"></div>
</div>
<div class="wrapper">
<div class="top">
<div class="inner">
<div><button></button></div>
</div>
</div>
<div class="bottom"></div>
</div>
I'd do it by using closest to go up to the container .wrapper element, then querySelector to find the bottom element:
function onClick(event) {
const wrapper = event.target.closest(".wrapper");
const bottom = wrapper && wrapper.querySelector(".bottom");
if (bottom) {
bottom.classList.toggle("active");
}
}
Live Example:
// I've added event delegation here
document.body.addEventListener("click", function onClick(event) {
const button = event.target.closest(".inner button");
const wrapper = button && button.closest(".wrapper");
const bottom = wrapper && wrapper.querySelector(".bottom");
if (bottom) {
bottom.classList.toggle("active");
}
});
.active {
color: blue;
border: 1px solid black;
}
<div class="wrapper">
<div class="top">
<div class="inner">
<div><button>Button A</button></div>
</div>
</div>
<div class="bottom">Bottom A</div>
</div>
<div class="wrapper">
<div class="top">
<div class="inner">
<div><button>Button B</button></div>
</div>
</div>
<div class="bottom">Bottom B</div>
</div>
Or the same thing using optional chaining (relatively new):
function onClick(event) {
const wrapper = event.target.closest(".wrapper");
const bottom = wrapper?.querySelector(".bottom");
bottom?.classList.toggle("active");
}
Live Example:
// I've added event delegation here
document.body.addEventListener("click", function onClick(event) {
const button = event.target.closest(".inner button");
const wrapper = button?.closest(".wrapper");
const bottom = wrapper?.querySelector(".bottom");
bottom?.classList.toggle("active");
});
.active {
color: blue;
border: 1px solid black;
}
<div class="wrapper">
<div class="top">
<div class="inner">
<div><button>Button A</button></div>
</div>
</div>
<div class="bottom">Bottom A</div>
</div>
<div class="wrapper">
<div class="top">
<div class="inner">
<div><button>Button B</button></div>
</div>
</div>
<div class="bottom">Bottom B</div>
</div>
By using closest() you can traverse the DOM upwards. With this it's easy to just get the relevant .bottom and toggle the active class on this element.
document.querySelectorAll('button').forEach(button => {
button.addEventListener('click', (e) => {
e.currentTarget.closest('.wrapper').querySelector('.bottom').classList.toggle('active');
});
});
.bottom {
display: none
}
.bottom.active {
display: block
}
<div class="wrapper">
<div class="top">
<div class="inner">
<button type="button">Toggle</button>
</div>
</div>
<div class="bottom">Hidden content</div>
</div>
<div class="wrapper">
<div class="top">
<div class="inner">
<button type="button">Toggle 2</button>
</div>
</div>
<div class="bottom">Hidden content 2</div>
</div>

How can I wrap inner divs that are dynamic?

I have been trying badly to wrap some divs with an outer div so that I can style them. But I'm unable to do so thus far.
I have this list div which contains some inner divs that I need to wrap. That is the inner divs which have same letters need to be bundled together. Although targeting the divs with the letters is not a good idea as they are gonna be dynamic.
This is an example of what I have been trying to achieve:
<div class="list-wrapper">
<div class="el">A</div>
<div>
<a>A</a>
</div>
</div>
<div class="list-wrapper">
<div class="el">C</div>
<div>
<a>C</a>
</div>
<div>
<a>C</a>
</div>
</div>
Another example:
This is what I have tried so far:
$(list).find('div.el').each(function(idx, item) {
$(item).nextAll('div').wrapAll('<div class="list-wrapper"></div>')
});
.wrapper {
background-color: red;
padding: 20px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="list">
<div class="el">A</div>
<div>
<a>A</a>
</div>
<div class="el">B</div>
<div>
<a>B</a>
</div>
<div class="el">C</div>
<div>
<a>C</a>
</div>
<div>
<a>C</a>
</div>
<div class="el">D</div>
<div>
<a>D</a>
</div>
<div>
<a>D</a>
</div>
<div>
<a>D</a>
</div>
<div class="el">E</div>
<div>
<a>E</a>
</div>
</div>
To achieve your goal you can use a combination of nextUntil() within the loop, to get the div elements between each .el, and wrapAll(). You can include addBack() in there to add the current .el in the loop in to the collection to be wrapped. Try this:
$('#list').find('.el').each((i, el) => {
$(el).nextUntil('.el').addBack().wrapAll('<div class="list-wrapper"></div>')
});
.wrapper {
background-color: red;
padding: 20px;
}
.list-wrapper { border: 1px solid #C00; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="list">
<div class="el">A</div>
<div><a>A</a></div>
<div class="el">B</div>
<div><a>B</a></div>
<div class="el">C</div>
<div><a>C</a></div>
<div><a>C</a></div>
<div class="el">D</div>
<div><a>D</a></div>
<div><a>D</a></div>
<div><a>D</a></div>
<div class="el">E</div>
<div><a>E</a></div>
</div>
Note that $(list) was only working by proxy, as elements with an id attribute are available as properties on the document. It's much better practice to use a valid string selector.

JS: Hide all elements except of one (by id) (and all of its descending child elements and its parents)

I try to select all elements on a page except of #content_container and all its descendent subelements and all of its parents. Later I want to hide all the selected elements.
However I already fail with this:
var elems = document.querySelectorAll("body *:not(#content_container *)");
Browser console (chrome) returns: Failed to execute 'querySelectorAll' on 'Document': 'body *:not(#content_container *)' is not a valid selector.
Whereas "body *:not(#content_container)" would not return an error.
How can this be accomplished?
note: cant use jQuery.
Edit:
Some of you wanted an example. The goal is to keep #content_container AND its content visible on the site, whereas all the other content will be hidden.
<body>
<div class="hide">
<div class="hide">
</div>
</div>
<div>
<div>
<div class="hide">
<div class="hide">
</div>
</div>
<div id="content_container">
<p> ------- content_container div ------- </p>
<div>
<div>
<div>
</div>
</div>
</div>
<div>
</div>
</div>
</div>
<div class="hide">
</div>
</div>
<div class="hide">
<div class="hide">
<div class="hide">
<div class="hide">
</div>
</div>
</div>
</div>
<div class="hide">
<div class="hide">
</div>
</div>
The only way I can see to do this is to get the subject node, then add all it's siblings to the "don't show" collection, then go up its parent nodes collecting and adding all siblings as you go, stopping at the body.
The following only adds siblings and parent siblings, not the node itself or its immediate ancestors, stopping once the body child nodes are processed. It also only collects element nodes and ignores all others, so empty #text node siblings will still be there, but should not affect the layout. If you want to get rid of those, just delete them.
Click the "Hide stuff" button.
function hideStuff(){
var el = document.querySelector('#content_container');
var node, nodes = [];
do {
var parent = el.parentNode;
// Collect element children
for (var i=0, iLen=parent.childNodes.length; i<iLen; i++) {
node = parent.childNodes[i];
// Collect only sibling nodes that are elements and not the current element
if (node.nodeType == 1 && node != el) {
nodes.push(node);
}
}
// Go up to parent
el = parent;
// Stop when processed the body's child nodes
} while (el.tagName.toLowerCase() != 'body');
// Hide the collected nodes
nodes.forEach(function(node){
node.style.display = 'none';
});
}
<body>
<div class="hide">hide
<div class="hide">hide
</div>
</div>
<div>
<div>
<div class="hide">hide
<div class="hide">hide
</div>
</div>
<div id="content_container">
<p> ------- content_container div ------- </p>
<button onclick="hideStuff()">Hide stuff</button>
<div>don't hide
<div>don't hide
<div>don't hide
</div>
</div>
</div>
<div>don't hide
</div>
</div>
</div>
<div class="hide">hide
</div>
</div>
<div class="hide">hide
<div class="hide">hide
<div class="hide">hide
<div class="hide">hide
</div>
</div>
</div>
</div>
<div class="hide">hide
<div class="hide">hide
</div>
</div>
</body>
This selects then hides everything inside the <body> except #content_container, its children and its parents.
class="hide" is added to the HTML purely to indicate which elements will be hidden, but isn't programmatically useful.
It works by applying the class="hidden" to every element within the <body>, unless it's #content_container or it contains #content_container.
An !important CSS rule then forces the children of #content_container to remain visible.
For demonstration, I have added a 1 second delay before the hiding occurs.
setTimeout( () => { // for demo
document.querySelectorAll( "body *:not( #content_container )" )
.forEach( ( v ) => {
if ( !v.querySelector( "#content_container" ) ) {
v.classList.add( "hidden" );
}
} );
}, 1000 );
body {
padding: .5rem;
background: lightgrey;
}
div {
padding: inherit;
border: 1px solid black;
background: lightblue;
}
#content_container {
background: lightgreen;
visibility: visible !important;
}
/* to hide the children, remove this rule */
#content_container * {
visibility: visible !important;
}
.hidden {
visibility: hidden;
}
<body>
<div>
<div class="hide">
<div class="hide">
<div class="hide">
<div class="hide"></div>
</div>
</div>
</div>
<div>
<div>
<div id="content_container">
<div>
<div>
<div></div>
</div>
</div>
</div>
<div class="hide">
<div class="hide">
<div class="hide">
<div class="hide"></div>
</div>
</div>
</div>
</div>
</div>
</div>
</body>
This solution doesn't maintain the visibility of #content_container's parents.
If #content_container's children should also be hidden, only a minor change to the CSS will fix it.
I have highlighted the CSS that keeps the children visible.
setTimeout( () => { // for demo
document.querySelectorAll( "body *:not( #content_container )" )
.forEach( ( v ) => { v.classList.add( "hidden" ); } );
}, 1000 );
body {
padding: .5rem;
background: lightgrey;
}
div {
padding: inherit;
border: 1px solid black;
background: lightblue;
}
#content_container {
background: lightgreen;
visibility: visible !important;
}
/* to hide the children, remove this rule */
#content_container * {
visibility: visible !important;
}
.hidden {
visibility: hidden;
}
<body>
<div>
<div class="hide">
<div class="hide">
<div class="hide">
<div class="hide"></div>
</div>
</div>
</div>
<div>
<div>
<div id="content_container">
<div>
<div>
<div></div>
</div>
</div>
</div>
<div class="hide">
<div class="hide">
<div class="hide">
<div class="hide"></div>
</div>
</div>
</div>
</div>
</div>
</div>
</body>
A far more efficient and simpler alternative to the previous solution is to hide the <body> (and therefore everything else on the page) whilst forcing the visibility of #content_container and its children.
This is a more direct route, faster to apply and easier to reverse if required; my first solution sets a lot of redundant classes.
setTimeout( () => { // for demo
document.querySelector( "body" ).classList.add( "hidden" );
}, 1000 );
body {
padding: .5rem;
background: lightgrey;
}
div {
padding: inherit;
border: 1px solid black;
background: lightblue;
}
#content_container {
background: lightgreen;
visibility: visible !important;
}
.hidden {
visibility: hidden;
}
<body>
<div>
<div class="hide">
<div class="hide">
<div class="hide">
<div class="hide"></div>
</div>
</div>
</div>
<div>
<div>
<div id="content_container">
<div>
<div>
<div></div>
</div>
</div>
</div>
<div class="hide">
<div class="hide">
<div class="hide">
<div class="hide"></div>
</div>
</div>
</div>
</div>
</div>
</div>
</body>

W3.css Conflicting with JQuery UI Progress Bar

I am at my last straw with this one. I cannot figure this out and it has been three days now of trying. I am using w3.css with jQuery UI and jQuery UI.css.
ISSUE: The progress bars appear but don't fill. When you remove the href to w3.css, the progress bars work just fine. But otherwise, the fill doesn't occur.
FIDDLE: http://jsfiddle.net/kjg95pxq/7/
HTML
<body class="w3-content" style="max-width:1300px">
<!-- ROW 3.1: Skillsets Section -->
<div class="w3-container">
<div class="progressbar w3-center" id="progressbar" data-value="50">
<p style="position:absolute">20%</p>
</div>
</div>
<div class="w3-row" id="rowWaypoint2">
<div class="capsuleBox3 animated" id="capBox3">
<div class="w3-half w3-dark-grey w3-container w3-center" id="contact" style="height:700px">
<div style="padding-top:55px">
<h1>Skillsets</h1>
<p>My current skill progressions</p>
</div>
<!-- Progress Bar for JavaScript/jQuery -->
<div style="padding-top:18px">
<p> Tacos </p>
</div>
<div style="padding-top:0px">
<div class="progressbar w3-center" data-value="40">
<p style="position:absolute">20%</p>
</div>
</div>
<div class="progressbar w3-center" id="progressbar" data-value="80">
<p style="position:absolute">20%</p>
</div>
<div class="progressbar w3-center" data-value="20">
<p style="position:absolute">20%</p>
</div>
</div>
</div>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>
</body>
CSS
.progressbar {
width: 80%;
margin: 20px auto;
}
.ui-progressbar-value {
transition: width 0.5s;
-webkit-transition: width 2s;
}
JS
$(document).ready(function() {
pbRun();
function pbRun() {
$(".progressbar").progressbar();
//this initializes the widget
$(".progressbar").each(function() {
var valPB = parseInt($(this).data('value'));
var percentPB = valPB;
$(this).progressbar("option", "value", percentPB);
});
}
});
Try using:
.ui-progressbar .ui-progressbar-value {
box-sizing: content-box;
}
w3.css adds:
*, *:before, *:after {
box-sizing: inherit;
}
which messes with code.
JSfiddle

How add class to a div after class in jQuery?

I have a child div that needs to be added with a class using jQuery.
<div class="main-content">
<article class="post status-publish">
<div class="post-content>
<div class="vc_row wpb_row vc_row-fluid">
<div class="vc_col-sm-12 wpb_column vc_column_container ">
</div>
</div>
</div>
</article>
</div>
The jQuery code that i tried so far is this:
j('.main-content .post-content').each(function () {
j(this).after().addClass('home-inner-content');
});
This is the result that i am desiring for:
<div class="main-content">
<article class="post status-publish">
<div class="post-content>
<div class="vc_row wpb_row vc_row-fluid home-inner-content">
<div class="vc_col-sm-12 wpb_column vc_column_container ">
</div>
</div>
</div>
</article>
</div>
Any help is appreciated. Thanks
You probably want something like:
j('.main-content .post-content').each(function () {
j(this).children().first().addClass('home-inner-content');
});
.after() is for inserting content, not locating it.
But really, I don't think you need a loop. You can do:
j('.main-content .post-content > *:first-child').addClass('home-inner-content');
The first part selects the elements you want. .addClass() adds a class to each of the elements that got selected.
If I understand you correctly, next code will help.
$('.main-content .post-content>div').addClass('home-inner-content');
$('.main-content .post-content').each(function() {
$(this).children().addClass('home-inner-content');
});
body * {
padding-left: 1em;
}
body *:before {
font-family: monospace;
content: attr(class);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="main-content">
<article class="post status-publish">
<div class="post-content">
<div class="vc_row wpb_row vc_row-fluid">
<div class="vc_col-sm-12 wpb_column vc_column_container">
</div>
</div>
</div>
</article>
</div>
You don't need to use each function here.
j('.main-content .post-content>div').addClass('home-inner-content');

Categories

Resources