Add class name to an exact element - javascript

There are 7 links in one div and 7 divs in another. Example https://jsfiddle.net/tania_poltava/2oqtr9v1/
I want, when the first link is hovered to influent on first img, adding class; and with other links.
im triing to do this - getting the number of hovered link, then looking for the div with classname with such number, and try to add new class.
<div class="links">
button1
button2
button3
button4
button5
button6
button7
</div>
<div class="rounds">
<div class="services__round--1"></div>
<div class="services__round--2"></div>
<div class="services__round--3"></div>
<div class="services__round--4"></div>
<div class="services__round--5"></div>
<div class="services__round--6"></div>
<div class="services__round--7"></div>
</div>
.rounds div {
background: grey;
width:40px;
height: 40px;
border-radius: 50%;
}
.services__round--active {
background: green;
}
jQuery(function ($) {
$(document).ready(function() {
var link = $(".links a");
var linkClass = $(link).attr('class');
var linkNumb = linkClass.replace(/[^0-9]/g,'');
var roundClass = "services__round--" + linkNumb;
$(link).hover(function(){
var round = $(roundClass).addClass('services__round--active');
// check
console.log(linkNumb);
console.log(linkClass);
console.log(roundClass);
})
})
})

EDITED: Answer for your code is;
https://jsfiddle.net/g3wjc6tz/
jQuery(function($) {
$(document).ready(function() {
var link = $(".links a");
$(link).hover(function() {
// check
$('.services__round--active').removeClass('services__round--active')
var linkClass = $(this).attr('class');
var linkNumb = linkClass.replace(/[^0-9]/g, '');
var roundClass = "services__round--" + linkNumb;
var round = $('.' + roundClass).addClass('services__round--active');
console.log(linkNumb);
console.log(linkClass);
console.log(roundClass);
})
})
})
Not the best but more simple and proper way to do it: https://jsfiddle.net/g3wjc6tz/1/

Related

How do i style each li element at a time?

I am trying to style each <li> element at a time on click, not all at once. For each click, the first one, then on the second click, the next one and so on...
This code puts style on all li elements at once. How do I do it?
$("a").click(function() {
var menu = document.getElementsByTagName("li");
for (var i = 0; menu[i]; i++) {
$(menu).css("background", "red");
}
});
p {
color: red;
margin: 5px;
cursor: pointer;
}
p:hover {
background: yellow;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<a>sdadsa</a>
<ul>
<li>asda</li>
<li>sadada</li>
<li>sada</li>
<li>asdad</li>
</ul>
You can use jQuery's .css() to check the css value of specified element
$("a").click(function() {
var menu = document.getElementsByTagName("li");
for (var i = 0; menu[i]; i++) {
// get element of current index
const menuElement = menu[i];
// if the first element's background is not red.
if ($(menuElement).css("background") !== "red") {
// set it red.
$(menuElement).css("background", "red");
// escape for loop
break;
}
}
});
You can use a variable that points to current li element which should change background on the next click. When the anchor tag is clicked we remove the background of previous li element and change the current element's background
<script>
let current = 0;
$("a").click(function () {
var menu = document.getElementsByTagName("li");
let prev = current-1;
if(prev==-1) prev = menu.length-1;
menu[prev].style.background = "none";
menu[current].style.backgroud = "red";
current = (current + 1)%menu.length;
});
</script>
One approach would be to add a class to do the styling.
When you click your element find the first <li> that doesn't have that class and add it to that one.
Adding and removing classes is typically easier than modifying and undoing inline style
$("a").click(function() {
$('li').not('.red-bg').first().addClass('red-bg')
});
.red-bg {background:red}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<a>sdadsa</a>
<ul>
<li>asda</li>
<li>sadada</li>
<li>sada</li>
<li>asdad</li>
</ul>

How to move an HTML element's content from and to over and over?

How do I add the ability to drag certain content from one element over to another element, and back again, in pure Javascript?
I need this functionality to change the position of the content based on desktop and mobile sizes.
I have made my own function but the problem is that it's not possible to do the last action, to move the content to it's Original position again. It needs some bind functionality I think?
function moveContent(fromid, toid)
{
// Insert After This
var ref_el = document.getElementById(toid);
var parent = ref_el.parentNode;
// From Element
var from_el = document.getElementById(fromid);
if (from_el != null)
{
var from_el_parent = from_el.parentNode;
tparent = from_el.parentNode;
if (tparent === null || tparent.id !== toid)
{
var holder = from_el.outerHTML;
from_el.innerHTML = '';
// Insert inside
ref_el.innerHTML = holder;
}
}
}
Function example
function ChangeContent(aid,bid)
{
if((document.getElementById(aid)!=null)&&(document.getElementById(bid)!=null))
{
var atemp=document.getElementById(aid).innerHTML;
var btemp=document.getElementById(bid).innerHTML;
document.getElementById(aid).innerHTML=btemp;
document.getElementById(bid).innerHTML=atemp;
}
}
HTML example
<div id='A'><hr>
First div content<hr>
</div>
<div id='B'>
<strong>List</strong><br>
<ul>
<li>1</li>
<li>2</li>
<ul>
<li>3.1</li>
<li>3.2</li>
</ul>
</ul>
</div>
<input type='button' onclick='SwapContent(\"A\",\"B\");' value='Swap'></button>
Notes
You must place JavaScript after HTML, because otherwise JavaScript will not be able to find the elements to swap the content of.
Quotes in "onclick" function parameters are of this type because all code written for PHP+Html printing width ".
I'm not sure whether how practical your approach is but here is a JavaScript solution which will remove an element from the DOM and append it inside another element.
If the parent element doesn't have an id atribute, one is created using a Counter.
Restoring the element is simply a case of keeping track of the id of the parent element using a data-parent attribute.
(function() {
var Counter = function () {
if (Counter.prototype._singletonInstance) {
return Counter.prototype._singletonInstance;
}
Counter.prototype._singletonInstance = this;
this.getValue = function() {
if (this.value) {
this.value++;
} else {
this.value = 1;
}
return this.value;
};
};
function moveContent(fromId, toId) {
var from_el = document.getElementById(fromId);
var target_el = document.getElementById(toId);
if (from_el != null && from_el != target_el) {
var from_el_parent = from_el.parentNode;
var parent_id = from_el_parent.getAttribute("id");
if (!parent_id) {
// parent element doesn't have an id
// so generate a new parent id
var counter = new Counter();
parent_id = "gen_" + counter.getValue();
from_el_parent.setAttribute("id", parent_id);
}
if (!from_el.getAttribute("data-parent")) {
// the data-parent attribute is our route home
from_el.setAttribute("data-parent", parent_id);
}
// Insert After This
target_el.appendChild(from_el);
}
}
function restoreContent(id) {
var el = document.getElementById(id);
var parent = el.getAttribute("data-parent");
if (parent) {
// data-parent attribute exists
var target = document.getElementById(parent);
if (target) {
// target is valid
target.appendChild(el)
}
}
}
document.getElementById("switchAtoB").onclick = function switchAtoB() {
moveContent("contentA", "parentB");
}
document.getElementById("restore").onclick = function restoreA() {
restoreContent("contentA");
}
})();
#parentA {
background-color: #0aa;
min-height: 100px;
}
#parentB {
background-color: #aa0;
min-height: 100px;
}
<div>
<div id="parentA">
<div id="contentA">
<h1>Simple Title</h1>
<p>Lorem ipsum...</p>
</div>
</div>
<div id="parentB">
<div id="intro">
<p>Blah blah blah ...</p>
</div>
</div>
<div>
<button id="switchAtoB">A -> B</button>
<button id="restore">Switch Back</button>
</div>
</div>

How to sequentially .append() created elements to the previously added element

The code
JavaScript:
var recurringF = (function(){
this.$el = $("#target");
this.arg = arguments[0];
this.spl = (!_.isEmpty(this.arg)) ? this.arg.split(" ") : false;
if(this.spl){
for(var i=0;i<this.spl.length;i++){
if(i===0){
this.$el.append(document.createElement(this.spl[i]));
}else{
this.$el.children().last().append(document.createElement(this.spl[i]));
}
}
}
return {
"$":this.$el
}
});
var t = new recurringF("div h1 span");
HTML-Body:
<body>
<div id="target"></div>
</body>
The Goal
I'd like to append elements sequentially to an parent element $("#target") so that the end result in the HTML is the following:
<body>
<div id="target">
<div>
<h1>
<span></span>
</h1>
</div>
</div>
</body>
The loop does not append the created elements to the the last appended element, but to the in loop cycle 1 created element 'div' like the following:
<div id="target">
<div>
<h1></h1>
<span></span>
</div>
</div>
What am I missing?
By using .children(), you'll only get the immediate div on every iteration after the first, thus resulting in
<div id="target">
<div>
<h1></h1>
<span></span>
<alltherest></alltherest>
</div>
</div>
because .children only looks at children, not all descendants. What you want is .find(*) so that it will get the deepest nested descendant on each iteration.
this.$el.find('*').last().append(document.createElement(this.spl[i]));
https://jsfiddle.net/f3fb997h/
That said, it would be better if you just stored a reference to the last created element and append to it, rather than having to reselect it every iteration.
var $tempEl = this.$el, newEl;
if(this.spl){
for(var i=0;i<this.spl.length;i++){
newEl = document.createElement(this.spl[i]);
$tempEl.append(newEl);
$tempEl = $(newEl);
}
}
https://jsfiddle.net/f3fb997h/1/
Note that at this point you're not really benefiting from jQuery at all, so a small tweak and you're not depending on it.
var recurringF = (function(){
this.el = document.getElementById('target');
this.arg = arguments[0];
this.spl = (!_.isEmpty(this.arg)) ? this.arg.split(" ") : false;
console.log(this.spl);
var tempEl = this.el, newEl;
if(this.spl){
for(var i=0;i<this.spl.length;i++){
newEl = document.createElement(this.spl[i]);
tempEl.appendChild(newEl);
tempEl = newEl;
}
}
return {
"el":this.el
}
});
You can try using regular javascript functionality, as it has child appending built in:
const recurseElement = (elementString, target) => {
const elements = elementString.split(' ');
elements.forEach(function(ele) {
const domElement = document.createElement(ele); // create the element
target.appendChild(domElement); // append to the target
target = domElement; // this element is the new target
});
}
So now you can use it like so:
recurseElement('div h1 span', document.getElementById('target'));
const recurseElement = (elementString, target) => {
const elements = elementString.split(' ');
elements.forEach(function(ele) {
const domElement = document.createElement(ele); // create the element
target.appendChild(domElement); // append to the target
target = domElement; // this element is the new target
});
};
recurseElement('div h1 span', document.getElementById('target'));
#target div {
background: green;
height: 16px; width: 128px; padding: 10px;
}
#target div h1 {
background: red;
height: 16px; width: 64px; padding: 10px;
}
#target div h1 span {
background: purple; display: block;
height: 16px; width: 32px; padding: 10px;
}
<div id="target"></div>
It should be noted that arrow functions are available for Chrome 45+, Firefox 22.0+, Edge, and Opera. They do not work in IE or Safari. Or they will work if you have a transpiler (like babel)

Wrap javascript element in HTML

The following code copies all elements given one css class, that's fine, it does render the list of elements... Now I'd like to wrap those results in HTML content, how can I achieve that?
setTimeout(function() {
var element = document.getElementById("unique_ID");
element.innerHTML = "";
Array.prototype.forEach.call(document.querySelectorAll(".a_random_class"), function(e) {
var storednode = element.appendChild(e.cloneNode(true));
});
}, 300);
How can I wrap in HTML content each of the storednode? I've been able to apply classes: storednode.className += " another-class";, but how can I wrap the results in any HTML I want? is that possible?
Thank you for your time.
Edit:
This is what the script does.
setTimeout(function() {
var element = document.getElementById("unique_ID");
element.innerHTML = "";
Array.prototype.forEach.call(document.querySelectorAll(".a_random_class"), function(e) {
element.appendChild(e.cloneNode(true));
});
}, 300);
#unique_ID {
border: 1px solid blue;
}
<div id="unique_ID"></div>
<div class="a_random_class">a</div>
<div class="a_random_class">b</div>
<div class="a_random_class">c</div>
<div class="a_random_class">d</div>
<div class="a_random_class">e</div>
<div class="a_random_class">f</div>
What I need is that each result, for example <div class="a_random_class">f</div> can be wrapped inside any HTML code I want, to get something like <div id="another-div" class="a-class" style="maybe:styles"><li><div class="a_random_class">f</div></li></div> This is certainly an example, but I'd like to know if that's possible... Not only copy the class elements but also append some HTML on them.
I think what you are looking for is something like
setTimeout(function () {
var element = document.createElement('div');
element.className = 'something';
[].forEach.call(document.querySelectorAll(".a_random_class"), function (e) {
var wrap = element.cloneNode(true);
e.parentNode.insertBefore(wrap, e)
wrap.appendChild(e);
});
}, 300);
setTimeout(function() {
var element = document.createElement('div');
element.className = 'something';
[].forEach.call(document.querySelectorAll(".a_random_class"), function(e) {
var wrap = element.cloneNode(true);
e.parentNode.insertBefore(wrap, e)
wrap.appendChild(e);
});
}, 300);
.something {
border: 1px solid red;
padding: 5px;
margin-bottom: 5px;
}
.a_random_class {
background-color: lightgrey;
}
<div class="a_random_class">a</div>
<div class="a_random_class">b</div>
<div class="a_random_class">c</div>
<div class="a_random_class">d</div>
<div class="a_random_class">e</div>
<div class="a_random_class">f</div>

Don't show more than one div at a time Javascript

I currently have four divs, which are each linked to a hidden div:
div1 - div1hidden
div2 - div2hidden
div3 - div3hidden
div4 - div4hidden
When a user clicks on one of the divs the hidden div appears. When clicked on again the div disappears.
The problem I have is if all four divs are clicked on all four hidden will appear. What I would like to do is only show one at a time.
For Example if 'div1hidden' is showing and the user clicks on div2 before hiding div1hidden, div1hidden will hide and div2hidden will appear.
This is the code I have so far:
function hide_menu(id){document.getElementById(id).style.display = "none";}
function show_menu(id){document.getElementById(id).style.display = "block";}
<div class="div1" onclick="if (document.getElementById('div1hidden').style.display=='none') show_menu('div1hidden'); else hide_menu('div1hidden');"></div>
<div class="div2" onclick="if (document.getElementById('div2hidden').style.display=='none') show_menu('div2hidden'); else hide_menu('div2hidden');"></div>
<div class="div3" onclick="if (document.getElementById('div3hidden').style.display=='none') show_menu('div3hidden'); else hide_menu('div3hidden');"></div>
<div class="div4" onclick="if (document.getElementById('div4hidden').style.display=='none') show_menu('div4hidden'); else hide_menu('div4hidden');"></div>
Thanks in advance
Rick
Try something like this:
Add a function:
function hide_all() {
hide_menu('div1hidden');
hide_menu('div2hidden');
hide_menu('div3hidden');
hide_menu('div4hidden');
}
Now call that function before you show any hidden div:
<div class="div1" onclick="if (document.getElementById('div1hidden').style.display=='none') {hide_all(); show_menu('div1hidden'); } else { hide_menu('div1hidden'); }"></div>
I'm not sure what's wrong with just hiding all other divs before opening the one your need:
<div class="div1" onclick="if (document.getElementById('div1hidden').style.display=='none') { hide_menu('div2hidden'); hide_menu('div3hidden'); hide_menu('div4hidden'); show_menu('div1hidden');} else hide_menu('div1hidden');"></div>
<!-- and so on -->
I must say that this isn't exactly the best approach to do the comparison in the onclick - instead I suggest putting it inside the function, something like this:
<script type="text/javascript">
function flipDiv(id)
{
var vis = document.getElementById('div' + id + 'hidden').style.display;
if(vis == 'none')
{
document.getElementById('div1hidden').style.display = 'none';
document.getElementById('div2hidden').style.display = 'none';
document.getElementById('div3hidden').style.display = 'none';
document.getElementById('div4hidden').style.display = 'none';
document.getElementById('div' + id + 'hidden').style.display = 'block';
}
else
{
document.getElementById('div' + id + 'hidden').style.display = 'block';
}
}
</script>
...
<div class="div1" onclick="flipDiv(1)">...</div>
...
The easiest way will be to cache the current open menu.
<head>
<script type="text/javascript">
var current = null; //current is stored here
function hide_current(){
if(current !=null){
document.getElementById(current).style.display = "none";
}
}
function show_menu(id){
if(current == id){
hide_current(); //current is already open, close it
current = null; //reset current
} else {
document.getElementById(id).style.display = "block";
current = id;
}
}
</script>
</head>
<body>
<div class="div1" onclick="hide_current();show_menu('div1hidden');"></div>
<div class="div2" onclick="hide_current();show_menu('div2hidden');"></div>
<div class="div3" onclick="hide_current();show_menu('div3hidden');"></div>
<div class="div4" onclick="hide_current();show_menu('div4hidden');"></div>
</body>
Although the other suggested answers will accomplish what you want, none of them are very robust. This is based on the fact that your sample code is not very robust. It relies on inline javascript calls and hard coding to your elements.
Something like this will be easily extendable and less prone to breakage. Please note that some modifications will be necessary to accommodate old versions of IE (attachEvent support and getElementsByClassName support). But the concepts are the important thing.
Basically we get all the parent divs. Attach an event to their click. When they are clicked we hide all the divs that are supposed to be hidden and show the one we want.
http://jsfiddle.net/mrtsherman/8sgC2/2/
var divs = document.getElementsByClassName('menu');
for (var index = 0; index < divs.length; index++) {
divs[index].addEventListener('click', function() {
var contentDiv = null;
//hide all other divs
for (var i = 0; i < divs.length; i++) {
contentDiv = document.getElementById(divs[i].id + 'content');
contentDiv.style.display = 'none';
}
//show current item
contentDiv = document.getElementById(this.id + 'content');
contentDiv.style.display = 'block';
}, false)
}
<div class="menu" id="div1">one</div>
<div class="menu" id="div2">two</div>
<div class="menu" id="div3">three</div>
<div class="menu" id="div4">four</div>
<div class="content" id="div1content">one content</div>
<div class="content" id="div2content">two content</div>
<div class="content" id="div3content">three content</div>
<div class="content" id="div4content">four content</div>
Note that libaries like jQuery can do this in far less code, without having to account for browser differences and with cool effects like sliding or fading in.
http://jsfiddle.net/mrtsherman/8sgC2/3/
//bind to click event on the div
$('.menu').click( function() {
//get content div associated with the clicked div
var contentDiv = $(this).attr('id') + 'content';
//if no items are visible yet then show current
if ($('.content').filter(':visible').length == 0) {
$('#' + contentDiv).slideDown();
return;
}
//hide visible divs and show new div
$('.content').filter(':visible').slideUp('fast', function() {
$('#' + contentDiv).slideDown();
});
});
You can create the Display Div & Hidden div
at the same time and creating the click event in loop
This is source code which you can use to apply for unlimited divs
var n = 10;
var did = 'divDisplay';
var hid = 'divHidden';
function divDisplayOnclick()
{
for(var i=0; i<n; i++)
{
document.getElementById(did+i+hid).style.display = 'none';
}
document.getElementById(this.id+hid).style.display = 'block';
}
function createDivDisplay()
{
for(var i=0; i<n;i++)
{
var divDisplay = document.createElement('div');
divDisplay.id = did+i;
divDisplay.innerHTML = 'Click to display hidden div '+i;
divDisplay.className = did;
divDisplay.onclick = divDisplayOnclick;
document.body.appendChild(divDisplay);
var divHidden = document.createElement('div');
divHidden.id = did+i+hid;
divHidden.innerHTML = 'This is hidden div '+i;
divHidden.className = hid;
document.body.appendChild(divHidden);
}
}
createDivDisplay();
.divDisplay
{
border: 1px solid powderblue;
margin-bottom: 5px;
cursor: pointer;
}
.divHidden
{
border: 1px solid red;
margin-left: 20px;
margin-bottom: 10px;
display: none;
}

Categories