Why can't I remove this class with javascript? - javascript

I'm trying to make a skeleton loading screen by having a class 'skeleton' on the elements which styles them then removing it with javascript after a timeout. The issue is that i can't get the javascript to work.
Here's my javascript to remove the class, why isn't it working?
const timeout = setTimeout(loading, 3000);
function loading() {
const element = document.getElementById("skeleton");
element.classList.remove("skeleton");
}

What I think is happening is that you have too many "skeleton" elements with the same id, and ids have to be unique. So remove the ids, and target the classes instead, and use forEach to iterate over each of them to remove the class.
const timeout = setTimeout(loading, 3000);
function loading() {
const skeletons = document.querySelectorAll('.skeleton');
skeletons.forEach(skeleton => {
skeleton.classList.remove('skeleton');
});
}
.skeleton { color: red; }
<div class="skeleton">One</div>
<div class="skeleton">Two</div>
<div class="skeleton">Three</div>
<div class="skeleton">Four</div>

You are calling getElmentById on Class. Can You Share The HTML Elment whose id or class is skeleton
try this
function loading() {
const element = document.getElementsByClassName("skeleton")[0];
element.classList.remove("skeleton");
}

I think the reason behind its not working is that your trying to remove the skeleton class from the skeleton itself. Try targeting the parent Element of the skeleton and then remove the skeleton from the parent Element. Did you try using :
const parentNode=document.querySelector(".parentElem");
parentNode.removeChild(document.querySelector(".skeleton"));
Did you notice you are trying to get an element by using getElementById whereas you stated skeleton is a class.

Related

How can i minimize the code in a class toggler that targets nav?

I love clean code but I'm zero in javascript. I'd love to do two things to the super easy code below:
function nav_open() {
var myNav = document.getElementById('nav_anim');
if (myNav.className == 'nav_closed') {
myNav.className = 'nav_open';
} else {
myNav.className = 'nav_closed';
}
}
Use getElementsByTagName to target the nav instead of giving it a useless id (in order to use only <nav> instead of <nav id="nav_anim"> in the body. I tried some combos but none of them works.
Get rid of that ugly myNav name, is it mandatory? I know I can change it, but can I remove it? Is it possible to use something like
nav.className=='nav_closed' or even better className=='nav_closed' instead of myNav.className=='nav_closed'
I would suggest keeping the id on your nav, targetting your DOM elements using ids or classes is something that is commonly done and can speed up lookup. Using getElementsByTagName() adds unnecessary complexity and would need to traverse your entire DOM to find your element, so it isn't very efficient, espeicially if you just have one nav element. If you really want to, you could use querySelector to select the first nav item:
const myNav = document.querySelector("nav");
At the end of the day though, if you want to interact with elements in your JavaScript code, you'll need to explicitly grab them (not counting named access on the global window object as it is recommended not to use this).
To further improve your toggle code, you could perform two toggles using DOMTokenList.toggle(), one to hide your first class and one to add your other. Every time you run both toggles, they will add/remove both classes depending on whether they exist or not:
const myNav = document.getElementById("nav_anim");
myNav.classList.toggle('nav_closed');
myNav.classList.toggle('nav_open');
See example below:
const btn = document.getElementById("btn");
btn.addEventListener("click", () => {
btn.classList.toggle("on");
btn.classList.toggle("off");
});
.on {
background-color: lightgreen;
}
.off {
background-color: red;
}
<button id="btn" class="on">Click me</button>
Depending on your code, you may even be able to remove the nav_closed class by targeting your nav element that does not have the nav_open class:
#nav_anim:not(.nav_open) {
/* nav_closed styles */
}
With this setup, you can use just one toggle:
const myNav = document.getElementById("nav_anim");
myNav.classList.toggle('nav_open');
See example below:
const btn = document.getElementById("btn");
btn.addEventListener("click", () => {
btn.classList.toggle("on");
});
.on {
background-color: lightgreen;
}
#btn:not(.on) {
background-color: red;
}
<button id="btn" class="on">Click me</button>
You should be able to do this with a conditional (ternary) operator, like so:
var nav = document.getElementsByTagName("nav")[0];
(nav.classList.contains('nav_open')) ? nav.classList.remove('nav_open') : nav.classList.add('nav_open'));
This is like a 1 line if statement with 3 parameters:
condition ? exprIfTrue : exprIfFalse

How to remove active class from other sections

const addActiveClass = () => {
if( isInViewport(section) ) {
section.classList.add('active-section');
// How to remove the 'active-section' from other sections
}
}
}
what is the code should be written to remove active class from other section?
In jQuery this may be easy but what about pure js?
Well, you question is a bit confusing because there is no context.
The simplest approach would be to have an array or a node object with all your sections.
Then loop through theses sections with a for loop to remove the active class from the one you want ?
For example here I have 3 sections.
I want every section to have the section--active class when I click on it.
But I also want that only one at the time can have the section--active class :
<div class="section section--1 section--active"></div>
<div class="section section--2"></div>
<div class="section section--3"></div>
In javascript I will get them in a node object (kind of array) :
const sections = document.querySelectorAll('.section')
Then I can bind click event to each section :
sections.forEach(section => {
section.addEventListener('click', () => {
// I loop again to remove the 'section--active' from all others sections
// To avoid confusion, I use 'el' as a name for each section in sections
sections.forEach(el => el.classList.remove('section--active'))
// Then I add the 'section--active' to the clicked element
section.classList.add('section--active')
})
})
You'll need to first loop over all the elements that have the active-section class with document.querySelectorAll(".active-section") and use classList.remove(). Then, once all elements have had that class removed, add it back to just the current element in question.
Something along these lines:
const addActiveClass = () => {
if( isInViewport(section) ) {
// Loop over all the elements that are active
document.querySelectorAll(".active-section").forEach(function(item){
item.classList.remove('active-section'); // Remove the class
});
// Then add it to the current element
section.classList.add('active-section');
}
}

Javascript Class References in Html

Assuming I have a class class FooBar() {} with a method doSomething(){}, can I create and append a html element from within the class itself that calls doSomething() when clicked?. Here is a code snippet:
class FooBar{
constructor(options){this.options = options}
doSomething(){ /* onclick functionality */}
creator(){
let reference = `<div onclick="this.doSomething()"></div>`;
document.getElementByTagName('body')[0].innerHtml = reference;
}
}
I would now like to know the correct way of writing the let reference . . . line.
First, to attach the event listener you can't use innerHTML because onclick="this.doSomething()" in your string won't point to your class. You have to construct the element using document.createElement and append that using appendChild.
Second, when you attach the event listener, make sure the proper this is used (more on that in this other SO question). We'll just use a simple arrow function. We'll also use addEventListener instead of onclick which is more standard:
class FooBar{
constructor(options) { this.options = options; }
doSomething() { /* onclick functionality */}
creator() {
let div = document.createElement("div");
div.addEventListener("click", ev => this.doSomething( /* pass 'ev' here if you want */ ));
// it's ok to use div.innerHTML here to fill out the div instead of createElement/appendChild
document.body.appendChild(div);
}
}
Maybe try using addEventListener instead of using onclick on the tag
let newElement = document.createElement('div')
newElement.addEventListenser('click', () => console.log('clicked'))

change div with Javascript

With pure Javascript I want to create a tab effect to toggle content in a div. Content is the name of the class I want to add or remove the second class active from
<script>
function changeClass(element) {
if (classList !=='active') {
element.classList.add('active');
}
else { element.classList.remove('active'); }
}
</script>
<ul>
<li onclick = "changeClass("content")">
The error is that you're not selecting any elements (wonder why nobody caught this), but trying to change the classlist of a string ("content".classList...). Make sure you select the proper element first:
function changeClass(element) {
element = document.getElementsByClassName(element)[0]; // assuming here we're selecting the first one
if (!element.classList.contains('active')) { // had to fix this as variable classList wasn't defined
element.classList.add('active');
}
else {
element.classList.remove('active');
}
}
Also, as #Teemu suggested in comments, but refused to write it, feel free to use element.classList.toggle('active');.
So the whole code should be:
function changeClass(element) {
element = document.getElementsByClassName(element)[0]; // assuming here we're selecting the first one
element.classList.toggle('active');
}
If you want to simply toggle between two classes, you can do something like this:
function changeClass(element) {
element.classList.toggle('Content');
}
Though in this case you've to pass a reference to the element rather than it's className.

How to check if an element with id exists or not in jQuery?

I'm generating a div dynamically and I've to check whether a dynamically generated div exists or not ? How can I do that?
Currently I'm using the following which does not detects the div generated dynamically. It only detects if there is already an element with the id contained in the HTML template.
$(function() {
var $mydiv = $("#liveGraph_id");
if ($mydiv.length){
alert("HHH");
}
});
How can I detect the dynamically generated div?
If mutation observes aren't an option due to their browser compatibility, you'll have to involve the code that's actually inserting the <div> into the document.
One options is to use a custom event as a pub/sub.
$(document).on('document_change', function () {
if (document.getElementById('liveGraph_id')) {
// do what you need here
}
});
// without a snippet to go on, assuming `.load()` for an example
$('#container').load('/path/to/content', function () {
$(this).trigger('document_change');
});
If it is added dinamically, you have to test again. Let's say, a click event
$("#element").click(function()
{
if($("#liveGraph_id").length)
alert("HHH");
});
How you inserting your dynamic generated div?
It works if you do it in following way:
var div = document.createElement('div');
div.id = 'liveGraph_id';
div.innerHTML = "i'm dynamic";
document.getElementsByTagName('body')[0].appendChild(div);
if ($(div).length > 0) {
alert('exists'); //will give alert
}
if ($('#liveGraph_id').length > 0) {
alert('exists'); //will give alert
}
if ($('#liveGraph_id_extra').length > 0) {
alert('exists'); //wont give alert because it doesn't exist.
}
jsfiddle.
Just for interest, you can also use a live collection for this (they are provided as part of the DOM). You can setup a collection of all divs in the page (this can be done in the head even before the body is loaded):
var allDivs = document.getElementsByTagName('div');
Any div with an id is available as a named property of the collection, so you can do:
if (allDivs.someId) {
// div with someId exists
}
If the ID isn't a valid identifier, or it's held in a variable, use square bracket notation. Some play code:
<button onclick="
alert(!!allDivs.newDiv);
">Check for div</button>
<button onclick="
var div = document.createElement('div');
div.id = 'newDiv';
document.body.appendChild(div);
">Add div</button>
Click the Check for div button and you'll get false. Add the div by clicking the Add div button and check again—you'll get true.
is very simple as that
if(document.getElementById("idname")){
//div exists
}
or
if(!document.getElementById("idname")){
// don't exists
}

Categories