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 !");
}
});
Related
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));
}
})
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>
I have encountered a problem with expandable divs. Here is my code:
HTML:
<div>more...</div>
<div class="expand" style="display:none">
YO DAWgGG
</div>
JS:
<script type="text/javascript" charset="utf-8">
function showHide(elementid){
if (document.getElementsByClassName("expand").style.display == 'none'){
document.getElementsByClassName("expand").style.display = '';
} else {
document.getElementsByClassName("expand").style.display = 'none';
}
}
</script>
It says that expand is undefined. But I don't see why. What am I doing wrong? Same code works if i use an ID but i need this for more than one div.
Thanks!
You need to do document.getElementsByClassName("expand")[0] as getElementsByClassName returns an array of object.
function showHide(el){
if (document.getElementsByClassName(el)[0].style.display == 'none'){
document.getElementsByClassName(el)[0].style.display = '';
} else {
document.getElementsByClassName(el)[0].style.display = 'none';
}
}
<div>more...</div>
<div class="expand" style="display:none">
YO DAWgGG
</div>
Based on the existing markup. I recommend to use document.querySelectorAll, and instead of setting an elements style, toggle its class.
var links = document.querySelectorAll('.link');
for (var i=0; i<links.length; i++) {
links[i].addEventListener('click', function(e){
e.target.parentElement.nextElementSibling.classList.toggle('show');
})
}
.expand {
display: none;
}
.expand.show {
display: block;
}
<div><a class="link" href="#">more...</a></div>
<div class="expand">
YO DAWgGG 1111
</div>
<div><a class="link" href="#">more...</a></div>
<div class="expand">
YO DAWgGG 222
</div>
<div><a class="link" href="#">more...</a></div>
<div class="expand">
YO DAWgGG 333
</div>
document.getElementsByClassName returns you a HTMLCollection and not a HTMLElement and hence you cant use .style on the collection.
So, if you need to apply some styling on all elements of the collection, you need to iterate over and apply.
Here is what you could do.
document.addEventListener('DOMContentLoaded', function() {
let anchors = document.querySelectorAll(".more");
[].forEach.call(anchors, (anchor) => {
anchor.addEventListener("click", (event) => {
event.preventDefault();
let parent = event.target.parentNode;
let ele = parent.querySelector(".expand");
if (ele.style.display == 'none') {
ele.style.display = '';
} else {
ele.style.display = 'none';
}
})
})
});
<div><a class="more" href="#">more...</a>
<div class="expand" style="display:none">
YO DAWgGG
</div>
</div>
<div><a class="more" href="#">more-2-...</a>
<div class="expand" style="display:none">
YO DAWgGG-2
</div>
</div>
Need a bit of help with JS. I'm trying to figure out how to sort a pile of div's, using values of their children elements. I'v found a solution here on stack and tried to modify it a bit but with no luck so far.
Please, give me some advise. Thank you
The idea is to sort div.person according to their "age" element.
<!DOCTYPE html>
<html>
<head>
<title>Sort list items alphabetically with Javascript</title>
<script type="text/javascript">
function sortUnorderedList(div, sortDescending) {
if(typeof div == "number")
div = document.getElementById(div);
var lis = div.getElementsByClassName("person");
var vals = [];
for(var i = 0, l = lis.length; i < l; i++)
vals.push(lis[i].innerHTML);
vals.sort();
if(sortDescending)
vals.reverse();
for(var i = 0, l = lis.length; i < l; i++)
lis[i].innerHTML = vals[i];
}
window.onload = function() {
var desc = false;
document.getElementById("test").onclick = function() {
sortUnorderedList("list", desc);
desc = !desc;
return false;
}
}
</script>
</head>
<body>
<input type="button" id="test" value="Sort List"/>
<div id="list">
<div class="person">
<div>Jack</div>
<div>Plumber</div>
<div class="info">
<span class="age">24</span>
<span class="hair-color">Blonde</span>
</div>
</div>
<div class="person">
<div>Jill</div>
<div>Actress</div>
<div class="info">
<span class="age">18</span>
<span class="hair-color">Gray</span>
</div>
</div>
<div class="person">
<div>John</div>
<div>Driver</div>
<div class="info">
<span class="age">37</span>
<span class="hair-color">Brown</span>
</div>
</div>
</ul>
</body>
</html>
I changed the code a bit to make it more readable for myself.
First I get all the htmlNode by class name "person", though this will return a htmlCollection which is array-ish but not an array.
Therefore I convert it to an array on the next line so I can perform array-methods on it like 'sort'.
You can swap out the different compareFunctions I wrote for different kind of sorting.
After sorting I empty the existing content of the list-element, and fill it up again with for-loop.
function sortUnorderedList(list, sortDescending) {
var htmlCollection = list.getElementsByClassName("person"),
elements = [].slice.call(htmlCollection); //convert htmlCollection to array
//sort by ...
//elements.sort(compareNames);
//elements.sort(compareJobs);
elements.sort(compareAges);
if (sortDescending) elements.reverse();
list.innerHtml = ''; //remove current contents
for (var i = 0; i < elements.length; i++) {
list.appendChild(elements[i]); //add them again in different order
}
function compareNames(el1, el2) {
//innerText of the first child of each element is the name
if (el1.children[0].innerText < el2.children[0].innerText) return -1;
if (el1.children[0].innerText > el2.children[0].innerText) return 1;
return 0;
}
function compareJobs(el1, el2) {
//innerText of the second child of each element is the job
if (el1.children[1].innerText < el2.children[1].innerText) return -1;
if (el1.children[1].innerText > el2.children[1].innerText) return 1;
return 0;
}
function compareAges(el1, el2) {
var age1 = parseInt(el1.children[2].children[0].innerText),
age2 = parseInt(el2.children[2].children[0].innerText);
if(isNaN(age1))age1=-1;
if(isNaN(age2))age2=-1;
return age1 - age2;
}
}
window.onload = function() {
var desc = false;
document.getElementById("test").onclick = function() {
sortUnorderedList(document.getElementById('list'), desc);
desc = !desc;
return false;
};
};
<!DOCTYPE html>
<html>
<head>
<title>Sort list items alphabetically with Javascript</title>
</head>
<body>
<input type="button" id="test" value="Sort List" />
<div id="list">
<div class="person">
<div>Jack</div>
<div>Plumber</div>
<div class="info">
<span class="age">24</span>
<span class="hair-color">Blonde</span>
</div>
</div>
<div class="person">
<div>Jill</div>
<div>Actress</div>
<div class="info">
<span class="age">0</span>
<span class="hair-color">Gray</span>
</div>
</div>
<div class="person">
<div>John</div>
<div>Driver</div>
<div class="info">
<span class="age"></span>
<span class="hair-color">Brown</span>
</div>
</div>
</ul>
</body>
</html>
I have the following list of divs and I'd like to be able to sort them using Javascript / JQuery.
<div class="item">
<div class="genre">Classical</div>
<div class="name">Alpha</div>
<div class="location">London</div>
</div>
<div class="item">
<div class="genre">Blues</div>
<div class="name">Bravo</div>
<div class="location">New York</div>
</div>
<div class="item">
<div class="genre">Pop</div>
<div class="name">Charlie</div>
<div class="location">Paris</div>
</div>
<div class="buttons">
Sort by Genre
Sort by Name
Sort by Location
</div>
I'd like to be able to sort the items by their Genre/Name/Location alphabetically.
Example: If Sort by Genre was clicked, it would sort the items in 0-9 A-Z by Genre.
If any of you have any tips it would greatly be appreciated.
Cheers :)
You have to make a little change to html like following:
<div id="container">
<div class="item">
<div class="genre">Classical</div>
<div class="name">Alpha</div>
<div class="location">London</div>
</div>
<div class="item">
<div class="genre">Blues</div>
<div class="name">Bravo</div>
<div class="location">New York</div>
</div>
<div class="item">
<div class="genre">Pop</div>
<div class="name">Charlie</div>
<div class="location">Paris</div>
</div>
</div>
<div class="buttons">
Sort by Genre
Sort by Name
Sort by Location
</div>
jQuery
function sorting(tag) {
var items = $('div.item').sort(function(a, b) {
var txt1 = $.trim($('div.' + tag, a).text()),
txt2 = $.trim($('div.' + tag, b).text());
if (txt1 > txt2) return 1;
else return -1;
});
return items;
}
$('.buttons a').on('click', function(e) {
e.preventDefault();
$('div#container').html(sorting(this.id));
});
Working Sample
Ok, this would be my pure JS solution.
First, we should wrap your <div>s into a larger container.
<div id = "wrapper">
<div id = "item">...</div>
<div id = "item">...</div>
<div id = "item">...</div>
</div>
Now, let's define a constant - which property do you want to sort it by? (this will probably be a function parameter later in your code).
var propName = "genre";
Let's get all the <div>s and put them in an array.
var items = document.getElementsByClassName("item");
var itemsArray = new Array();
Let us sort them lexicographically according to the text of the selected property.
for (var i = 0; i < items.length; i++)
itemsArray.push(items[i]);
itemsArray.sort(function(a, b) {
var aProp = a.getElementsByClassName(propName)[0].firstChild.nodeValue;
var bProp = b.getElementsByClassName(propName)[0] .firstChild.nodeValue;
if (aProp < bProp)
return -1;
else if (aProp > bProp)
return 1;
else
return 0;
});
Let us construct a document fragment consisting of the sorted <div>s.
var fragment = document.createDocumentFragment();
for (var i = 0; i < itemsArray.length; i++)
fragment.appendChild(itemsArray[i].clone());
Finally, let us clear the contents of the <div id = "wrapper"> and replace it with the document fragment.
document.getElementById('wrapper').innerHTML = '';
document.getElementById('wrapper').appendChild(fragment);
Also, note that document.getElementsByClassName does not work in IE<9, but I was now really lazy to cope with that issue.
A fiddle: http://jsfiddle.net/nNXr4/
Check this beast:
function sortByCreatedOnAsc(a,b){
return $(a).find('.created_on').text() > $(b).find('.created_on').text();
}
function sortByCreatedOnDesc(a,b){
return $(a).find('.created_on').text() < $(b).find('.created_on').text();
}
function reorderEl(el){
var container = $('#tasks');
container.html('');
el.each(function(){
$(this).appendTo(container);
});
}
$('#created_on').click(function(){
if($(this).hasClass("asc")){
reorderEl($('.task').sort(sortByCreatedOnDesc));
$(this).removeClass("asc");
$(this).addClass("desc");
} else {
reorderEl($('.task').sort(sortByCreatedOnAsc));
$(this).removeClass("desc");
$(this).addClass("asc");
}
return false;
});
jsfiddle: http://jsfiddle.net/jKJc3/116/