Pass multiple elements to an each function - javascript

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") );

Related

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.

to attach an event to each element of an array

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();
});

Get ID of Element Being Clicked and Pass as Parameter?

How does one, through jQuery, get the ID of an element that is being clicked on and then pass it as a parameter into a function? Example jQuery code below.
jQuery(document).ready(function() {
var id = this_id;
jQuery(".lightbox a").click({param: id}, functionName);
});
May I note that the "param" parameter is integral to the structure of the function.
Apologies all, I am no Javascript master by any means.
I'm guessing the point is to pass event data to a function that expects that, as ,click() supports the .click( [eventData ], handler(eventObject) ) syntax, and if so, you have to iterate the collection yourself:
jQuery(document).ready(function($) {
$(".lightbox a").each(function() {
$(this).click({param: this.id}, functionName);
});
});
EDIT:
You could do this with on() as well:
jQuery(document).ready(function($) {
$(".lightbox a").each(function() {
$(this).on('click', {param: this.id}, functionName);
});
});
FIDDLE
Within the click handler, you can access the element ID with this.id or $(this).attr('id'):
jQuery(document).ready(function() {
jQuery(".lightbox a").click(function(){
functionName(this.id);
});
});
You can use this.id inside a click event, example:
jQuery(".lightbox a").click(function() {
var id = this.id;
//pass to a function
testFunction(id);
});
function testFunction(param) {
console.log(param);
}
It's easy just access to the this element to get the clicked element, then extract its id and save it into a variable like this:
jQuery(".lightbox a").click(function(){
var id = jQuery(this).attr("id");
callFunction(id);
});
http://jsfiddle.net/pArW6/
jQuery(document).ready(function() {
jQuery(".lightbox a").click(functionName);
});
function functionName()
{
alert(this.id);
}
You can you Use $(this).att("id").
$(".lightbox a").click(function() {
var ID=$(this).att("id");
//pass to a function
TestFunction(ID);
});
function TestFunction(P) {
console.log(P);
}
Live example
http://jsbin.com/enobop/1/edit
You can do this:
jQuery(document).ready(function () {
jQuery(".lightbox a").click(function (e) {
// Cancel the default action (navigation) of the click.
e.preventDefault();
// 'this' here refers to the link being clicked in the current scope
// you can check the console for the id for debug purpose
console.log(this.id);
// pass the id to the function
functionName(this.id);
});
});
Another way is to use the event parameter that gets passed to the callback function.
jQuery(".lightbox a").click(function(ev) {
console.log(ev.target.id);
}
Of course it's a mix of jQuery and pure JS.
Usually you have a function for an event declared with
function(event)
and the event has a target and the id of the target is, what you want. So
$("SomeElement").on("click", function(e){ callanotherFunction(e.target.id) })
does, what you wanted
You can use this.id or $(this).attr("id");, but you might want to get a reference to $(this) - wrapped or not - immediately and work from a variable if you do much of anything else in there.

Binding a function that is already bound to another element

I have a bunch of elements that get three different classes: neutral, markedV and markedX. When a user clicks one of these elements, the classes toggle once: neutral -> markedV -> markedX -> neutral. Every click will switch the class and execute a function.
$(document).ready(function(){
$(".neutral").click(function markV(event) {
alert("Good!");
$(this).addClass("markedV").removeClass("neutral");
$(this).unbind("click");
$(this).click(markX(event));
});
$(".markedV").click(function markX(event) {
alert("Bad!");
$(this).addClass("markedX").removeClass("markedV");
$(this).unbind("click");
$(this).click(neutral(event));
});
$(".markedX").click(function neutral(event) {
alert("Ok!");
$(this).addClass("neutral").removeClass("markedX");
$(this).unbind("click");
$(this).click(markV(event));
});
});
But obviously this doesn't work. I think I have three obstacles:
How to properly bind the changing element to the already defined function, sometimes before it's actually defined?
How to make sure to pass the event to the newly bound function [I guess it's NOT accomplished by sending 'event' to the function like in markX(event)]
The whole thing looks repetitive, the only thing that's changing is the alert action (Though each function will act differently, not necessarily alert). Is there a more elegant solution to this?
There's no need to constantly bind and unbind the event handler.
You should have one handler for all these options:
$(document).ready(function() {
var classes = ['neutral', 'markedV', 'markedX'],
methods = {
neutral: function (e) { alert('Good!') },
markedV: function (e) { alert('Bad!') },
markedX: function (e) { alert('Ok!') },
};
$( '.' + classes.join(',.') ).click(function (e) {
var $this = $(this);
$.each(classes, function (i, v) {
if ( $this.hasClass(v) ) {
methods[v].call(this, e);
$this.removeClass(v).addClass( classes[i + 1] || classes[0] );
return false;
}
});
});
});
Here's the fiddle: http://jsfiddle.net/m3CyX/
For such cases you need to attach the event to a higher parent and Delegate the event .
Remember that events are attached to the Elements and not to the classes.
Try this approach
$(document).ready(function () {
$(document).on('click', function (e) {
var $target = e.target;
if ($target.hasClass('markedV')) {
alert("Good!");
$target.addClass("markedV").removeClass("neutral");
} else if ($target.hasClass('markedV')) {
alert("Bad!");
$target.addClass("markedX").removeClass("markedV");
} else if ($target.hasClass('markedX')) {
alert("Ok!");
$target.addClass("neutral").removeClass("markedX");
}
});
});
OR as #Bergi Suggested
$(document).ready(function () {
$(document).on('click', 'markedV',function (e) {
alert("Good!");
$(this).addClass("markedV").removeClass("neutral");
});
$(document).on('click', 'markedX',function (e) {
alert("Bad!");
$(this).addClass("markedX").removeClass("markedV");
});
$(document).on('click', 'neutral',function (e) {
alert("Ok!");
$(this).addClass("neutral").removeClass("markedX");
});
});
Here document can be replaced with any static parent container..
How to properly bind the changing element to the already defined function, sometimes before it's actually defined?
You don't bind elements to functions, you bind handler functions to events on elements. You can't use a function before it is defined (yet you might use a function above the location in the code where it was declared - called "hoisting").
How to make sure to pass the event to the newly bound function [I guess it's NOT accomplished by sending 'event' to the function like in markX(event)]
That is what happens implicitly when the handler is called. You only need to pass the function - do not call it! Yet your problem is that you cannot access the named function expressions from outside.
The whole thing looks repetitive, the only thing that's changing is the alert action (Though each function will act differently, not necessarily alert). Is there a more elegant solution to this?
Yes. Use only one handler, and decide dynamically what to do in the current state. Do not steadily bind and unbind handlers. Or use event delegation.

Toggling Classes Voids the Event function?

I thought this would work, but whenever I click on the element with the class name of one and it changes to the class named two, I can't get the second event to work. What am I missing here?
//first event
$('.one').on('click', function () {
$('.one').attr('class', 'two');
});
//second event
$('.two').on('click', function () {
$('.two').attr('class', 'one');
});
You need to delegate the event to a static parent..
The problem is , because you seem to dynamically change the class you need to bind the event every single time you change the class.. So delegating it should remove this problem..
Also You can write this as a Single event..
$('body').on('click','.one' , '.two', function() {
if( $(this).hasClass('one'){
function1();
}
else if( $(this).hasClass('two'){
function2();
}
$(this).toggleClass('one two');
});
Why not more simple :) http://jsfiddle.net/XZeNE/1/ or this http://jsfiddle.net/4mJJe/
use API - toggleClass
Further HTML CHange Dmeo http://jsfiddle.net/vuLQK/1/
code
$('.one').on('click', function() {
$(this).toggleClass('two');
});​
HTML change
$('.one').on('click', function() {
$(this).toggleClass(function(){
if($(this).hasClass('two'))
$(this).html('NOw its class two HTML HULK');
else
$(this).html('CLASS ONE HTML IRONMAN' );
return "two";
})
});
​
You should use .on to attach to one of the ancestors of the 2 elements and then use the selector argument to match the event target. The selectors won't match elements that aren't present when the handlers are bound.
$(function () {
$("#container").delegate(".one", "click", function () {
$(this).attr('class', 'two');
});
$("#container").delegate(".two", "click", function () {
$(this).attr('class', 'one');
});
})

Categories