Anchor Tag href functions - javascript

I am trying to create a function that finds the id of an element that an anchor tag directs to, and attach a class to that element. I need this to be vanilla js not jquery.
For Example:
<div id="firstDiv"></div>
<div> Destination </div>
<div> Destination #2 </div>
The idea would be that once you click on the anchor tag that it would take you to the div and attach a class to that div to initiate a function.
The script that I've written runs for loops that add the values of the href attribute and the id attribute from javascript objects. See Below:
var rooms = [
{
id: 1,
name: Example,
},
{
id:2,
name: Example #2,
}
]
for ( x in rooms ) {
var i = document.getElementById("firstDiv");
var a = document.createElement("a");
i.appendChild(a);
a.href = "#" + rooms[x].id;
a.innerHTML += rooms[x].name + "<br>";
a.classList.add("show");
}
var rect = document.getElementsByTagName("rect");
for ( i = 0; i < rect.length; i++ ) {
rect[i].setAttribute("id", rooms[i].id);
}
Output:
<div id="firstDiv">
Example
Example #2
</div>
<div id="1"> Destination </div>
<div id="2"> Destination #2 </div>
The function below is an example of what I want the function to do for each corresponding div when an a tag is clicked.
function attach() {
var div = document.getElementById(rooms[i].id);
div.classList.toggle("active");
}
Any advice on how to properly write this function for my particular needs. Would a for loop be best for this or an if/else statement. I've tried both but neither has worked.
Please let me know if I need to clarify more.

It seems like this is what you are asking about. See comments inline.
document.addEventListener("click", function(event){
// First, check to see if it was an anchor that was clicked
// in the document
if(event.target.nodeName === "A"){
// If so, add a class to the target
// Get the href attribute and strip off the "#", then find that element and toggle the class
document.getElementById(event.target.getAttribute("href").replace("#","")).classList.toggle("highlight");
}
});
.highlight { background-color:yellow; }
<div id="firstDiv">
Example
Example #2
</div>
<div id="one"> Destination </div>
<div id="two"> Destination #2 </div>

Try this:
let anchors = document.querySelectorAll("#firstDiv a");
for (let i = 0; i < anchors.length; i++) {
anchors[i].addEventListener("click", () => {
var div = document.getElementById(rooms[i].id);
div.classList.toggle("active");
}

You're almost there you just need to add an onclick property for the anchor tag now you can or cannot use the third attach function.I am including both implementations for your reference.
for ( x in rooms ) {
var i = document.getElementById("firstDiv");
var a = document.createElement("a");
i.appendChild(a);
a.href = "#" + rooms[x].id;
a.innerHTML += rooms[x].name + "<br>";
a.classList.add("show");
a.onClick=`document.getElementById(${rooms[x].id}).classList.toggle("active")`;
}
If you want to have a dedicated function your loop becomes
for ( x in rooms ) {
var i = document.getElementById("firstDiv");
var a = document.createElement("a");
i.appendChild(a);
a.href = "#" + rooms[x].id;
a.innerHTML += rooms[x].name + "<br>";
a.classList.add("show");
a.onClick=`attach(${rooms[x].id})`;
}
Your attach function then becomes:
function attach(id) {
var div = document.getElementById(id);
div.classList.toggle("active");
}
Do let me know if you have any issues.

CSS Only 😎
This is a bit off-topic but you can use the :target selector to set the style of the corresponding id without JS.
/* element with an id matching the URL fragment */
:target {
background: gold;
}
/* you can combine target with other selectors */
#c:target {
background: orange
}
/* just a bit of styling */
a,div {
padding: .5rem;
display: block;
width: 20%;
float:left;
}
Link to A
Link to B
Link to C
Link to D
<div id="a">A</div>
<div id="b">B</div>
<div id="c">C</div>
<div id="d">D</div>

Related

Changing class using JavaScript [duplicate]

I have an element that already has a class:
<div class="someclass">
<img ... id="image1" name="image1" />
</div>
Now, I want to create a JavaScript function that will add a class to the div (not replace, but add).
How can I do that?
If you're only targeting modern browsers:
Use element.classList.add to add a class:
element.classList.add("my-class");
And element.classList.remove to remove a class:
element.classList.remove("my-class");
If you need to support Internet Explorer 9 or lower:
Add a space plus the name of your new class to the className property of the element. First, put an id on the element so you can easily get a reference.
<div id="div1" class="someclass">
<img ... id="image1" name="image1" />
</div>
Then
var d = document.getElementById("div1");
d.className += " otherclass";
Note the space before otherclass. It's important to include the space otherwise it compromises existing classes that come before it in the class list.
See also element.className on MDN.
The easiest way to do this without any framework is to use element.classList.add method.
var element = document.getElementById("div1");
element.classList.add("otherclass");
Edit:
And if you want to remove class from an element -
element.classList.remove("otherclass");
I prefer not having to add any empty space and duplicate entry handling myself (which is required when using the document.className approach). There are some browser limitations, but you can work around them using polyfills.
find your target element "d" however you wish and then:
d.className += ' additionalClass'; //note the space
you can wrap that in cleverer ways to check pre-existence, and check for space requirements etc..
Add Class
Cross Compatible
In the following example we add a classname to the <body> element. This is IE-8 compatible.
var a = document.body;
a.classList ? a.classList.add('classname') : a.className += ' classname';
This is shorthand for the following..
var a = document.body;
if (a.classList) {
a.classList.add('wait');
} else {
a.className += ' wait';
}
Performance
If your more concerned with performance over cross-compatibility you can shorten it to the following which is 4% faster.
var z = document.body;
document.body.classList.add('wait');
Convenience
Alternatively you could use jQuery but the resulting performance is significantly slower. 94% slower according to jsPerf
$('body').addClass('wait');
Removing the class
Performance
Using jQuery selectively is the best method for removing a class if your concerned with performance
var a = document.body, c = ' classname';
$(a).removeClass(c);
Without jQuery it's 32% slower
var a = document.body, c = ' classname';
a.className = a.className.replace( c, '' );
a.className = a.className + c;
References
jsPerf Test Case: Adding a Class
jsPerf Test Case: Removing a Class
Using Prototype
Element("document.body").ClassNames.add("classname")
Element("document.body").ClassNames.remove("classname")
Element("document.body").ClassNames.set("classname")
Using YUI
YAHOO.util.Dom.hasClass(document.body,"classname")
YAHOO.util.Dom.addClass(document.body,"classname")
YAHOO.util.Dom.removeClass(document.body,"classname")
Another approach to add the class to element using pure JavaScript
For adding class:
document.getElementById("div1").classList.add("classToBeAdded");
For removing class:
document.getElementById("div1").classList.remove("classToBeRemoved");
2 different ways to add class using JavaScript
JavaScript provides 2 different ways by which you can add classes to HTML elements:
Using element.classList.add() Method
Using className property
Using both methods you can add single or multiple classes at once.
1. Using element.classList.add() Method
var element = document.querySelector('.box');
// using add method
// adding single class
element.classList.add('color');
// adding multiple class
element.classList.add('border', 'shadow');
.box {
width: 200px;
height: 100px;
}
.color {
background: skyblue;
}
.border {
border: 2px solid black;
}
.shadow {
box-shadow: 5px 5px 5px gray;
}
<div class="box">My Box</div>
2. Using element.className Property
Note: Always use += operator and add a space before class name to add class with classList method.
var element = document.querySelector('.box');
// using className Property
// adding single class
element.className += ' color';
// adding multiple class
element.className += ' border shadow';
.box {
width: 200px;
height: 100px;
}
.color {
background: skyblue;
}
.border {
border: 2px solid black;
}
.shadow {
box-shadow: 5px 5px 5px gray;
}
<div class="box">My Box</div>
document.getElementById('some_id').className+=' someclassname'
OR:
document.getElementById('some_id').classList.add('someclassname')
First approach helped in adding the class when second approach didn't work.
Don't forget to keep a space in front of the ' someclassname' in the first approach.
For removal you can use:
document.getElementById('some_id').classList.remove('someclassname')
When the work I'm doing doesn't warrant using a library, I use these two functions:
function addClass( classname, element ) {
var cn = element.className;
//test for existance
if( cn.indexOf( classname ) != -1 ) {
return;
}
//add a space if the element already has class
if( cn != '' ) {
classname = ' '+classname;
}
element.className = cn+classname;
}
function removeClass( classname, element ) {
var cn = element.className;
var rxp = new RegExp( "\\s?\\b"+classname+"\\b", "g" );
cn = cn.replace( rxp, '' );
element.className = cn;
}
Assuming you're doing more than just adding this one class (eg, you've got asynchronous requests and so on going on as well), I'd recommend a library like Prototype or jQuery.
This will make just about everything you'll need to do (including this) very simple.
So let's say you've got jQuery on your page now, you could use code like this to add a class name to an element (on load, in this case):
$(document).ready( function() {
$('#div1').addClass( 'some_other_class' );
} );
Check out the jQuery API browser for other stuff.
You can use the classList.add OR classList.remove method to add/remove a class from a element.
var nameElem = document.getElementById("name")
nameElem.classList.add("anyclss")
The above code will add(and NOT replace) a class "anyclass" to nameElem.
Similarly you can use classList.remove() method to remove a class.
nameElem.classList.remove("anyclss")
To add an additional class to an element:
To add a class to an element, without removing/affecting existing values, append a space and the new classname, like so:
document.getElementById("MyElement").className += " MyClass";
To change all classes for an element:
To replace all existing classes with one or more new classes, set the className attribute:
document.getElementById("MyElement").className = "MyClass";
(You can use a space-delimited list to apply multiple classes.)
If you don't want to use jQuery and want to support older browsers:
function addClass(elem, clazz) {
if (!elemHasClass(elem, clazz)) {
elem.className += " " + clazz;
}
}
function elemHasClass(elem, clazz) {
return new RegExp("( |^)" + clazz + "( |$)").test(elem.className);
}
I too think that the fastest way is to use Element.prototype.classList as in es5: document.querySelector(".my.super-class").classList.add('new-class')
but in ie8 there is no such thing as Element.prototype.classList, anyway you can polyfill it with this snippet (fell free to edit and improve it):
if(Element.prototype.classList === void 0){
function DOMTokenList(classes, self){
typeof classes == "string" && (classes = classes.split(' '))
while(this.length){
Array.prototype.pop.apply(this);
}
Array.prototype.push.apply(this, classes);
this.__self__ = this.__self__ || self
}
DOMTokenList.prototype.item = function (index){
return this[index];
}
DOMTokenList.prototype.contains = function (myClass){
for(var i = this.length - 1; i >= 0 ; i--){
if(this[i] === myClass){
return true;
}
}
return false
}
DOMTokenList.prototype.add = function (newClass){
if(this.contains(newClass)){
return;
}
this.__self__.className += (this.__self__.className?" ":"")+newClass;
DOMTokenList.call(this, this.__self__.className)
}
DOMTokenList.prototype.remove = function (oldClass){
if(!this.contains(newClass)){
return;
}
this[this.indexOf(oldClass)] = undefined
this.__self__.className = this.join(' ').replace(/ +/, ' ')
DOMTokenList.call(this, this.__self__.className)
}
DOMTokenList.prototype.toggle = function (aClass){
this[this.contains(aClass)? 'remove' : 'add'](aClass)
return this.contains(aClass);
}
DOMTokenList.prototype.replace = function (oldClass, newClass){
this.contains(oldClass) && this.remove(oldClass) && this.add(newClass)
}
Object.defineProperty(Element.prototype, 'classList', {
get: function() {
return new DOMTokenList( this.className, this );
},
enumerable: false
})
}
To add, remove or check element classes in a simple way:
var uclass = {
exists: function(elem,className){var p = new RegExp('(^| )'+className+'( |$)');return (elem.className && elem.className.match(p));},
add: function(elem,className){if(uclass.exists(elem,className)){return true;}elem.className += ' '+className;},
remove: function(elem,className){var c = elem.className;var p = new RegExp('(^| )'+className+'( |$)');c = c.replace(p,' ').replace(/ /g,' ');elem.className = c;}
};
var elem = document.getElementById('someElem');
//Add a class, only if not exists yet.
uclass.add(elem,'someClass');
//Remove class
uclass.remove(elem,'someClass');
I know IE9 is shutdown officially and we can achieve it with element.classList as many told above but I just tried to learn how it works without classList with help of many answers above I could learn it.
Below code extends many answers above and improves them by avoiding adding duplicate classes.
function addClass(element,className){
var classArray = className.split(' ');
classArray.forEach(function (className) {
if(!hasClass(element,className)){
element.className += " "+className;
}
});
}
//this will add 5 only once
addClass(document.querySelector('#getbyid'),'3 4 5 5 5');
You can use modern approach similar to jQuery
If you need to change only one element, first one that JS will find in DOM, you can use this:
document.querySelector('.someclass').className += " red";
.red {
color: red;
}
<div class="someclass">
<p>This method will add class "red" only to first element in DOM</p>
</div>
<div class="someclass">
<p>lorem ipsum</p>
</div>
<div class="someclass">
<p>lorem ipsum</p>
</div>
<div class="someclass">
<p>lorem ipsum</p>
</div>
Keep in mind to leave one space before class name.
If you have multiple classes where you want to add new class, you can use it like this
document.querySelectorAll('.someclass').forEach(function(element) {
element.className += " red";
});
.red {
color: red;
}
<div class="someclass">
<p>This method will add class "red" to all elements in DOM that have "someclass" class.</p>
</div>
<div class="someclass">
<p>lorem ipsum</p>
</div>
<div class="someclass">
<p>lorem ipsum</p>
</div>
<div class="someclass">
<p>lorem ipsum</p>
</div>
This might be helpful for WordPress developers etc.
document.querySelector('[data-section="section-hb-button-1"] .ast-custom-button').classList.add('TryMyClass');
Just to elaborate on what others have said, multiple CSS classes are combined in a single string, delimited by spaces. Thus, if you wanted to hard-code it, it would simply look like this:
<div class="someClass otherClass yetAnotherClass">
<img ... id="image1" name="image1" />
</div>
From there you can easily derive the javascript necessary to add a new class... just append a space followed by the new class to the element's className property. Knowing this, you can also write a function to remove a class later should the need arise.
I think it's better to use pure JavaScript, which we can run on the DOM of the Browser.
Here is the functional way to use it. I have used ES6 but feel free to use ES5 and function expression or function definition, whichever suits your JavaScript StyleGuide.
'use strict'
const oldAdd = (element, className) => {
let classes = element.className.split(' ')
if (classes.indexOf(className) < 0) {
classes.push(className)
}
element.className = classes.join(' ')
}
const oldRemove = (element, className) => {
let classes = element.className.split(' ')
const idx = classes.indexOf(className)
if (idx > -1) {
classes.splice(idx, 1)
}
element.className = classes.join(' ')
}
const addClass = (element, className) => {
if (element.classList) {
element.classList.add(className)
} else {
oldAdd(element, className)
}
}
const removeClass = (element, className) => {
if (element.classList) {
element.classList.remove(className)
} else {
oldRemove(element, className)
}
}
Sample with pure JS. In first example we get our element's id and add e.g. 2 classes.
document.addEventListener('DOMContentLoaded', function() {
document.getElementsById('tabGroup').className = "anyClass1 anyClass2";
})
In second example we get element's class name and add 1 more.
document.addEventListener('DOMContentLoaded', function() {
document.getElementsByClassName('tabGroup')[0].className = "tabGroup ready";
})
For those using Lodash and wanting to update className string:
// get element reference
var elem = document.getElementById('myElement');
// add some classes. Eg. 'nav' and 'nav header'
elem.className = _.chain(elem.className).split(/[\s]+/).union(['nav','navHeader']).join(' ').value()
// remove the added classes
elem.className = _.chain(elem.className).split(/[\s]+/).difference(['nav','navHeader']).join(' ').value()
Shortest
image1.parentNode.className+=' box';
image1.parentNode.className+=' box';
.box { width: 100px; height:100px; background: red; }
<div class="someclass">
<img ... id="image1" name="image1" />
</div>
You can use the API querySelector to select your element and then create a function with the element and the new classname as parameters. Using classlist for modern browsers, else for IE8. Then you can call the function after an event.
//select the dom element
var addClassVar = document.querySelector('.someclass');
//define the addclass function
var addClass = function(el,className){
if (el.classList){
el.classList.add(className);
}
else {
el.className += ' ' + className;
}
};
//call the function
addClass(addClassVar, 'newClass');
In my case, I had more than one class called main-wrapper in the DOM, but I only wanted to affect the parent main-wrapper. Using :first Selector (https://api.jquery.com/first-selector/), I could select the first matched DOM element. This was the solution for me:
$(document).ready( function() {
$('.main-wrapper:first').addClass('homepage-redesign');
$('#deals-index > div:eq(0) > div:eq(1)').addClass('doubleheaderredesign');
} );
I also did the same thing for the second children of a specific div in my DOM as you can see in the code where I used $('#deals-index > div:eq(0) > div:eq(1)').addClass('doubleheaderredesign');.
NOTE: I used jQuery as you can see.
The majority of people use a .classList.add on a getElementById, but I i wanted to use it on a getElementByClassName. To do that, i was using a forEach like this :
document.getElementsByClassName("class-name").forEach(element => element.classList.add("new-class"));
But it didn't work because i discovered that getElementsByClassName returns a HTML collection and not an array. To handle that I converted it to an array with this code :
[...document.getElementsByClassName("class-name")].forEach(element => element.classList.add("new-class"));
first, give the div an id. Then, call function appendClass:
<script language="javascript">
function appendClass(elementId, classToAppend){
var oldClass = document.getElementById(elementId).getAttribute("class");
if (oldClass.indexOf(classToAdd) == -1)
{
document.getElementById(elementId).setAttribute("class", classToAppend);
}
}
</script>
This js code works for me
provides classname replacement
var DDCdiv = hEle.getElementBy.....
var cssCNs = DDCdiv.getAttribute('class');
var Ta = cssCNs.split(' '); //split into an array
for (var i=0; i< Ta.length;i++)
{
if (Ta[i] == 'visible'){
Ta[i] = 'hidden';
break;// quit for loop
}
else if (Ta[i] == 'hidden'){
Ta[i] = 'visible';
break;// quit for loop
}
}
DDCdiv.setAttribute('class',Ta.join(' ') ); // Join array with space and set class name
To add just use
var cssCNs = DDCdiv.getAttribute('class');
var Ta = cssCNs.split(' '); //split into an array
Ta.push('New class name');
// Ta.push('Another class name');//etc...
DDCdiv.setAttribute('class',Ta.join(' ') ); // Join array with space and set class name
To remove use
var cssCNs = DDCdiv.getAttribute('class');
var Ta = cssCNs.split(' '); //split into an array
for (var i=0; i< Ta.length;i++)
{
if (Ta[i] == 'visible'){
Ta.splice( i, 1 );
break;// quit for loop
}
}
DDCdiv.setAttribute('class',Ta.join(' ') ); // Join array with space and set class name
Hope this is helpful to sombody
In YUI, if you include yuidom, you can use
YAHOO.util.Dom.addClass('div1','className');
HTH

Pure JS: Store list of data- attributes in array, then iterate

I'm fairly new to JS and I can do DOM manipulation and if/else statements by hand. Now I'm trying for something out of my league, combining iteration with arrays, and I have a bit of a hard time understanding both of them.
With this in mind: Considering this div: <div id="firstAnchor"> would act as an anchor to this link:
I want to store the ID of these div's (id's should be able to be anything):
<div id="firstAnchor" style="display: inline-block;">First title</div>
<div id="secondAnchor" style="display: inline-block;">Second title</div>
<div id="thirdAnchor" style="display: inline-block;">Third title</div>
into an array, and then create these three links automatically* placed in a div called "anchorLinks":
Link to first title
Link to second title
Link to third title
How would I go about this?
*
for example within this function:
(function create_anchor_link_list() {
//placed here
})();
Edit:
Here is what I have tried to begin with. I first had data-anchor="firstAnchor" etc. on my div elements until I realized I couldn't link to div elements based on data- attributes values. So with the data- attributes I tried:
(function anchorsInPage2(attrib) {
console.log("=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#");
console.log("=#=#=#=#=# anchorsInPage2 function #=#=#=#=#");
console.log("=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#");
console.log(" ");
var elements = document.getElementsByTagName("*");
var foundelements = [];
for (var i = 0; i < elements.length; i++) {
if (elements[i].attributes.length > 0) {
for (var x = 0; x < elements[i].attributes.length; x++) {
if (elements[i].attributes[x].name === attrib) {
foundelements.push(elements[i]);
}
}
}
}
return foundelements;
console.log(" ");
console.log("=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#");
console.log("=#=#=#=#=# / anchorsInPage2 function #=#=#=#=#");
console.log("=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#");
})();
function anchorsInPage3() {
console.log("=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#");
console.log("=#=#=#=#=# anchorsInPage3 function #=#=#=#=#");
console.log("=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#");
console.log(" ");
var elements = document.getElementsByTagName("*");
var foundelements = [];
for (var i = 0; i < elements.length; i++) {
if (elements[i].attributes.length > 0) {
for (var x = 0; x < elements[i].attributes.length; x++) {
if (elements[i].attributes[x].name === "anchor") {
foundelements.push(elements[i]);
}
}
}
}
return foundelements;
console.log(" ");
console.log("=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#");
console.log("=#=#=#=#=# / anchorsInPage3 function #=#=#=#=#");
console.log("=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#");
}
(function anchorsInPage1() {
console.log("=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#");
console.log("=#=#=#=#=# anchorsInPage1 function #=#=#=#=#");
console.log("=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#");
console.log(" ");
var anchors = document.querySelectorAll('[anchor]');
for(var i in anchors){
console.log(i);
}
console.log(" ");
console.log("=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#");
console.log("=#=#=#=#=# / anchorsInPage1 function #=#=#=#=#");
console.log("=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#");
})();
First update after further testing:
Barmar's example was used. The text below is a direct answer to Barmar (too long for the other comment field)
Test: http://jsfiddle.net/e5u03g4p/5/
My reply:
With the first variable you found all element with the attribute data-anchor, so I guess the brackets in querySelectorAll tells it which specific attribute we mean instead of what elements ID's we want, which is the "standard" writing document.querySelectorAll("tagName") instead of document.querySelectorAll("[attributeName]").
With the second variable you found the first element with the ID of anchorLinks. The hashtag is needed to specify ID as querySelector represents div so the result is div#anchorLinks(?).
You then take the variable anchors (which results in an array of the data-anchor value of the div's with the data-anchor attribute) and for each of them, a function triggers where the d argument of the function equals the element ID of the elements with the data-anchor attribute. Everything within this function repeats for each of the elements with data-anchor attribute (ie. the variable anchors).
What's happening within the function is:
-You create a variable (a) which contains the element creation of an <a> element
-You then set the href attribute of the newly created <a> element to the ID
of the data-anchor elements.
-I then assign the attribute title of the <a> elements to the content of the data-anchor elements (instead of the original thought where it was textContent that was set to the <a> elements`as I want the links to be images instead of text)
-I then also added a new class attribute to the <a> elements in order to style them
If you used data-anchor="something" in your DIVs, then you should use
var anchors = document.querySelectorAll('[data-anchor]');
not [anchor].
You can then loop over them with forEach()
var anchorLinks = document.querySelector("#anchorLinks");
anchors.forEach(function(d) {
var a = document.createElement('a');
a.href = '#' + d.id;
a.textContent = 'Link to ' + d.textContent.toLowerCase();
anchorLinks.appendChild(a);
});
If you craft the query selector correctly you can get all of the "anchor" elements at once, then iterate over them to add the relevant links.
var links = document.getElementById('anchorLinks');
document.querySelectorAll('#anchors div[id]').forEach(function(anchor) {
var link = document.createElement('a');
link.href = '#' + anchor.id;
link.textContent = 'Link for ' + anchor.textContent;
links.appendChild(link);
});
<div id="anchors">
<div id="firstAnchor" style="display: inline-block;">First title</div>
<div id="secondAnchor" style="display: inline-block;">Second title</div>
<div id="thirdAnchor" style="display: inline-block;">Third title</div>
</div>
<div id="anchorLinks">
</div>
How about this:
document.getElementsByTagName('div').forEach(function(d) {
var a = document.createElement('a');
a.setAttribute('href', '#' + d.id);
a.innerHTML = 'Link to ' + d.textContent.toLowerCase();
document.getElementById('anchorLinks').appendChild(a);
});
Or if you have more divs (of course) and they have a specific class, you can do:
document.getElementsByClassName('your-class-name').forEach(function(d) {
var a = document.createElement('a');
a.setAttribute('href', '#' + d.id);
a.innerHTML = 'Link to ' + d.textContent.toLowerCase();
document.getElementById('anchorLinks').appendChild(a);
});

javascript create div and append it next to a child element without id

Using the solution suggested here: https://stackoverflow.com/a/32135318/10279127 i'm trying to create a new div, and append it inside a parent div with id, next to a child <a> html element.
html:
<div id="div0">
anchor text
// I'd like to place the new div here
</div>
js:
Element.prototype.appendAfter = function(element) {
element.parentNode.insertBefore(this, element.nextSibling);
}, false;
var NewElement = document.createElement('div');
NewElement.id = 'newDivID';
var tToAfter = $('#div' + index + ' > a'); // this is what i tried but doesn't work
NewElement.appendAfter(tToAfter);
If inside .appendAfter(...) instead of tToAfter i write document.getElementById('randomElementId') it works and appends it, so i think must be pure javascript, is there a way in js to do something like: document.getElementById('div' + index).firstChild to get the <a> ?
Or to make it entirely with jQuery using the insertAfter (https://stackoverflow.com/a/8707793/10279127) ?
you can select inside div#div0 by using
const anchor = document.querySelector("#div0>a");
You can simplify your approach by using insertAdjacentElement. For example (the css is irrelevant - just there so you can visually see the inserted div):
const anchor = document.querySelector('#div0 a');
const elem = document.createElement('div');
elem.id = 'newDivID';
anchor.insertAdjacentElement('afterend', elem);
div:not(#div0) {
height: 20px;
background-color: green;
}
<div id="div0">
anchor text
// I'd like to place the new div here
</div>

javascript function onclick with new elements

I work on a website, and I have a js problem.
I resume the situation:
I made a dynamic form with some tabs in.
I can switch tabs with a js click function
When I click on the "+" tab , it creates a new tab ( new <li> on the <ul>, and new <div> on main div )
But when I want to go on the new tab freshly created, the click function don't answer.
I put a console.log on the first line of the click function, and no log output.
the click function works well with static content, but with fresh content don't work.
How can I make it works with dynamic content ?
http://jsfiddle.net/npx2mes2/
http://jsfiddle.net/npx2mes2/1/
$("#tabs_menu_n1").on('click', 'a', function(e)
the problem was on registering the event, you should attach it to parent first, and then on every child.
change the line $(".tabs_menu_n1 a").click(function(e) { to $(document).on('click', ".tabs_menu_n1 a", function (e) {
Demo
Explanation.
when the elements are being added to DOM dynamically you must register the for the events every time the element is added. So instead of doing this process every time simply register events like below, therefore you don't want to register the events fro dynamically created elements
$(document).on('click', ".selector", function (e) {));
Now i can add elements with selector class dynamically and can handle click event on the element without registering the click event every time i add the element.
Note: You can use parent selector in place of document
A bit simplified sample without jQuery.
But idea same: add click handler to ul and check inside that clicked a tag.
var x = 2;
var original = document.getElementById('H1_n1');
function a(content, href) {
var link = document.createElement("a");
link.textContent = content;
link.setAttribute('href', href);
return link;
}
function li_a(id, content, href) {
var listItem = document.createElement("li");
listItem.setAttribute('id', id);
listItem.appendChild(a(content, href));
return listItem;
}
function div(id, textContent) {
var d = document.createElement("div");
d.setAttribute('class', 'tab_content_n1')
d.setAttribute('id', id)
d.textContent = textContent;
return d;
}
function add_rec() {
var i = x++;
var mdiv = document.getElementById("tab_n1");
mdiv.appendChild(div('H1_n' + i, '\nHello world from n' + i + '.\n'));
pbtn = document.getElementById('pbtn');
var ul = document.getElementById("tabs_menu_n1");
ul.insertBefore(li_a("hn" + i, "H" + i, "#H1_n" + i), pbtn);
}
document.getElementById('tabs_menu_n1').addEventListener('click', function(e) {
var el = e.target;
if (el.nodeName !== 'A') return;
if (el.hash == "#+") add_rec();
else {
e.preventDefault();
var current = document.querySelectorAll("#tabs_menu_n1 .current, #tab_n1 .current");
for (var i = 0, len = current.length; i < len; i++) {
current[i].classList.remove('current');
}
el.classList.add('current');
document.querySelector(el.hash).classList.add('current');
}
}, false);
.tab_content_n1 {
display: none;
}
.tab_content_n1.current {
display: block;
animation: fadeIn 1s;
}
a.current {
color: red;
}
#keyframes fadeIn {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
<div class="tab_space">
<ul id="tabs_menu_n1" class="nav nav-tabs tabs_menu_n1 tab_body">
<li><a class="current" href="#M_n1">mai</a>
</li>
<li>red
</li>
<li id="hn1">hor
</li>
<li id="pbtn">+
</li>
</ul>
</div>
<div id="tab_n1" class="tab_n1">
<div class="tab_content_n1 current" id="M_n1">mai</div>
<div class="tab_content_n1" id="R_n1">red</div>
<div class="tab_content_n1" id="H1_n1">hor</div>
</div>

How to add a class to a given element?

I have an element that already has a class:
<div class="someclass">
<img ... id="image1" name="image1" />
</div>
Now, I want to create a JavaScript function that will add a class to the div (not replace, but add).
How can I do that?
If you're only targeting modern browsers:
Use element.classList.add to add a class:
element.classList.add("my-class");
And element.classList.remove to remove a class:
element.classList.remove("my-class");
If you need to support Internet Explorer 9 or lower:
Add a space plus the name of your new class to the className property of the element. First, put an id on the element so you can easily get a reference.
<div id="div1" class="someclass">
<img ... id="image1" name="image1" />
</div>
Then
var d = document.getElementById("div1");
d.className += " otherclass";
Note the space before otherclass. It's important to include the space otherwise it compromises existing classes that come before it in the class list.
See also element.className on MDN.
The easiest way to do this without any framework is to use element.classList.add method.
var element = document.getElementById("div1");
element.classList.add("otherclass");
Edit:
And if you want to remove class from an element -
element.classList.remove("otherclass");
I prefer not having to add any empty space and duplicate entry handling myself (which is required when using the document.className approach). There are some browser limitations, but you can work around them using polyfills.
find your target element "d" however you wish and then:
d.className += ' additionalClass'; //note the space
you can wrap that in cleverer ways to check pre-existence, and check for space requirements etc..
Add Class
Cross Compatible
In the following example we add a classname to the <body> element. This is IE-8 compatible.
var a = document.body;
a.classList ? a.classList.add('classname') : a.className += ' classname';
This is shorthand for the following..
var a = document.body;
if (a.classList) {
a.classList.add('wait');
} else {
a.className += ' wait';
}
Performance
If your more concerned with performance over cross-compatibility you can shorten it to the following which is 4% faster.
var z = document.body;
document.body.classList.add('wait');
Convenience
Alternatively you could use jQuery but the resulting performance is significantly slower. 94% slower according to jsPerf
$('body').addClass('wait');
Removing the class
Performance
Using jQuery selectively is the best method for removing a class if your concerned with performance
var a = document.body, c = ' classname';
$(a).removeClass(c);
Without jQuery it's 32% slower
var a = document.body, c = ' classname';
a.className = a.className.replace( c, '' );
a.className = a.className + c;
References
jsPerf Test Case: Adding a Class
jsPerf Test Case: Removing a Class
Using Prototype
Element("document.body").ClassNames.add("classname")
Element("document.body").ClassNames.remove("classname")
Element("document.body").ClassNames.set("classname")
Using YUI
YAHOO.util.Dom.hasClass(document.body,"classname")
YAHOO.util.Dom.addClass(document.body,"classname")
YAHOO.util.Dom.removeClass(document.body,"classname")
Another approach to add the class to element using pure JavaScript
For adding class:
document.getElementById("div1").classList.add("classToBeAdded");
For removing class:
document.getElementById("div1").classList.remove("classToBeRemoved");
2 different ways to add class using JavaScript
JavaScript provides 2 different ways by which you can add classes to HTML elements:
Using element.classList.add() Method
Using className property
Using both methods you can add single or multiple classes at once.
1. Using element.classList.add() Method
var element = document.querySelector('.box');
// using add method
// adding single class
element.classList.add('color');
// adding multiple class
element.classList.add('border', 'shadow');
.box {
width: 200px;
height: 100px;
}
.color {
background: skyblue;
}
.border {
border: 2px solid black;
}
.shadow {
box-shadow: 5px 5px 5px gray;
}
<div class="box">My Box</div>
2. Using element.className Property
Note: Always use += operator and add a space before class name to add class with classList method.
var element = document.querySelector('.box');
// using className Property
// adding single class
element.className += ' color';
// adding multiple class
element.className += ' border shadow';
.box {
width: 200px;
height: 100px;
}
.color {
background: skyblue;
}
.border {
border: 2px solid black;
}
.shadow {
box-shadow: 5px 5px 5px gray;
}
<div class="box">My Box</div>
document.getElementById('some_id').className+=' someclassname'
OR:
document.getElementById('some_id').classList.add('someclassname')
First approach helped in adding the class when second approach didn't work.
Don't forget to keep a space in front of the ' someclassname' in the first approach.
For removal you can use:
document.getElementById('some_id').classList.remove('someclassname')
When the work I'm doing doesn't warrant using a library, I use these two functions:
function addClass( classname, element ) {
var cn = element.className;
//test for existance
if( cn.indexOf( classname ) != -1 ) {
return;
}
//add a space if the element already has class
if( cn != '' ) {
classname = ' '+classname;
}
element.className = cn+classname;
}
function removeClass( classname, element ) {
var cn = element.className;
var rxp = new RegExp( "\\s?\\b"+classname+"\\b", "g" );
cn = cn.replace( rxp, '' );
element.className = cn;
}
Assuming you're doing more than just adding this one class (eg, you've got asynchronous requests and so on going on as well), I'd recommend a library like Prototype or jQuery.
This will make just about everything you'll need to do (including this) very simple.
So let's say you've got jQuery on your page now, you could use code like this to add a class name to an element (on load, in this case):
$(document).ready( function() {
$('#div1').addClass( 'some_other_class' );
} );
Check out the jQuery API browser for other stuff.
You can use the classList.add OR classList.remove method to add/remove a class from a element.
var nameElem = document.getElementById("name")
nameElem.classList.add("anyclss")
The above code will add(and NOT replace) a class "anyclass" to nameElem.
Similarly you can use classList.remove() method to remove a class.
nameElem.classList.remove("anyclss")
To add an additional class to an element:
To add a class to an element, without removing/affecting existing values, append a space and the new classname, like so:
document.getElementById("MyElement").className += " MyClass";
To change all classes for an element:
To replace all existing classes with one or more new classes, set the className attribute:
document.getElementById("MyElement").className = "MyClass";
(You can use a space-delimited list to apply multiple classes.)
If you don't want to use jQuery and want to support older browsers:
function addClass(elem, clazz) {
if (!elemHasClass(elem, clazz)) {
elem.className += " " + clazz;
}
}
function elemHasClass(elem, clazz) {
return new RegExp("( |^)" + clazz + "( |$)").test(elem.className);
}
I too think that the fastest way is to use Element.prototype.classList as in es5: document.querySelector(".my.super-class").classList.add('new-class')
but in ie8 there is no such thing as Element.prototype.classList, anyway you can polyfill it with this snippet (fell free to edit and improve it):
if(Element.prototype.classList === void 0){
function DOMTokenList(classes, self){
typeof classes == "string" && (classes = classes.split(' '))
while(this.length){
Array.prototype.pop.apply(this);
}
Array.prototype.push.apply(this, classes);
this.__self__ = this.__self__ || self
}
DOMTokenList.prototype.item = function (index){
return this[index];
}
DOMTokenList.prototype.contains = function (myClass){
for(var i = this.length - 1; i >= 0 ; i--){
if(this[i] === myClass){
return true;
}
}
return false
}
DOMTokenList.prototype.add = function (newClass){
if(this.contains(newClass)){
return;
}
this.__self__.className += (this.__self__.className?" ":"")+newClass;
DOMTokenList.call(this, this.__self__.className)
}
DOMTokenList.prototype.remove = function (oldClass){
if(!this.contains(newClass)){
return;
}
this[this.indexOf(oldClass)] = undefined
this.__self__.className = this.join(' ').replace(/ +/, ' ')
DOMTokenList.call(this, this.__self__.className)
}
DOMTokenList.prototype.toggle = function (aClass){
this[this.contains(aClass)? 'remove' : 'add'](aClass)
return this.contains(aClass);
}
DOMTokenList.prototype.replace = function (oldClass, newClass){
this.contains(oldClass) && this.remove(oldClass) && this.add(newClass)
}
Object.defineProperty(Element.prototype, 'classList', {
get: function() {
return new DOMTokenList( this.className, this );
},
enumerable: false
})
}
To add, remove or check element classes in a simple way:
var uclass = {
exists: function(elem,className){var p = new RegExp('(^| )'+className+'( |$)');return (elem.className && elem.className.match(p));},
add: function(elem,className){if(uclass.exists(elem,className)){return true;}elem.className += ' '+className;},
remove: function(elem,className){var c = elem.className;var p = new RegExp('(^| )'+className+'( |$)');c = c.replace(p,' ').replace(/ /g,' ');elem.className = c;}
};
var elem = document.getElementById('someElem');
//Add a class, only if not exists yet.
uclass.add(elem,'someClass');
//Remove class
uclass.remove(elem,'someClass');
I know IE9 is shutdown officially and we can achieve it with element.classList as many told above but I just tried to learn how it works without classList with help of many answers above I could learn it.
Below code extends many answers above and improves them by avoiding adding duplicate classes.
function addClass(element,className){
var classArray = className.split(' ');
classArray.forEach(function (className) {
if(!hasClass(element,className)){
element.className += " "+className;
}
});
}
//this will add 5 only once
addClass(document.querySelector('#getbyid'),'3 4 5 5 5');
You can use modern approach similar to jQuery
If you need to change only one element, first one that JS will find in DOM, you can use this:
document.querySelector('.someclass').className += " red";
.red {
color: red;
}
<div class="someclass">
<p>This method will add class "red" only to first element in DOM</p>
</div>
<div class="someclass">
<p>lorem ipsum</p>
</div>
<div class="someclass">
<p>lorem ipsum</p>
</div>
<div class="someclass">
<p>lorem ipsum</p>
</div>
Keep in mind to leave one space before class name.
If you have multiple classes where you want to add new class, you can use it like this
document.querySelectorAll('.someclass').forEach(function(element) {
element.className += " red";
});
.red {
color: red;
}
<div class="someclass">
<p>This method will add class "red" to all elements in DOM that have "someclass" class.</p>
</div>
<div class="someclass">
<p>lorem ipsum</p>
</div>
<div class="someclass">
<p>lorem ipsum</p>
</div>
<div class="someclass">
<p>lorem ipsum</p>
</div>
This might be helpful for WordPress developers etc.
document.querySelector('[data-section="section-hb-button-1"] .ast-custom-button').classList.add('TryMyClass');
Just to elaborate on what others have said, multiple CSS classes are combined in a single string, delimited by spaces. Thus, if you wanted to hard-code it, it would simply look like this:
<div class="someClass otherClass yetAnotherClass">
<img ... id="image1" name="image1" />
</div>
From there you can easily derive the javascript necessary to add a new class... just append a space followed by the new class to the element's className property. Knowing this, you can also write a function to remove a class later should the need arise.
I think it's better to use pure JavaScript, which we can run on the DOM of the Browser.
Here is the functional way to use it. I have used ES6 but feel free to use ES5 and function expression or function definition, whichever suits your JavaScript StyleGuide.
'use strict'
const oldAdd = (element, className) => {
let classes = element.className.split(' ')
if (classes.indexOf(className) < 0) {
classes.push(className)
}
element.className = classes.join(' ')
}
const oldRemove = (element, className) => {
let classes = element.className.split(' ')
const idx = classes.indexOf(className)
if (idx > -1) {
classes.splice(idx, 1)
}
element.className = classes.join(' ')
}
const addClass = (element, className) => {
if (element.classList) {
element.classList.add(className)
} else {
oldAdd(element, className)
}
}
const removeClass = (element, className) => {
if (element.classList) {
element.classList.remove(className)
} else {
oldRemove(element, className)
}
}
Sample with pure JS. In first example we get our element's id and add e.g. 2 classes.
document.addEventListener('DOMContentLoaded', function() {
document.getElementsById('tabGroup').className = "anyClass1 anyClass2";
})
In second example we get element's class name and add 1 more.
document.addEventListener('DOMContentLoaded', function() {
document.getElementsByClassName('tabGroup')[0].className = "tabGroup ready";
})
For those using Lodash and wanting to update className string:
// get element reference
var elem = document.getElementById('myElement');
// add some classes. Eg. 'nav' and 'nav header'
elem.className = _.chain(elem.className).split(/[\s]+/).union(['nav','navHeader']).join(' ').value()
// remove the added classes
elem.className = _.chain(elem.className).split(/[\s]+/).difference(['nav','navHeader']).join(' ').value()
Shortest
image1.parentNode.className+=' box';
image1.parentNode.className+=' box';
.box { width: 100px; height:100px; background: red; }
<div class="someclass">
<img ... id="image1" name="image1" />
</div>
You can use the API querySelector to select your element and then create a function with the element and the new classname as parameters. Using classlist for modern browsers, else for IE8. Then you can call the function after an event.
//select the dom element
var addClassVar = document.querySelector('.someclass');
//define the addclass function
var addClass = function(el,className){
if (el.classList){
el.classList.add(className);
}
else {
el.className += ' ' + className;
}
};
//call the function
addClass(addClassVar, 'newClass');
In my case, I had more than one class called main-wrapper in the DOM, but I only wanted to affect the parent main-wrapper. Using :first Selector (https://api.jquery.com/first-selector/), I could select the first matched DOM element. This was the solution for me:
$(document).ready( function() {
$('.main-wrapper:first').addClass('homepage-redesign');
$('#deals-index > div:eq(0) > div:eq(1)').addClass('doubleheaderredesign');
} );
I also did the same thing for the second children of a specific div in my DOM as you can see in the code where I used $('#deals-index > div:eq(0) > div:eq(1)').addClass('doubleheaderredesign');.
NOTE: I used jQuery as you can see.
The majority of people use a .classList.add on a getElementById, but I i wanted to use it on a getElementByClassName. To do that, i was using a forEach like this :
document.getElementsByClassName("class-name").forEach(element => element.classList.add("new-class"));
But it didn't work because i discovered that getElementsByClassName returns a HTML collection and not an array. To handle that I converted it to an array with this code :
[...document.getElementsByClassName("class-name")].forEach(element => element.classList.add("new-class"));
first, give the div an id. Then, call function appendClass:
<script language="javascript">
function appendClass(elementId, classToAppend){
var oldClass = document.getElementById(elementId).getAttribute("class");
if (oldClass.indexOf(classToAdd) == -1)
{
document.getElementById(elementId).setAttribute("class", classToAppend);
}
}
</script>
This js code works for me
provides classname replacement
var DDCdiv = hEle.getElementBy.....
var cssCNs = DDCdiv.getAttribute('class');
var Ta = cssCNs.split(' '); //split into an array
for (var i=0; i< Ta.length;i++)
{
if (Ta[i] == 'visible'){
Ta[i] = 'hidden';
break;// quit for loop
}
else if (Ta[i] == 'hidden'){
Ta[i] = 'visible';
break;// quit for loop
}
}
DDCdiv.setAttribute('class',Ta.join(' ') ); // Join array with space and set class name
To add just use
var cssCNs = DDCdiv.getAttribute('class');
var Ta = cssCNs.split(' '); //split into an array
Ta.push('New class name');
// Ta.push('Another class name');//etc...
DDCdiv.setAttribute('class',Ta.join(' ') ); // Join array with space and set class name
To remove use
var cssCNs = DDCdiv.getAttribute('class');
var Ta = cssCNs.split(' '); //split into an array
for (var i=0; i< Ta.length;i++)
{
if (Ta[i] == 'visible'){
Ta.splice( i, 1 );
break;// quit for loop
}
}
DDCdiv.setAttribute('class',Ta.join(' ') ); // Join array with space and set class name
Hope this is helpful to sombody
In YUI, if you include yuidom, you can use
YAHOO.util.Dom.addClass('div1','className');
HTH

Categories

Resources