Toggle a class on and off between two elements - javascript

I have this html:
<div class="container">
<div id="element-1" class="element-show"></div>
<div id="element-2"></div>
</div>
I want class element-show to hide from element-1 and show in element-2 and vice versa; called from one function in jQuery.
Any way I can do this properly?

will something like that be OK?
$("button").on("click", function(e){
$('.container').children("div").toggleClass("element-show");
})
.element-show{
color:red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
<div id="element-1" class="element-show">x</div>
<div id="element-2">y</div>
</div>
<button>Toggle class</button>

You can achieve that by doing this:
function getClass() {
var children_container = document.getElementsByClassName("container")[0].children;
for (var i = 0; i < children_container.length; i++) {
if ($(children_container[i]).hasClass('element-show')) {
$(children_container[i]).removeClass();
if (i == "0") {
$(children_container[1]).addClass("element-show");
break;
} else if (i == "1") {
$(children_container[0]).addClass("element-show");
break;
}
}
};
};
getClass();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
<div id="element-1" class="element-show"></div>
<div id="element-2"></div>
</div>
If you have more than 2 elements and you want to add the class on rest of them and remove it from the element which already has that class, then you can achieve that by doing this (this function will also work for the case you mentioned too):
function getClass() {
var children_container = document.getElementsByClassName("container")[0].children;
var class_elem;
for (var i = 0; i < children_container.length; i++) {
if ($(children_container[i]).hasClass('element-show')) {
class_elem = i;
$(children_container[i]).removeClass();
i = 0;
}
if (class_elem != undefined) {
if (i != class_elem) {
$(children_container[i]).addClass('element-show');
}
};
};
};
getClass();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
<div id="element-0"></div>
<div id="element-1" class="element-show"></div>
<div id="element-2"></div>
<div id="element-3"></div>
<div id="element-4"></div>
</div>

Related

Add an existing div element with classes (along with its underlying elements) to a div

I need to have a function that would add an existing div with a class (along with its underlying elements) to a particular div using for loop. It looks like this:
<div class="left-col">
<div class="list-row">
<div class="list-row2">
<span>Hello</span>
</div>
</div>
</div>
I need to loop through a function that will produce or duplicate "list-row" twice.
$(function() {
var leftcol = document.getElementsByClassName('left-col');
for (var i = 0; i < 2; i++) {
var listrow = document.querySelector('.list-row');
leftcol.appendChild(listrow[i]);
}
})
It should look like this:
<div class="left-col">
<div class="list-row">
<div class="list-row2">
<span>Hello</span>
</div>
</div>
<div class="list-row">
<div class="list-row2">
<span>Hello</span>
</div>
</div>
<div class="list-row">
<div class="list-row2">
<span>Hello</span>
</div>
</div>
</div>
You can try the following way:
$(function() {
var leftcol = document.querySelector('.left-col');
for (let i = 0; i < 2; i++) {
var listrow = document.querySelector('.list-row').cloneNode();
listrow.textContent = i + 1 + listrow.textContent;
leftcol.appendChild(listrow);
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="left-col">
<div class="list-row">0</div>
</div>
You could use cloneNode and set the deep property to true. This will clone the node and all of its descendants.
For example:
function cloneNode(copies = 1) {
for (let i = 0; i < copies; i++) {
let leftcol = document.getElementsByClassName('left-col')[0];
let nodeToClone = document.querySelector(".list-row");
let clonedNode = nodeToClone.cloneNode(true);
leftcol.appendChild(clonedNode);
}
}
clone.addEventListener("click", function() {
cloneNode();
});
<button id="clone" type="button">Clone Node</button>
<div class="left-col">
<div class="list-row">Test</div>
</div>
If you wanted to insert more than one copy, you could pass a different value to the cloneNode function.
You can use jQuery's .clone() method to copy the entire content of an element to another element. The boolean argument passed to the clone function determines whether the events associated with the cloned element has to be copied or not. true indicates all the events associated with that div has to be copied.
$(function() {
$('.list-row').each(function(){
$(".left-col").append($(this).clone(true));
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.0/jquery.min.js"></script>
<div class="left-col">
<div class="list-row"><h1>This is original row</h1></div>
</div>
$(function() {
var leftcol = document.getElementsByClassName('left-col');
var listrow = document.querySelector('.list-row');
for (var i = 0; i < 2; i++) {
leftcol.appendChild(listrow.clone(true));
}
})

Sort divs by multiple data attributes

How can I sort by both of the data attributes? First I need to sort by discount and then sort by weight.
<div id="list">
<div class="row" data-weight="1" data-discount=0>banana</div>
<div class="row" data-weight="3" data-discount=30>apple</div>
<div class="row" data-weight="4" data-discount=0>avocado</div>
<div class="row" data-weight="8" data-discount=15>milk</div>
</div>
function sortOrder(){
divList.sort(function(a, b){
return $(b).data("order")-$(a).data("order")
});
$(".list").html(divList);
}
Your current sort() logic shows how to do this for a single attribute. For multiple attributes you simply need to amend the logic to cater for cases where the values are the same, which can be seen below.
Note that this logic can be made less verbose, but I left it this way to make the flow more obvious.
var $divList = $('#list .row');
function sortOrder() {
$divList.sort(function(a, b) {
var $a = $(a), $b = $(b);
if ($a.data('discount') < $b.data('discount')) {
return 1;
} else if ($a.data('discount') > $b.data('discount')) {
return -1;
}
if ($a.data('weight') < $b.data('weight')) {
return 1;
} else if ($a.data('weight') > $b.data('weight')) {
return -1;
}
return 0;
});
$("#list").append($divList);
}
sortOrder();
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="list">
<div class="row" data-weight="1" data-discount=0>banana</div>
<div class="row" data-weight="3" data-discount=30>apple</div>
<div class="row" data-weight="4" data-discount=0>avocado</div>
<div class="row" data-weight="8" data-discount=15>milk</div>
</div>

Double onclick events not working

I have a tab menu on my website and the code used for it works perfectly. JavaScript:
function openTab(tabName) {
var i;
var x = document.getElementsByClassName("tab");
for (i = 0; i < x.length; i++) {
x[i].style.display = "none";
}
document.getElementById(tabName).style.display = "flex";
}
HTML:
<div class="col-md-4">
<div onclick="openTab('tab-1')" class="tab-button">
<h5>IT Problems</h5>
</div>
</div>
<div class="col-md-4">
<div onclick="openTab('tab-2')" class="tab-button">
<h5>Save Time</h5>
</div>
</div>
<div class="col-md-4">
<div onclick="openTab('tab-3')" class="tab-button">
<h5>Cost Effective</h5>
</div>
</div>
And then obviously I applied the IDs ("tab-[1/2/3]") and classes ("tab") to the divs I want as tabs. However, when I replicate the exact same code to have a tab button highlighted for the current tab open, it doesn't work. JavaScript:
function selectedTab(selectName) {
var i;
var x = document.getElementsByClassName("select");
for (i = 0; i < x.length; i++) {
x[i].style.border-bottom-color = "#dbdbdb";
}
document.getElementById(selectName).style.border-bottom-color = "#25a7df";
}
HTML:
<div class="col-md-4">
<div onclick="openTab('tab-1'); selectedTab('select-1')" class="tab-button">
<h5 id="select-1" class="select">IT Problems</h5>
</div>
</div>
<div class="col-md-4">
<div onclick="openTab('tab-2'); selectedTab('select-2')" class="tab-button">
<h5 id="select-2" class="select">Save Time</h5>
</div>
</div>
<div class="col-md-4">
<div onclick="openTab('tab-3'); selectedTab('select-3')" class="tab-button">
<h5 id="select-3" class="select">Cost Effective</h5>
</div>
</div>
I've looked literally everywhere online and had multiple people look at this and nobody can find a solution. Can anyone help?
border-bottom-color is not a valid style property, you need to replace hyphen case with camel case
You need to use the borderBottomColor property of style in selectTab method
function selectedTab(selectName) {
var x = document.getElementsByClassName("select");
for (var i = 0; i < x.length; i++) {
x[i].style.borderBottomColor = "#dbdbdb"; //observe style property Change
}
document.getElementById(selectName).style.borderBottomColor = "#25a7df";
}

Set CSS property with js click event handler

I am trying to create an onclick event which will show/hide elements of an array however I am struggling with the showSubTabGroup() function below.
Sidenote: Eventually I would like to make this onmouseenter and onmouseleave, rather than 'click' as you see below.
I would like to be able to click on a div and show subsequent div's below as you might expect from a navigation feature.
The console is not returning any errors, however the 'click' function seems alert("CLICKED") properly.
Any help would be greatly appreciated.
Problem:
Tab.prototype.showSubTabGroup = function (tabIndex, subTabIndex) {
this.tab[tabIndex].addEventListener('click', function () {
alert("CLICKED");//Testing 'click' call
for (var i = subTabIndex; i < this.subTabGroup; i++) {
this.subTab[i].style.display = "";
}
});
}
function Tab (subTabGroup) {
this.tab = document.getElementsByClassName("tab");
this.subTab = document.getElementsByClassName("sub-tab");
this.subTabGroup = subTabGroup;
}
Tab.prototype.hideSubTabs = function () {
for (var i = 0; i < this.subTab.length; i++) {
this.subTab[i].style.display = "none";
}
}
Tab.prototype.showSubTabGroup = function (tabIndex, subTabIndex) {
this.tab[tabIndex].addEventListener('click', function () {
for (var i = subTabIndex; i < this.subTabGroup; i++) {
this.subTab[i].style.display = "";
}
});
}
var tab = new Tab(3);
tab.hideSubTabs();
tab.showSubTabGroup(0,0);
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Responsive Nav</title>
</head>
<body>
<!-- JQuery CDN -->
<script src="http://code.jquery.com/jquery-3.1.0.js"></script>
<div class="container">
<div class="tab">
<p>TAB</p>
</div>
<div class="sub-tab">
<p>SUBTAB</p>
</div>
<div class="sub-tab">
<p>SUBTAB</p>
</div>
<div class="sub-tab">
<p>SUBTAB</p>
</div>
</div>
<div class="container">
<div class="tab">
<p>TAB</p>
</div>
<div class="sub-tab">
<p>SUBTAB</p>
</div>
<div class="sub-tab">
<p>SUBTAB</p>
</div>
<div class="sub-tab">
<p>SUBTAB</p>
</div>
</div>
<div class="container">
<div class="tab">
<p>TAB</p>
</div>
<div>
<div class="sub-tab">
<p>SUBTAB</p>
</div>
<div class="sub-tab">
<p>SUBTAB</p>
</div>
<div class="sub-tab">
<p>SUBTAB</p>
</div>
</div>
</div>
<script type="text/javascript" src="tab.js"></script>
<script type="text/javascript" src="tabEvents.js"></script>
</body>
</html>
The problem of what is this inside the click. It is not your tab code, it is the reference to the element that you clicked on. You need to change that by using bind
Tab.prototype.showSubTabGroup = function (tabIndex, subTabIndex) {
this.tab[tabIndex].addEventListener('click', (function () {
for (var i = subTabIndex; i < this.subTabGroup; i++) {
this.subTab[i].style.display = "";
}
}).bind(this));
}
As I read your post, I assume hideSubTabs() is working properly. In that case I will suggest to use in showSubTabGroup():
this.subTab[i].style.display = "initial";
instead of
this.subTab[i].style.display = "";
"initial" will set to its default e.g. as "block" for div and "inline" for span
I see that you also have included jQuery. If I may ask why don't jQuery functions which will do the same with less code:
$('.tab').on('click',function() {
$(this).closest('.container').find('.sub-tab').toggle()
})
$('.tab').click();
$('.tab')[0].click();

Why is .parent of .getElementByTagName undefined

Why does .parent of an item in .getElementsByTagName return undefined? I am trying to apply a class to the parent of the with href equal to document.URL.
<div id="JSE_vertical_nav">
<div class="jse_link_row">
HOME
</div>
<div class="jse_link_row">
ABOUT
</div>
<div class="jse_link_row">
NEWS
</div>
</div>
<script language="javascript" type="text/javascript">
var jse_page_url = document.URL;
var jse_links_in_nav = document.getElementById('JSE_vertical_nav').getElementsByTagName('a');
for (var i=0; i < jse_links_in_nav.length; i++) {
if (jse_links_in_nav[i] == jse_page_url) {
//why does this alert undefined?
alert(jse_links_in_nav[i].parent);
}
}
</script>
parentNode is the property you're looking for :)
Use jquery for that
$(document).ready(function(){
if($('a[href="google.com"]').length != 0)
{
alert("found !");
}
});

Categories