to attach an event to each element of an array - javascript

I have made several icon, and on their mouse hover they should do something. Now, I have made an array of my Icons, but as I apply each() to the set, it does not work:
So i need the following block of code to attach a hover event to each element of the set.
var icon_set = new Array('.icon-online', '.icon-save', '.icon-sms',
'.icon-access', '.icon-support');
icon_set.each(function () {
$(this).mouseleave(function () {
img.stop().fadeOut();
});
});

Try Array.join()
var icon_set = new Array('.icon-online', '.icon-save', '.icon-sms',
'.icon-access', '.icon-support');
$(icon_set.join()).mouseleave(function () {
img.stop().fadeOut();
});
icon_set.each(function () { --> .each() doesn't work with array
Use jQuery.each() , array.forEach(callback[, thisArg]) for array.

icon_set is a raw JavaScript Array. It doesn't have an each method. Use Array.prototype.forEach or $.each and wrap each array element with $();
icon_set.forEach(function (el) {
$(el).mouseleave(function () {
$(this).stop().fadeOut();
});
});
or
$.each(icon_set, function(index, el) {
$(el).mouseleave(function () {
$(this).stop().fadeOut();
});
});
And prefer using the array literal syntax([]) over the Array constructor
['.icon-online', '.icon-save',
'.icon-sms','.icon-access', '.icon-support'].forEach(yourMouseleaveHandler);

If all your icons have a classname that begin with icon- you can use this Jquery Starts With Selector
$('*[className^="icon-"]').mouseleave(function() {
// Do something
});
PS: It will select all icons which begin with icon-. It depends, you may/may not want that.

Just as an alternative, why not give those images another class which is the same for all, then your selector becomes much simpler, i.e for a new class of myImgs.
$('.myImgs').mouseleave(function() {
$(this).stop().fadeOut();
});

Related

Uncaught TypeError: e.nextElementSibling.fadeToggle is not a function

I've got error:
Uncaught TypeError: e.nextElementSibling.fadeToggle is not a function
at HTMLSpanElement.e.addEventListener
The weird thing is when I change: el.nextElementSibling.fadeToggle() to: el.nextElementSibling.remove() - everything works fine. Any ideas?
$(function () {
const spans = $('span');
const lists = $('ul')
const newArr = [];
for (x of spans) {
newArr.push(x);
}
newArr.forEach(fn)
function fn(el) {
el.addEventListener('click', () => el.nextElementSibling.fadeToggle();
)
}
})
Why would you do this? jQuery was designed specifically to do things in a nice and concise manner without unpacking/repacking:
$(() => {
const fade = function() {
let el = this.nextSibling;
if (el) $(el).toggleFade();
};
$('span').click(fade);
});
And we're done.
You can use almost any jQuery function on the result of a jQuery selection. Just make sure that you are absolutey not using an arrow function, because arrow functions are explicitly meant to preserve what this means based on the scope it's declared in, which is the opposite of what you want to have happen when you're using jQuery.
The reason why .remove works is that because it's built-in in the ChildNode API. However, fadeToggle() is jQuery-only. You have to "jquerize" your element to make your code work (include it in $(...)). Like this:
// toggle the next sibling every 2s
setInterval(() => {
$('ul').each(function() {
$(this.nextElementSibling).fadeToggle();
});
}, 2000);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul>
<li>some</li>
<li>list</li>
</ul>
<div>
the <code>nextElementSibling</code> of the list
</div>
fadeToogle is likely a jQuery method, while nextElementSibling is a regular DOM element.
You'd have to wrap it up in jQuery to use jQuery methods, as in
$(el.nextElementSibling).fadeToggle()
The real question is why are you doing this at all, when you could do
$(function() {
$('span').on('click', function() {
$(this).next().fadeToggle();
});
});
The reason remove() works, is because there's both a jQuery version and a native version that works the same way, so with a regular DOM element you're calling the native remove(), not jQuery's version.

Is there an opposite of keyword this?

Is there a keyword that is opposite to the keyword this?
$('.lt-buttonContainer button').click(function () {
var $this = $(this);
$this.addClass("button1Clicked");
$!this.removeClass("button1Clicked");
})
There is no built in method to get all the other elements. Use not() to remove it from the collection.
var buttons = $('.lt-buttonContainer button');
buttons.click(function () {
var $this = $(this);
$this.addClass("button1Clicked");
buttons.not($this).removeClass("button1Clicked");
});
No, there is not a keyword that is the opposite of this in your context.
!this simply takes the logical not of the value of this which will not solve the problem in your code.
Your question could really stand for some clarification, but in your specific example, if you want all elements that were in the original collection, but are not the current value of this and that' what you meant by opposite, then you have to compute that collection yourself.
That could be accomplished like this:
$('.lt-buttonContainer button').click(function () {
$('.lt-buttonContainer button').removeClass("button1Clicked");
$(this).addClass("button1Clicked");
});
Or, if you really want a collection of the elements in the original collection that are not this, then you can do this:
$('.lt-buttonContainer button').click(function () {
$('.lt-buttonContainer button').not(this).removeClass("button1Clicked");
$(this).addClass("button1Clicked");
});
though the extra .not() operation in this second code snippet is not required in this specific case because it does no harm to .removeClass() from all objects in the collection before adding it back on one.
Does following snippet help ?
$('.lt-buttonContainer button').click(function () {
var $this = $(this);
$('.lt-buttonContainer button').removeClass ("button1Clicked");
$this.addClass("button1Clicked");
})
You could use toggleClass() jq method and delegate event using following logic:
$('.lt-buttonContainer').on('click', 'button:not(.button1Clicked)', function (e) {
$(e.delegateTarget).find('button.button1Clicked').add(this).toggleClass("button1Clicked");
});
And if elements button are siblings:
$('.lt-buttonContainer').on('click', 'button:not(.button1Clicked)', function () {
$(this).siblings('button.button1Clicked').add(this).toggleClass("button1Clicked");
});

Chaging document.getElementById to getElementsByClassName

I have the following function that I would like to work with a class "pause" instead of an id.
I did see a few topics about this however I didn't quite understand how would this work.
Thanks!!!
function onPlayerReady(event) {
document.getElementById('pause').onclick = function() {
youtubePlayer1.pauseVideo();
youtubePlayer2.pauseVideo();
youtubePlayer3.pauseVideo();
e.preventDefault();
};
};
Using jQuery you can attach a click handler to all elements that have the pause class.
$(".pause").on("click", function () {
youtubePlayer1.pauseVideo();
youtubePlayer2.pauseVideo();
youtubePlayer3.pauseVideo();
e.preventDefault();
});
As you can guess from the name, the getElementsByClassName() function can return multiple (or zero) results. This is because element ids must be unique, but many different elements can have the same class.
So all you need to do is iterate over the results and add the click handler as before:
function onPlayerReady(event) {
var elem = document.getElementById('pause')
for(var i in elem) {
elem[i].onclick = function() {
youtubePlayer1.pauseVideo();
youtubePlayer2.pauseVideo();
youtubePlayer3.pauseVideo();
e.preventDefault();
}
}
};
Even though you only expect a single result, this is how you should do it to prevent errors.

Pass multiple elements to an each function

function generalShowPopup(click_element, show_elements) {
click_element.on("click", function(event) {
show_elements.each(function() {
$(this).show();
});
event.preventDefault();
});
}
With the above function I intend to show an element when a certain link is clicked.
Calling the function like this (one second argument) works fine:
generalShowPopup($(".popup_link"), $(".popup") );
But how could I pass two elements to the second argument, i.e show two elements when a certain link is clicked?
Just use a comma, ,, inside the selector string, and there really is no reason to use .each():
generalShowPopup($(".popup_link"), $(".popup,.selecctor2, #selector3") );
No need to use each:
function generalShowPopup(click_element, show_elements) {
click_element.on("click", function(event) {
event.preventDefault();
show_elements.show();
});
}
A quicker way to write all this is:
$(function() {
$(".popup_link").on('click', function(event) {
event.preventDefault();
$(".popup,.selecctor2, #selector3").show();
});
});
$(".popup") is a jQuery Collection,
Just use .add() method:
generalShowPopup($(".popup_link"), $(".popup").add(".another") );

Remove class using index

This might be easy but I am having trouble in getting it to work. I am using .each() to iterate through a list. I was wondering if it is possible to remove a class using the index.
eg. If there were 10 items in the list and I want to remove the class from the 5th element when I click the 8th element for example.
$(function () {
var items = $('#v-nav>ul>li').each(function (index) {
$(this).click(function () {
if (index = 8)
{
$(#5).removeClass('class');
}
});
});
Anyone with any ideas? Thank you
Change
$(#5).removeClass('class');
To
$('#v-nav>ul>li:eq(4)').removeClass('class');
Its better to assign the element returned by your selector to do the same processing again to get desired element.
$(function () {
var items = $('#v-nav>ul>li')
$('#v-nav>ul>li').click(function () {
if ($(this).index() = 8)
{
$(items).eq(4).removeClass('class');
}
});
});
There's no need to iterate with each(), as each element already has an index, and using eq() will let you select elements based on the index they have in the DOM. This solution is dependant on the elements being siblings() etc.
$(function () {
var elems = $('#v-nav>ul>li');
elems.on('click', function() {
if ($(this).index()==8) elems.eq(4).removeClass('class');
});
});
You could also just bind the click to that one element:
$(function () {
$('#v-nav>ul>li:eq(7)').on('click', function() {
$(this).siblings().filter(':eq(4)').removeClass('class');
});
});
Otherwise I would just do:
$(function () {
var elems = $('#v-nav>ul>li');
$.each(elems, function(idx, elm) {
if (idx==8) elems.eq(4).removeClass('class');
});
});
As a sidenote ID's consisting of just a number (or starting with a number) is invalid.
Actually you don't need to iterate over all the li elements, instead you can do it like this way
$(function(){
$('#v-nav>ul>li').eq(7).on('click', function(){ // eq(7) is 8th li
$(this).closest('ul').find('li').eq(4).removeClass('cls'); //eq(4) is 5th li
});
});
DEMO.

Categories