Assigning events to elements from getElementsByClassName - javascript

Javascript:
var myArr = document.getElementsByClassName('contItm');
for(i=0;i<myArr.length;i++){
myArr[i].onmouseover = function(){
document.getElementById(myArr[i].id + 'Mnu').style.display = "inline";
}
}
HTML:
<ul class="contMnu">
<li>
Accounts & Access
<ul id="reqAcctMnu" class="subContMnu" style="background-color:#cdcdcd">
<li>Sub1</li>
<li>sub2</li>
</ul>
</li>
</ul>
What I want to do is basically assign a function that will take in the ID of the href and add "Mnu" to it to target the ID of the ul below.
If I were writing this inside of each element this is how it would display but i want it to dynamically be added to all items with the classname
Accounts & Access

Bind the event to a parent element:
HTML:
<ul id="contMnu" class="contMnu"> ... </ul>
JavaScript
var menu = document.getElementById("contMnu");
menu.onmouseover = function(e){
console.log(e.target);
};
Using e.target to get the element that moused over and doing your logic there.
EXAMPLE

You have a problem with the famous "i" in the loop where it will be equal to myArr.length when the method is called. Below is one way around the problem.
var myArr = document.getElementsByClassName('contItm');
for(i=0;i<myArr.length;i++){
(function (elem) {
elem.onmouseover = function(){
document.getElementById(elem.id + 'Mnu').style.display = "inline";
};
})(myArr[i]);
}
without the reference to the elem, you can just use this.id inside
for(i=0;i<myArr.length;i++){
myArr[i].onmouseover = function(){
document.getElementById(this.id + 'Mnu').style.display = "inline";
};
}

Related

Is there any way to select elements in loop

I have a drop down menu created from li elements and each of them has a unique id. Instead of writing 4 different variables I want to create one loop (if possible and has sense) but I'm encountering a problem. After clicking on the particular li, the program should change the innerhtml with this li value.
function calories_calculator() {
const list = new Array(3);
list[0] = "1";
list[1] = "2"; /////// those numbers are id of li elements
list[2] = "3";
list[3] = "4";
const array = [];
for (var i = 0; i < list.length; i++) {
const f = document.getElementById(list[i]).onclick;
if (true) {
document.getElementById("display").innerHTML = list[i];
}
}
}
Is this what you want?
<ul>
<li id="id1"><button>aaaaa</button></li>
<li id="id2"><button>bbbbb</button></li>
<li id="id3"><button>ccccc</button></li>
<li id="id4"><button>ddddd</button></li>
</ul>
<div></div>
</body>
<script>
const elements = document.querySelectorAll('li')
elements.forEach(element => {
element.addEventListener('click' , () => {
document.querySelector('div').innerHTML = element.textContent;
})
})
</script>
</html>
It looks like there is a syntax issue with your "onclick" event handler. The onclick should be followed by an equal sign and then the function. I found this answer which might be useful:
Handling "onclick" event with pure JavaScript

How to remove an specific <li> with pure javascript

I'm trying to figure out, how am i able to delete a specific <li> with pure javascript ?
My purpose is: each <li> does have a "remove" button and if we click on that button, it will remove that <li>.
function remove(r){
**REMOVE**
}
function add(){
var ul = document.getElementById("ul");
var li = document.createElement("li");
if(document.getElementById("nameS").value && document.getElementById("mailS").value){
var nameS = document.createElement("i");
nameS.innerHTML = document.getElementById("nameS").value;
nameS.innerHTML += ": ";
var mailS = document.createElement("font");
mailS.setAttribute("color","#000080");
mailS.innerHTML = document.getElementById("mailS").value;
mailS.innerHTML += " - ";
if(document.getElementById("webpageS").value){
mailS.innerHTML += ""+document.getElementById("webpageS").value+"";
}
var element = document.createElement("input");
element.setAttribute("type","button");
element.setAttribute("value","Remover");
//element.setAttribute("onclick",remove());
element.addEventListener('click',function(){
li.remove();
},false);
li.appendChild(nameS);
li.appendChild(mailS);
li.appendChild(element);
ul.appendChild(li);
}
}
If you add your remove function using addEventListener as suggested by #Eevee, the first argument passed to remove will be an Event object. (For a click event, it will be a MouseEvent object.)
Every Event object has a property, target, which tells you where the element came from. So, you can simply go up the tree of elements to get the li, and remove that:
function removeParent(evt) {
evt.target.parentNode.remove();
}
element.addEventListener('click', removeParent, false);
Some other comments on your code:
Please don't ever use font elements; likewise i elements. You should use span if you want to apply styles; if you want to emphasise text, use em.
What i would do would be to add a unique id to each of the li's that you can later reference to remove it:
var curId = 0;
function add(){
....
var li = document.createElement("li");
li.setAttribute(id,curId)
...
curId++;
}
Then in your button pass that id
element.setAttribute("onclick",remove(curId));
Then for your remove function it is simply:
function remove(ele){
ducument.getElementById(ele).remove();
}

Getting the value of the clicked li element

First of all I'm adding an EventListener to the ul, as follows:
action_list_ul.addEventListener("click", set_ua_value, false);
The set_ua_value job is to:
• Listen to every click made on the ul childs (li elements)
• get the value (innerHTML?) of the a tag inside the clicked li
<ul id="action-list">
<li>foo</li>
<li>bar</li>
</ul>
In case foo was clicked on, I need to retrieve the "foo" string.
Since I'm fairly new to javascript, I'm not sure how to get the actual "this"
of the clicked li.
I do not want to use jQuery. Thanks :)
A quick and dirty way is to bind the event to the list, and filter by anchor tags:
JS
var action_list_ul = document.getElementById('action-list');
action_list_ul.addEventListener("click", set_ua_value, false);
function set_ua_value (e) {
if(e.target.nodeName == "A") {
console.log(e.target.innerHTML);
}
}
JS Bin
Alternately, you can filter by LI, and access the anchor through firstChild or childNodes[0].
Use something like:
var win = window, doc = document, bod = doc.getElementsByTagName('body')[0];
function E(e){
return doc.getElementById(e);
}
function actionListValue(element, func){
var cn = element.childNodes;
for(var i=0,l=cn.length; i<l; i++){
if(cn[i].nodeType === 1){
var nc = cn[i].childNodes;
for(var n=0,c=nc.length; n<c; n++){
if(nc[n].nodeType === 1){
nc[n].onclick = function(){
func(this.innerHTML);
}
}
}
}
}
}
actionListValue(E('action-list'), set_ua_value);
Here is an alternative:
var foo = document.getElementById("foo");
foo.addEventListener("click", modifyText);
function modifyText(e) {
console.log(e.target.innerHTML);
}
In this case the binding would have to be with the a elements.
<ul id="action-list">
<li>foo</li>
<li>bar</li>
</ul>
JS BIN

Anchor tag onclick using unobtrusive javascript

<li id="Account_Tab" class="bgrad">
<a class="bganch" title="Accounts Tab" href="/xxx/xxx">Accounts</a>
</li>
there are few other <li> tags in the similar way , How can i create an onclick function for the anchor tag,
not like: <a onclick="function()"......> is there any other approach other than inline Javascript?
You can add the handler like so:
function anchorClicked(){
console.log("clicked");
}
window.onload = function(){
var anchors = document.getElementsByClassName('bganch');
for(var i=0; i<anchors.length; i++){
anchors[i].onclick = anchorClicked;
}
};
The above adds the click event to elements with the bganch class.
Other options:
Give the anchor an ID and use document.getElementById('someid')
Get all anchors by the tag name using document.getElementsByTagName('a')
Try
window.onload = function(){
var anchors = document.getElementsByClassName('bganch');
var anchortitle= anchors.title;
};

How to iterate through ul list using Javascript?

I have the following HTML page (page is simplified here as it is a sample of the real one):
<html>
<head>
<script type="text/javascript" src="JavaScript/Painting.js"></script>
</head>
<body>
<div id="center-wrapper">
<div id="side-menu">
<ul>
<li><a onclick="Paint()">About</a></li>
<li><a onclick="Paint()">Contents</a></li>
<li><a onclick="Paint()">Visual</a></li>
<li><a onclick="Paint()">CSS</a></li>
<li><a onclick="Paint()">Javascript</a></li>
</ul>
</div>
</div>
</body>
</html>
And I have the Painting.js file (again, a bit simplified):
function Paint()
{
var e = window.event;
var sender;
if (e.target)
{
sender = e.target;
}
else
{
if (e.srcElement)
{
sender = e.srcElement;
}
}
for (element in sender.parentNode.parentNode.getElementsByTagName("a"))
{
element.style.color = 'blue';
element.style.backgroundColor = '#FFFFFF';
}
sender.style.color = '#FFFFFF';
sender.style.backgroundColor = '#000000';
}
The basic idea is:
Find a HTML element that caused the event.
Go up until you reach the <ul> element.
Loop through the list items; find the <a> tags and change their color and background
Upon exiting the loop, change the color and the background of the HTML element that caused the event.
Now, I can't seem to get to the part located in the for loop. I think I am making a mistake by calling GetElementsByTagName() method. Could you help me out? Thanks.
You should call getElementsByTagName() only once, caching the result.
Then iterate over the collection like this (instead of using for/in).
var a_elements = sender.parentNode.parentNode.getElementsByTagName("a");
for (var i = 0, len = a_elements.length; i < len; i++ ) {
a_elements[ i ].style.color = 'blue';
a_elements[ i ].style.backgroundColor = '#FFFFFF';
}
sender.style.color = '#FFFFFF';
sender.style.backgroundColor = '#000000';
To get the target, you can pass it as the parameter in the inline onclick:
<ul>
<li><a onclick="Paint(this)">About</a></li>
<li><a onclick="Paint(this)">Contents</a></li>
<li><a onclick="Paint(this)">Visual</a></li>
<li><a onclick="Paint(this)">CSS</a></li>
<li><a onclick="Paint(this)">Javascript</a></li>
</ul>
Then your javascript can look like this:
function Paint( sender ) {
var a_elements = sender.parentNode.parentNode.getElementsByTagName("a");
for (var i = 0, len = a_elements.length; i < len; i++ ) {
a_elements[ i ].style.color = 'blue';
a_elements[ i ].style.backgroundColor = '#FFFFFF';
}
sender.style.color = '#FFFFFF';
sender.style.backgroundColor = '#000000';
}
Example: http://jsbin.com/aroda3/
Basically:
In order to find the element which caused the event you have to add an identifier to the a or li element and then use it as a parameter to your function. For example:
<li id='id_li1'><a onclick="Paint(id_li1)">About</a></li>
You can also use the ul id as parameter for your function, so you can know which is the ul that you need. I supposed that you generate your ul dinamically:
<a onclick="Paint(id_li1, id_ul)">About</a>
Then you have the reference for the ul and you can implement a function to iterate on the list items and give to the function the ul node using the id_ul. For example:
function processUL(ul) {
if (!ul.childNodes || ul.childNodes.length == 0) return;
// Iterate LIs
for (var itemi=0;itemi<ul.childNodes.length;itemi++) {
var item = ul.childNodes[itemi];
if (item.nodeName == "LI") {
// Iterate things in this LI in the case that you need it put your code here to get the a element and change the color and background
.....
}
}
}
I know you can't use jQuery for this, but I thought I'd supply a solution for others that may be able to:
$(function(){
$("li a").click(function(){
$(this).parent().siblings().each(function(){
$(this).find("a").css({'color':'blue','background-color':'white'});
});
$(this).css({'color':'white','background-color':'black'});
return false;
});
});
You can get the ul element with document.getelementbyid and then use the "children" property of the element which is a list of the list elements inside it.
No. Getting links by getElementsByTagName("a") is your one-off web-developer solution.
You can also traverse the DOM properly by childNodes, and this solution generalizes to all UL lists you may have:
_($("#my-list")[0].childNodes).filter(function(node) { return node.nodeName == "LI"; })
It uses underscore and jQuery.

Categories