Below is a snippet of code that gets some elements via the DOM. I just attach a simple onclick which is supposed to add the "hidden" property to the classList of each retrieved element.
HTML:
<body>
<h1 id="view-one-header">Exploring View 1</h1>
<img id ="dragonite" src="https://cdn.bulbagarden.net/upload/8/8b/149Dragonite.png" alt="Dragonite">
<button id="toggle-view-two-btn">Toggle View 2</button>
</body>
Javascript:
window.onload = pageLoad;
function pageLoad() {
let viewOneHeader = document.getElementById("view-one-header");
let dragoniteImg = document.getElementById("dragonite");
let toggleViewTwoBtn = document.getElementById("toggle-view-two-btn");
toggleViewTwoBtn.onclick = changeToViewTwo;
function changeToViewTwo() {
viewOneHeader.classList.add("hidden");
dragoniteImg.classList.add("hidden");
}
I am trying to debug this script because when the button is clicked, the corresponding views do not disappear. It has been awhile and I am unable to figure out the issue. Any help would be appreciated.
Here I have added some css for the class "hidden". When you click on the element with the id "toggle-view-two-btn" the classes are added.
let viewOneHeader = document.getElementById("view-one-header");
let dragoniteImg = document.getElementById("dragonite");
let toggleViewTwoBtn = document.getElementById("toggle-view-two-btn");
toggleViewTwoBtn.onclick = changeToViewTwo;
function changeToViewTwo() {
viewOneHeader.classList.add("hidden");
dragoniteImg.classList.add("hidden");
}
.hidden {
display: none;
}
<div id="view-one-header">view-one-header</div>
<div id="dragonite">dragonite</div>
<div id="toggle-view-two-btn">toggle-view-two-btn</div>
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 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.
I am building a site with a search bar, but there is too much search content and I need a way for people to toggle it being hidden
<div class="search">
<ul>Bash Shell Emulator</ul>
<ul>How to use bash shell </ul>
much more to this. But how can I toggle it being hidden and it being shown with JS and <span>?
Thank you very much,
Ring Games
Hi you can use toggle to add and remove a class, and with the class you can hide the elements inside the search, this is an example:
const searchElement = document.getElementById("search");
const toggleElement = document.getElementById("toggle-visibility");
toggleElement.addEventListener("click", toggleSearchVisibility);
function toggleSearchVisibility() {
searchElement.classList.toggle("hide-element")
}
.hide-element{
display: none;
}
<div id="search">
<ul>Bash Shell Emulator</ul>
<ul>How to use bash shell </ul>
</div>
<span id="toggle-visibility">Click me!</span>
I would strongly suggest you use the JQuery library. Its super easy, all you need to do as add the following script to your <head> tag:
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
</head>
Then it would be simple as:
$("#clickedElementThatWillHide").click(function(){
$("span").hide();
});
For more examples checkout W3Schools
Here is Vanilla Javascript without using big library
<p>
<a class="toggle" href="#example">Toggle Div</a>
</p>
<div id="example">
<ul>Bash Shell Emulator</ul>
<ul>How to use bash shell </ul>
</div>
<script>
var show = function (elem) {
elem.style.display = 'block';
};
var hide = function (elem) {
elem.style.display = 'none';
};
var toggle = function (elem) {
// If the element is visible, hide it
if (window.getComputedStyle(elem).display === 'block') {
hide(elem);
return;
}
// Otherwise, show it
show(elem);
};
// Listen for click events
document.addEventListener('click', function (event) {
// Make sure clicked element is our toggle
if (!event.target.classList.contains('toggle')) return;
// Prevent default link behavior
event.preventDefault();
// Get the content
var content = document.querySelector(event.target.hash);
if (!content) return;
// Toggle the content
toggle(content);
}, false);
</script>
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>
So I have a mini slide menu in my website there is a menu you can choose what you want to read. There are points to click, when u clicked it the point get a red background.
But there is a problem.
When i click one point and then an other point the first clicked point have to lose his background.
Here is my HTML:
<div id="slide_button" onClick="clicked(this);"><dir class="button_1"></dir></div>
<div id="slide_button" onClick="clicked(this);"><dir class="button_2"></dir></div>
<div id="slide_button" onClick="clicked(this);"><dir class="button_3"></dir></div>
<div id="slide_button" onClick="clicked(this);"><dir class="button_4"></dir></div>
<div id="slide_button" onClick="clicked(this);"><dir class="button_5"></dir></div>
Here is my JS:
function clicked(slide_button) {
slide_button.getElementsByTagName("dir")[0].style.backgroundColor="red";
}
HERE IS AN EXAMPLE ON FIDDLE.
My "QUESTION IS" what i have to do to solve that?
What should I pay attention?
First you need to fix your HTML becaue your id values aren't unique. In fact, you don't even need id values, so you should use "slide_button" as a class. You can then use it to select all the buttons:
<div onClick="clicked(this);" class="slide_button"><dir></dir></div>
<div onClick="clicked(this);" class="slide_button"><dir></dir></div>
<div onClick="clicked(this);" class="slide_button"><dir></dir></div>
<div onClick="clicked(this);" class="slide_button"><dir></dir></div>
<div onClick="clicked(this);" class="slide_button"><dir></dir></div>
The CSS needs to be changed now so "slide_button" is a class selector, instead of an id selector:
.slide_button {
display: inline-block;
}
As for clearing the background, clear all of them before coloring the selected one red:
function clicked(slide_button) {
var buttons = document.getElementsByClassName('slide_button');
for(var i = 0; i < buttons.length; i++) {
buttons[i].getElementsByTagName('dir')[0].style.backgroundColor = '';
}
slide_button.getElementsByTagName('dir')[0].style.backgroundColor = 'red';
}
jsfiddle
This uses just JavaScript with no JQuery, but if you are using JQuery, you might as well use it here. The code is a lot shorter and easier to follow.
Here's a JQuery version:
$(function() {
$('.slide_button').click(function() {
var $button = $(this);
$button.children(':first').css({ backgroundColor: 'red' });
$button.siblings().children(':first').css({ backgroundColor: '' });
});
});
Note: This registers a click-handler, so you can get rid of the "onclick" attirbutes.
jsfiddle
You have to select all other points and set their background to none.
Or remeber which point is selected and on select another just remove background on last and remeber current point, then set its background to red.
See fiddle: http://fiddle.jshell.net/399Dm/5/
At first id should be unique per element.
<div class="slide_button"><dir class="button"></dir></div>
<div class="slide_button"><dir class="button"></dir></div>
<div class="slide_button"><dir class="button"></dir></div>
<div class="slide_button"><dir class="button"></dir></div>
<div class="slide_button"><dir class="button"></dir></div>
Second, you should store reference of clicked element if you want later remove background color, and instead of inline event handlers or binding all elements would be better if you use event delegation.
Demonstration
(function () {
"use strict";
// getting parent node of divs, due to bind click event. then
var ele = document.querySelector(".slide_button").parentNode,
prev = null; // store previous clicked element
ele.addEventListener("click", clickHandler); // event handler.
function clickHandler(e) {
var t = e.target; // get target of clicked element
// filter by target node name and class. edit: removed class checking
if (t.nodeName.toLowerCase() === "dir") {
// checking value of prev !== null and it's not same element.
if (prev && prev !== t) {
prev.style.backgroundColor = "";
}
prev = t; // store clicked element
t.style.backgroundColor = "red";
}
}
}());
I have fixed the fiddle so that it works hopefully as you plan.
http://jsfiddle.net/399Dm/8/ There you go!
var forEach = function(ctn, callback){
return Array.prototype.forEach.call(ctn, callback);
}
function clear(element, index, array) {
element.getElementsByTagName("dir")[0].style.backgroundColor="";
}
function clicked(slide_button) {
forEach(document.getElementsByClassName("slide_button"), clear);
//.style.backgroundColor="";
slide_button.getElementsByTagName("dir")[0].style.backgroundColor="red";
}
I had a slightly different method than #atlavis but a similar result.
http://fiddle.jshell.net/2AGJQ/
JSFIDDLE DEMO
jQuery
$('.slide_button').click(function(){
$('.slide_button dir').css("background-color", "inherit");
$(this).find('dir').css("background-color", "red");
});
HTML - Your markup is invalid because you have duplicate ids. Make them classes as below instead.
<div class="slide_button" >
<dir class="button_1"></dir>
</div>
<div class="slide_button">
<dir class="button_2"></dir>
</div>
<div class="slide_button">
<dir class="button_3"></dir>
</div>
<div class="slide_button">
<dir class="button_4"></dir>
</div>
<div class="slide_button">
<dir class="button_5"></dir>
</div>
CSS change
.slide_button {
display: inline-block;
}
If you can look at the following jsfiddle, I used jQuery to get what you want.