Getting index of a node on click - javascript

I'm trying get the index of a tab in YUI using delegate along with the indexOf method - specifically I want to remove a tab on the click of an image housed inside of an li element:
var tabView = new Y.TabView({
srcNode: '#data-table'
});
...
//creating tabs
...
var removeTab = function(e) {
var tabList = e.container.all('li'); //returns a list of the 'li' elements/tabs
tab = tabView.indexOf(e.currentTarget);
alert(tab); //returns -1 (node not found)
//tabView.remove(tab);
}
Y.one('#data-table').delegate('click', removeTab, 'img');//on click of the img, launch removeTab
I don't believe YUI has a simpler way of doing this-most guides I've found are outdated or don't implement removing tabs the same way.

The problem is that the delegate handler is set on img element - so e.currentTarget will refer to an <img> element (that was clicked).
With e.container.all('li'), however, you retrieve the collection of <li> elements. No element in this collection, naturally, can be equal to <img>. That's why indexOf fails.
One possible solution is finding the <li> parent of <img> element first, then check its index:
var liClicked = e.currentTarget.ancestor('li');
var tabIndex = tabList.indexOf(liClicked);

Related

Javascript remove item from DOM before rendering code

I'm trying to remove an element from my HTML document, which I'm able to do with the remove method, however, when console logging the NodeList with document.querySelectorAll() on some classes on elements that should've been removed, they're still showing up in the NodeList.
I need to remove an element from the webpage, but also from the NodeList, as if the element wasn't there initially on page load to prevent the rest of my application from thinking that it's there.
I would've thought that the remove method would've covered this, but unfortunately it doesn't, what am I missing and what's the workaround?
function removeElement (ident) {
const elem = document.querySelector(ident)
if (elem) {
elem.remove()
}
}
you have to get elements by their id name.
var elem = document.getElementById('myid');
elem.remove()
here 'myid' is the id of the item to be deleted.
if you want to delete it using query selector then take the help of elem's parent element.
let elem = document.querySelector(ident);
elem.parentElement.removeChild(elem);

Click to change inner child and other sections with Javascript/ES6

So I made this in Jquery:
Game Gallery
However I need to change it in Vanilla/ES6 and I'm a stuck on how to target the parents child on click and also find the index (.eq($(this).parent().index()) for other sections(copy and images section in my case):
My tryout was doing a for loop like:
const mode = document.querySelectorAll('.gamegallery span');
for (let i = 0; i < mode.length; i++) {
mode[i].onclick = function() {
this.parentNode.classList.toggle('active');
};
}
But it seems I'm missing something to get the parent to stay in sync with the icons because it sets .active but stays .active on all icons. I tried:
if {
this.parentNode.classList.add('active');
}
else {
this.parentNode.classList.remove('active');
}
Which does nothing...theres something else Im missing?
Lastly to also change a different section like the content/images I used:
$('.gamegallery .game-images img').eq($(this).parent().index()).addClass('active');
});
I basically need to do the same function all at once. Removing active to icons - content-images parents. Finding the first object and then go to the parents side and go to each index(which is the first one as default). node.parentNode.childNodes; is the one thing I found...I'll keep updating. Not asking to do it but more of what I'm missing from the code I added. Specifically the first part. Coming from a noob EcsMaScript/Modern Vanilla guy.
Rather than traversing the node hierarchy in search of the elements you want to toggle you can simplify it by specifying a target. This comes in handy if your clicked node's index doesn't match your intended target.
Checkout this Fiddle for a Demo
You can use the data- HTML attribute. For example: data-target=".xbox" could be applied to your span.circle element since that is what you're adding your click listener to.
<span class="circle" data-target=".xbox">
and add the class inside data-target to your, well, target:
<div class="swiper-slide xbox"></div>
and
<img src=".." class="xbox">
On click, you can pull your target from the element with: this.dataset and specify what you're looking for. In this case it is: const target = this.dataset.target.
With the target's selector found from the dataset we can find the elements with a selector:
const targets = document.querySelectorAll('.swipe-slider'+target+', .game-images '+target');
Once we have the target we can remove the current active class from our target's neighbors. In this case, though, I've simply removed it from all.
document.querySelectorAll('.swiper-slide, .game-images img').forEach(el => el.classList.remove('active'));
Then we add the active class with:
targets.forEach(target => target.classList.add('active');
Altogether now:
function handleClick(e) {
const target = this.dataset.target;
const targets = document.querySelectorAll('.swiper-slide'+target+', .game-images '+target);
document.querySelectorAll('.swiper-slide, .game-images img').forEach(el => el.classList.remove('active'));
targets.forEach(target => target.classList.add('active'));
}

Using event delegation and getting the object thats linked to the clicked child dom?

Im trying to attach an event listener to each li element, but instead I want to attach it to the parent ul, to avoid confusion, if I remove or add li elements.
var theParent = document.getElementById("parent-list");
theParent.addEventListener("click", function(e) {
// e.target is the clicked item!
if(e.target && e.target.nodeName == "LI") {
console.log("li has been clicked, cool!");
console.log("is this George or Smith!");
}
});
This works fine. However the way I add my li elements to the parent is by creating a custom object, as I need to hold some state information:
var Person = function(name, favColor){
var elem = document.createElement('li');
theParent.appendChild(elem);
this.name = name;
this.color = favColor;
};
var listItems = [];
listItems.push(new Person("Smith", "blue"));
listItems.push(new Person("George", "red"));
One of the solutions I was thinking is to add state information to the li elements by using data- attribute, but I feel like thats going to get messy If I am going to have so many properties.
right now your JavaScript object and dom elements are not connected at all. you are just using a JavaScript object to create the dom element.
data attribute is a good way to go, you can maybe just have a data attribute with an object index, and save all your objects in a JavaScript array. than on click, retrieve the JavaScript object with the correct index from the array.
Please let me know if this is enough to get you going or you need more.

Identify number of li from group of li onclick

I'm trying to identify a li element from a group of li inside of div
<div id="group">
<li></li>
<li></li>
<li></li>
</div>
its quite simple tho, i could give each li an unique id and this problem would be over. like
var listItem1,2,3 = document.getElementById('liItem1,2,3') etc
listItem1,2,3.addEventListener('click',function);
this might be handy when it comes to 1,2 or 3 elements but this is all static and when it start to scale its not possible anymore, Instead im trying to make use of NodeList.
var nodeList = document.getElementById('group').getElementsByTagName('li');
now i will have a NodeList with li 0, li 1, li 2
the problem comes now becouse i donĀ“t know how to trace which li is being clicked.
nodeList.addEventListener('click',function);
wont work here becouse it dosent know which one is being clicked at here.
nodeList[0].addEventListener('click',function);
is the same solution as above. How can i trace which of the li is being clicked at? only plain/raw javascript
To find the index of an element in response to an event, I'd suggest delegating the event-handling to an ancestor (rather than individually binding an event-handler to multiple child-elements):
// 'event' is passed in automagically (in non IE browsers, haven't tested IE):
function getIndexFrom(event){
// event.target is the element upon which the event was triggered:
var clicked = event.target,
// finding all the children of the parent of the clicked-element
// (could use 'this.children', as 'this' will be the 'ul' in this demo):
children = clicked.parentNode.children;
// iterating over those child elements:
for (var i = 0, len = children.length; i < len; i++){
// if the clicked element is the current element:
if (children[i] === clicked){
console.log('index is: ' + i)
// we return 'i' as the index:
return i;
}
}
// this shouldn't happen, assuming we're looking at the right group
// of elements, but it's there as an in-case and for debugging:
return false;
}
document.getElementById('group').addEventListener('click', getIndexFrom);
JS Fiddle demo.
References:
EventTarget.addEventListener().
for... loop.
ParentNode.children.

JavaScript Folding Menu Tree

This is a JavaScript function for menu tree. I would like to add more sub-menu in it, not only one sub-menu. What's x.all[0] and x.all[2]?
var head="display:''"
img1=new Image()
img1.src="fold.gif"
img2=new Image()
img2.src="open.gif"
function change(){
if(!document.all)
return
if (event.srcElement.id=="folding"){
var x=event.srcElement.parentElement
if (x.all[2].style.display=="none"){
x.all[0].src="open.gif"
x.all[2].style.display=''
alert(x.all[2].name )
}
else{
x.all[0].src="fold.gif"
x.all[2].style.display="none"
}
}
document.onclick=change
all is a collection of child elements belonging to a particular element. document.all returns all elements for a document. It is an IE only feature and will not work in other browsers.
In your code, x is event.srcElement.parentElement, so it's all property would be all the child elements belonging to that parent element. The [0] will return the first element in the collection and [2] will return the third element in the collection.
As mentioned before, this code will only work in Internet Explorer, so you should explore other cross browser methods to achieve what you're trying to do if you want better browser compatibility.

Categories

Resources