I would like to create a curriculum presentation by Java Script similar to the one on Udemy.
https://prnt.sc/22zxxrp
I have tried to put both button and content in the same div and to add an event listener which would on click trigger conditional check if both of the elements are of the same parent and if true to display the content.
But it does not work.
The code would be something like this but with more buttons.
let batonceros = document.getElementsByClassName("batno");
let paragraph = document.getElementsByClassName("para");
batonceros.addEventListener("click", function() {
if( batonceros != paragraph && batonceros.parentNode == paragraph.parentNode) {
batonceros.style.display = "block";
}
else {
batonceros.style.display = "none";
}
});
Not exactly sure what you're trying to accomplish, but maybe this might help. It shows how to reference the parent container to find the relative .para from its .batno
let batonceros = document.querySelectorAll(".batno");
let paragraph = document.querySelectorAll(".para");
batonceros.forEach(button => button.addEventListener("click", e => {
e.target.closest('div').querySelector('.para').classList.toggle('show');
}));
.para {
display: none;
}
.show {
display: block;
}
<div>
<p class='para'>This is a paragraph</p>
<button class='batno'>Button</button>
</div>
<div>
<p class='para'>This is a paragraph</p>
<button class='batno'>Button</button>
</div>
To debug, try to see if it works without checking the parent. Also, no need to check to see if the button equals the paragraph. Also, you are changing the button style, not the paragraph style.
batonceros.addEventListener("click", function() {
paragraph.style.display = "block";
}
If this does cause the paragraph to display, your problem may in your element structure.
Related
I have this JS function that is supposed to initially hide a that has the class name "tw" and when clicked on a button it should make it visible. However, whenever I click the button it only changes the visibility of one div. I have 4. How can I fix this?
function myFunction(){
var elms = document.getElementsByClassName("tw");
Array.from(elms).forEach((x) => {
if (x.style.display === "block") {
x.style.display = "none";
} else {
x.style.display = "block";
}
})
}
https://jsfiddle.net/qm8bxryh/307/
Here's the fiddle
I copied your code into the context of a very simple page (see below) and it seems to work...I might have missed something, but could the issue be elsewhere in your project? Perhaps investigating it piece by piece in the browser console could help.
<!DOCTYPE html>
<html>
<script>
function myFunction(){
var elms = document.getElementsByClassName("tw");
Array.from(elms).forEach((x) => {
if (x.style.display === "block") {
x.style.display = "none";
} else {
x.style.display = "block";
}
})
}
</script>
<body>
<button onclick="myFunction()">Click me</button>
<div class="tw">1</div>
<div class="tw" style="display: block;">2</div>
<div class="tw">3</div>
<div class="tw" style="display: block;">4</div>
</body>
</html>
There is no display value set as default, so when you try to access it on an element where you never used display in css or style it returns undefined or nothing
Thats why on the first button click nothing happens if no element has any display, then due to your function all of them get through the else display: block and on the second click the all toggle
What i like to do is creating a class like displayNone
so in css:
.displayNone{
display:none;
}
then whenever you wanna make an element invisible give it this class and then when you click the button just remove the class and all elements become visible
so like this in your function:
function myFunction() {
var elms = document.getElementsByClassName("tw");
console.log(elms);
console.log(Array.from(elms));
Array.from(elms).forEach((x) => x.classList.remove('displayNone')); // just remove the class
}
alternatively you can also use the classList.toggle('displayNone) so it switches between display none and its inital display
I would keep styling in the CSS realm and toggle a class in JS to display the element. Also when you return a nodeList using querySelectorAll() it is in array form already.
Add a css class to the CSS:
.display {
display: block;
}
Then your JS function could be a lot more streamlined with toggle()
let elms = document.querySelectorAll(".tw");
function myFunction() {
elms.forEach(el => el.classList.toggle('display'))
}
JSFiddle
I'm finishing my website and I have a script which is hiding or showing a div when a button is pressed.
Here is code :
function display(id) {
var e = document.getElementById(id);
if (e.style.display === "none") {
e.style.display = "block";
} else {
e.style.display = "none";
}
}
But this code is not truly what I'd like because I only want that one div can be displayed at the same time (ex : if div 4 is active and the user need to see the div 2, it has to hide the first one). I have just used JS for quick things therefore I don't have any idea how to do this.
Also would it be possible to hide a specific div depending from which link the user comes on the page.
Exemple of my html :
<a onclick="display('1_1_1')">button</a>
<div id="1_1_1" class="well" style="display: none;">
<h1>Title</h1>
</div>
Thank you for your help !
It is better to add a class which contains display: none like
.no-display {
display: none;
}
then just add or remove that class when you click on a div like
parentDiv.addEventListener("click", function() {
const elem = getElemenyById("elemID");
if(something) {
elem.classList.add("no-display");
else if(something) {
elem.classList.remove("no-display");
};
});
You can create a class with display property and you can add it using Jquery.
CSS:
.display_none_class {
display: none;
}
Jquery:
<script>
$( "#element_ID" ).addClass( "display_none_class" );
</script>
But this sometimes has aligning issues. So, you can use CSS as:
.display_none_class {
width:0;
visibility: none;
}
You can implement this by toggle class:
$("#button_ID").click(function(){
$("#element1_id").toggleClass("display_none_class");
$("#element2_id").toggleClass("display_none_class");
});
First, add this class to the element which you want to hide first. Then On clicking button, it will toggle the class and will make one element visible and other hide.
First add this
I'm making something for my own use that will allow me to quickly and easily stack commands (for Minecraft command block creations).
I have already created a button to create new textareas and a button to delete them. Presuming that there will be several textareas created, how could I delete a specific textbox in the middle of all of them (with the button to delete them)?
I have a div element to act as the parent, and actually was able to successfully delete the textareas AND buttons. My problem is after deleting even just one, I wasn't able to create more. And I noticed the text in the boxes would shift to the left.
The function :
function removeBox() {
var div = document.getElementById("newText");
var cats = document.getElementsByClassName("tAC");
var catss = document.getElementsByClassName("tACB");
div.removeChild(cats[0]);
div.removeChild(catss[0]);
}
Don't judge me because I named the variables cats!
The div :
<div id="newText">
<textarea class="tAC" id="firstText"></textarea>
<p></p>
</div>
Any ideas?
With what you have posted, I am suggesting this.
Whenever a new textarea is created, create a new button within the div that holds the textarea. This way when the remove button is clicked, you can use event.target to get the button element which dispatched the event and from there you can use event.target.previousSibling to find the textarea and remove it from the DOM by calling removeChild on event.target.parentNode. I am not sure if this is what you expect, so I didn't share code.
This is an example:
HTML:
<div id="container"></div>
JS:
var cont = document.getElementById("container");
cont.innerHTML += "<button id='b12' onclick='deleteMe("+'"b12"'+")'>b1b</button>"+
"<button id='b22' onclick='deleteMe("+'"b22"'+")'>b2b</button>"+
"<button id='b32' onclick='deleteMe("+'"b32"'+")'>b3b</button>";
window.deleteMe = function (elementId){
console.log("Borrando:", elementId );
document.getElementById(elementId).remove();
};
this is how it looks: fiddle
The idea is to be able to identify the element, that is why setting an id for the elements you need to manipulate is very helpful. Hope it inspire you.
I just tried your setup and it seems to be working fine:
function removeBox() {
var div = document.getElementById('new-text');
var cats = document.getElementsByClassName("tAC");
var catss = document.getElementsByClassName("tACB");
var cats0 = cats[0];
var catss0 = catss[0];
div.removeChild(cats0);
div.removeChild(catss0);
}
var button = document.getElementsByTagName('button')[0]
button.addEventListener('click',removeBox,false);
#new-text {
width: 200px;
}
#new-text p {
display: inline-block;
width: 100px;
}
#new-text .tAC {
float: left;
}
#new-text .tACB {
float: right;
}
button {
clear: both;
}
<div id="new-text">
<p class="tAC">cats0</p>
<p class="tACB">catss0</p>
<p class="tAC">cats1</p>
<p class="tACB">catss1</p>
<p class="tAC">cats2</p>
<p class="tACB">catss2</p>
</div>
<button type="button" />Click Me</button>
I am trying to make webpage where there is a div in the center which is being changed, instead of going to different pages.
Ultimately, I would like to have the new div, when clicking on an arrow, to flow from right or left in to the center. But first I would like to make the divs appear and disappear when clicking on the arrows but unfortunately this doesn't work.
This is my javascript:
<script>
function changeToHome() {
document.getElementById("mainmain").style.display="block";
document.getElementById("mainmain2").style.display="none";
document.getElementById("mainmain3").style.display="none";
document.getElementById("mainmain4").style.display="none";
}
function changeToStudy() {
document.getElementById("mainmain").style.display="none";
document.getElementById("mainmain2").style.display="block";
document.getElementById("mainmain3").style.display="none";
document.getElementById("mainmain4").style.display="none";
}
function changeToJob() {
document.getElementById("mainmain").style.display="none";
document.getElementById("mainmain2").style.display="none";
document.getElementById("mainmain3").style.display="block";
document.getElementById("mainmain4").style.display="none";
}
function changeToContact() {
document.getElementById("mainmain").style.display="none";
document.getElementById("mainmain2").style.display="none";
document.getElementById("mainmain3").style.display="none";
document.getElementById("mainmain4").style.display="block";
}
function changePageRight() {
var displayValue5 = document.getElementById('mainmain').style.display;
var displayValue5 = document.getElementById('mainmain2').style.display;
var displayValue6 = document.getElementById('mainmain3').style.display;
var displayValue7 = document.getElementById('mainmain4').style.display;
if (document.getElementById('mainmain').style.display == "block") {
document.getElementById("mainmain").style.display="none";
document.getElementById("mainmain2").style.display="block";
}
else if (document.getElementById('mainmain2').style.display == "block") {
document.getElementById("mainmain2").style.display="none";
document.getElementById("mainmain3").style.display="block";
}
else if (document.getElementById('mainmain3').style.display == "block") {
document.getElementById("mainmain3").style.display="none";
document.getElementById("mainmain4").style.display="block";
}
else if (displayValue8 == block) {}
}
function changePageLeft() {
var displayValue = document.getElementById('mainmain').style.display;
var displayValue2 = document.getElementById('mainmain2').style.display;
var displayValue3 = document.getElementById('mainmain3').style.display;
var displayValue4 = document.getElementById('mainmain4').style.display;
if (displayValue == "block") { }
else if (displayValue2 == "block") {
document.getElementById("mainmain").style.display="block";
document.getElementById("mainmain2").style.display="none";
}
else if (displayValue3 == "block") {
document.getElementById("mainmain2").style.display="block";
document.getElementById("mainmain3").style.display="none";
}
else if (displayValue4 === "block") {
document.getElementById("mainmain3").style.display="block";
document.getElementById("mainmain4").style.display="none";
}
}
</script>
Now I have a few divs that look like this:
<div id="mainmain4">
<img style="width:400px;height:327px;margin-left:auto;margin-right:auto;display:block;" src="Untitled-22.png" />
<h2> My name </h2>
<p>Hi,</p>
<p>Some text</p>
</div>
With these css atributes:
#mainmain {
float: left;
width: 575px;
display: block;
position: relative;
}
And all other divs with display: none; so I can change this to block and the one that was block to none.
For some reason, after when I click on one button of the menu, which activates a changeToX() function, the arrows work great. But before that, when you first go to the website, it doesn't.
Can someone explain me what I do wrong?
You don't tell the browser which divs shall be displayed on load. You can use theonloadevent for this:
<body onload="changeToHome()">
One additional hint: you maybe don't want to use inline JavaScript and CSS.
jQuery is as this simple:
<script src="//code.jquery.com/jquery-1.11.0.min.js"></script>
toggle!
<div id="mainmain">test text</div>
<script>
// you need this, only apply javascript when all html (dom) is loaded:
$(document).ready(function() {
$('.toggle-container').on('click', function(e) {
e.preventDefault(); // this prevents the real href to '#'
// .toggle() is like "on / off" switch for hiding and showing a container
$($(this).data('container')).toggle();
});
});
</script>
This function can be reused, because it is based on classes instead of id's.
Check this JSFiddle: http://jsfiddle.net/r8L6xg15/
Maybe this is of some use. I've tried to make a page control-like behaviour. You can select any container div and put elements in there that have the class 'page'. The JavaScript code will let you navigate those with buttons.
You can make it more fancy by adding the buttons through JavaScript. What you then have is basically a list of pages which are normally displayed as regular divs, but when the script kicks in, it changes them to a page control.
You can call this for any parent element, and in that sense it behaves a bit like a jQuery plugin. It is all native JavaScript, though. And not too much code, I hope. Like you said, I think it's good to learn JavaScript at first. It is very powerful by itself, and it's becoming increasingly powerful. jQuery adds a lot of convenience functions and provides fallbacks in case browser don't support certain features, or when implementations differ. But for many tasks, bare JavaScript will do just fine, and it certainly can't hurt to know your way around it.
Press the 'Run this snippet' button at the bottom to see it in action.
function Pages(element)
{
// Some initialization
var activePage;
// Find all pages within this element.
var pages = document.querySelectorAll('.page');
var maxPage = pages.length - 1;
// Function to toggle the active page.
var setPage = function(index)
{
activePage = index;
for (p = 0; p <= maxPage; p++)
{
if (p == activePage)
pages[p].className = 'page active';
else
pages[p].className = 'page inactive';
}
}
// Select the first page by default.
setPage(0);
// Handler for 'previous'
element.querySelector('.prev').onclick = function()
{
if (activePage == 0)
return;
setPage(activePage - 1);
}
// Handler for 'next'
element.querySelector('.next').onclick = function()
{
if (activePage == maxPage)
return;
setPage(activePage + 1);
}
// Add a class to the element itself. This way, you can already change CSS styling
// depending on whether this code is loaded or not. So in case of an error, the
// divs are just all show underneath each other, and the nav buttons are hidden.
element.className = element.className + ' js';
}
Pages(document.querySelector('.pages'));
.pages .page {
display: block;
padding: 40px;
border: 1px solid blue;
}
.pages .page.inactive {
display: none;
}
.pages .nav {
display: none;
}
.pages.js .nav {
display: inline-block;
}
<div class="pages">
<button class="nav prev">Last</button>
<button class="nav next">Next</button>
<div class="page">Page 1 - Introduction and other blah</div>
<div class="page">Page 2 - Who am I? Who are you? Who is Dr Who?</div>
<div class="page">Page 3 - Overview of our products
<ul><li>Foo</li><li>Bar</li><li>Bar Pro</li></ul>
</div>
<div class="page">Page 4 - FAQ</div>
<div class="page">Page 5 - Contact information</div>
</div>
To dos to make this a little more professional:
Add the navigation through JavaScript
Disable the buttons when first/last page has been reached
Support navigation by keys too (or even swipe!)
Some CSS transform (fade or moving) when toggling between pages
Smarter adding and removing of classes. Now I just set className, which sucks if someone would like to add classes themselves. jQuery has addClass and removeClass for this, which is helpful. there are also stand-alone libraries that help you with this.
Visible indication of pages, maybe with tabs at the top?
I have the following working Javascript function:
function collapsible(zap) {
if (document.getElementById) {
var abra = document.getElementById(zap).style;
if (abra.display == "block") {
abra.display = "none";
} else {
abra.display = "block";
}
return false;
} else {
return true;
}
}
When I use the following in html code it displays or hides the "element" div:
<li>Element</li>
Thats working fine. But the problem is, that I want to use the function for multiple links, and then the other elements, that were clicked before, stay, open.
How can I reprogram the code, so that only one div stays open and the other gets closed if i click on another link?
Thanks beforehand!
If you could use jQuery and more importantly jQueryUI accordion I think it would accomplish exactly what you're looking for.
However, without using those two, here is how I would structure it. Like mentioned above, I would use classes to modify the styles of the divs you want shown or hidden. Then the js code can just toggle those classes on each of your elements. The slightly more difficult part (without jquery) is modifying class values since in your final application you may have lots of classes on each div. This is just a very crude example to get you going.
Working JSFiddle Example
Sample DOM
<div >
<li>Element1</li>
<div id='elem1' class='myelem visible'>
Element 1 contents
</div>
</div>
<div >
<li>Element2</li>
<div id='elem2' class='myelem'>
Element 2 contents
</div>
</div>
<div >
<li>Element3</li>
<div id='elem3' class='myelem'>
Element 3 contents
</div>
</div>
Sample JS
window['collapsible'] = function(zap) {
if (document.getElementById)
{
var visDivs = document.getElementsByClassName('visible');
for(var i = 0; i < visDivs.length; i++)
{
visDivs[i].className = visDivs[i].className.replace('visible','');
}
document.getElementById(zap).className += " visible";
return false;
}
else
return true;
}
Sample CSS:
.myelem {
display: none;
}
.visible {
display: block;
}
The way to go is to create a class(or maybe two), like collapsible and active or open that has this style(display: block or none) and then you working adding or removing the class.
The logic would be:
Links that has the class collapsible when clicked would add the active or open class which would give the behavior that remains opens(or active) by css.
If you want to hide others elements you would look for the elements with the class collapsible and then remove the active(or open) class if has any.
Here is my solution: http://jsfiddle.net/g5oc0uoq/
$('.content').hide();
$('.listelement').on('click', function(){
if(!($(this).children('.content').is(':visible'))){
$('.content').slideUp();
$(this).children('.content').slideDown();
} else {
$('.content').slideUp();
}
});
show() and hide() can be used instead of slideUp() and slideDown() if you have performance issues.