target specific class onclick - javascript

Hi I have 2 classes which have an on click event on it, How can I target the event on click that would not affect the other class. Basically let's say I have two classes of scroller-right, I just want to affect the class that is being click.
This what I have so far
$('.scroller-right').click(function(e) {
$('.scroller-left').fadeIn('slow');
$('.scroller-right').fadeOut('slow');
$('.tab-scroll').animate({left:"+="+widthOfHidden()+"px"},'slow',function(){
});
});
$('.scroller-left').click(function() {
$('.scroller-right').fadeIn('slow');
$('.scroller-left').fadeOut('slow');
$('.tab-scroll').animate({left:"-="+getLeftPosi()+"px"},'slow',function(){
});
});

try to use '$(this)' variable inside function liek below
$('.scroller-left').click(function() {
$('.scroller-right').fadeIn('slow');
$(this).fadeOut('slow');
});

You correctly observed that you need a single function. As a result, we need to write a function which can handle both cases and add it as a handler for both.
function scrollerClick(e) {
var isLeft = $(this).hasClass("scroller-left");
$('.scroller-' + (isLeft ? "left" : "right")).fadeIn('slow');
$('.scroller-' + (!isLeft ? "left" : "right")).fadeOut('slow');
$('.tab-scroll').animate({left:"+="+widthOfHidden()+"px"},'slow',function(){
});
}
$('.scroller-right, .scroller-left').click(scrollerClick);

Related

jQuery add/remove class using 'this'

I'm trying to append a class to a div when its click and remove when its clicked a second time I currently have this has my script -
$(".project").click(function(){
if ($(".project-expand", this).is(':visible')) {
$(".project-expand",this).hide(1000);
$('.project').delay(1000).queue(function(){
$(".project").removeClass('item-dropped').clearQueue();
});
} else if ($(".project-expand", this).is(':hidden')) {
$(".project-expand").hide(1000);
$(".project-expand",this).show(1000);
$(".project").addClass('item-dropped');
}
});
But this adds the "item-dropped" class to all of my divs that have a class "project" when I change the code to -
$(".project", this).addClass('item-dropped');
It doesn't do anything, where am I going wrong here?
Instead of using the class selector $('.project') you could simply use the target of the click event ($(this)):
$(".project").click(function () {
var project = $(this);
var projectExpand = $(".project-expand", this);
if (projectExpand.is(':visible')) {
projectExpand.hide(1000);
project.delay(1000).queue(function () {
project.removeClass('item-dropped').clearQueue();
});
} else if (projectExpand.is(':hidden')) {
$(".project-expand").hide(1000);
projectExpand.show(1000);
project.addClass('item-dropped');
}
});
Additional Info :
The reason what you were trying to do didn't work originally is because $('.project', this) looks for elements with class project inside the current element (i.e. looking for a project inside a project)
You have to use $(this) to add class on the clicked item:
$(".project").click(function(){
if ($(".project-expand", this).is(':visible')) {
$(".project-expand",this).hide(1000);
$(this).delay(1000).queue(function(){
$(this).removeClass('item-dropped').clearQueue(); // Here
});
} else if ($(".project-expand", this).is(':hidden')) {
$(".project-expand").hide(1000);
$(".project-expand",this).show(1000);
$(this).addClass('item-dropped'); // Here
}
});
you have to use :
$(this).addClass('item-dropped');
concept fiddle

click event not working when changing id or class

I'm starting with jquery, and have an issue here:
http://jsfiddle.net/8guzD/
$('#test.off').click(function(){
$(this).removeClass('off').addClass('on');
});
$('#test.on').click(function(){
$(this).removeClass('on').addClass('off');
alert('ok');
});
the first part of the code goes well, the class is apply, but when I attach an event in this element with its new class it won't work.
Can someone explain me what is the problem exactly?
I tried with javascript,
http://jsfiddle.net/R5NRz/
var element = document.getElementById('test');
element.addEventListener('click', function() {
this.id ='test2';
alert("ok");
}, false);
var element2 = document.getElementById('test2');
element2.addEventListener('click', function() {
alert("ok2");
}, false);
and it didn't really help me, having the same issue
try
$(document).on("click",'#test.on',function(){
$(this).removeClass('off').addClass('on');
alert('ok');
});
$(document).on("click",'#test.off',function(){
$(this).removeClass('off').addClass('on');
alert('ok passs');
});
Demo
In your jQuery example you are binding to DOM elements that exist at that time. That is why you see the first fire but not the second. It is not a match for your '#test.on' selector when the code is run. What you want to do instead is use delegation:
$('#test').on('click',function() {
var ele = $(this);
if (ele.hasClass('on')) {
ele.removeClass('on').addClass('off');
} else {
ele.removeClass('off').addClass('on');
}
});
This assumes that you are doing more than just toggling classes. If you want simply toggle classes then an easier solution is to pick one as the default and use the other as a flag. For example, .on is on but without .on it's off. Then you can just use toggle:
$('#test').on('click', function() {
$(this).toggleClass('on');
});
$("#test.on")
Doesn't bind to anything. Try this:
$('#test').click(function() {
if($(this)).hasClass('off') $(this).removeClass('off').addClass('on');
else $(this).removeClass('on').addClass('off');
});
You might consider using an 'active' class instead and just toggling that, instead of have two separate on/off classes. Then you can write:
$("#test").click(function() {
$(this).toggleClass('active');
});

How to add onclick event in dynamicly add html code via JavaScript?

I try to add some list element in loop via JS. Every element <li>contains <a> tag, now I want to add onClick event in every adding <a> tag. I try to do it so:
liCode = '<li>Text using variable foo: ' + foo + '</li>';
$('#list').append(function() {
return $(liCode).on('click', clickEventOccurs(foo));
});
In clickEventOccurs I just output to console foo. It works in strange way: this event performed just on init when every tag is adding to list, but after click on <a> doesn`t perform anything. How to make it works in proper way - on click performed code in clickEventOccurs?
Firstly, you are assigning not a callback function, but a result of function evaluation. In right way it should be like this:
$('#list').append(function() {
return $(liCode).click(function() {
clickEventOccurs(foo);
});
});
Also, as you are using jQuery you might use benefits of events delegation and use .on method this way:
$('#list').on('click', 'li', function() {
return clickEventOccurs(foo);
});
on() is good for handling events, even to elements which will be created dynamically.
$('body').on('click', '#list li', function(){
clickEventOccurs(foo);
});
http://jsfiddle.net/lnplnp/uGJnc/
HTML :
<ol id="list">
<li>Text using variable foo: foovalue</li>
</ol>
JAVASCRIPT/JQUERY :
function appending(foo) {
liCode = '<li>Text using variable foo: ' + foo + '</li>';
$('#list').append($(liCode));
}
$('#list').on('click', 'li', function() {
return clickEventOccurs($("a", this).text());
});
function clickEventOccurs(v){
console.log(v.split(":")[1].trim());
}
appending("foo1");
appending("foo2");
appending("foo3");
To pass a variable to that function you'll have to make a second anonymous one, otherwise your clickEventOccurs function will be called at assignment, not as a callback.
$('#list').append(function() {
return $(liCode).click(function() {
clickEventOccurs(foo)
});
});

A smart toggle class in jQuery

I am trying to implement a script to set different class name on a specific element…
Let's suppose the dom looks like this:
<body class='pre-existing-class-name'>
If I make
smartToogle('body', 'new-class');
// the dom should look like this
// <body class='pre-existing-class-name new-class'>
smartToogle('body', 'new-class-2');
// the dom should look like this
// <body class='pre-existing-class-name new-class-2'>
I did the following code but it does not work:
var smartToogle = function (element, newClassName) {
var oldClassName;
var $element = $(element);
$element.addClass(newClassName);
if (oldClassName !== newClassName) {
$element.removeClass(oldClassName);
}
oldClassName = newClassName;
};
Requirements:
1) I am using query
2) I would like to pass just one class name, the new one.
Solution:
The following code works but I do not like it because it uses global variable.
Any hint to fix it?
function myToggle(newClassName) {
if (window.oldClassName) {
$('body').toggleClass(window.oldClassName);
}
window.oldClassName = newClassName;
$('body').toggleClass(newClassName);
}
You can use data attribute for the element, that is accessible using
$(element).data(attrib_name)
Just a small change is required in your method
function myToggle(newClassName) {
if (window.oldClassName) {
$('body').toggleClass(window.oldClassName);
}
window.oldClassName = newClassName;
$('body').toggleClass(newClassName);
}
can be replaced with
function myToggle(element, newClassName) {
if ($(element).data('oldClassName')) {
$(element).toggleClass($(element).data('oldClassName'));
}
$(element).data('oldClassName', newClassName)
$(element).toggleClass(newClassName);
}
Hope this solves it for you.
Update:
There is one thing you need to understand.
If you want two different behaviors you don't need 2 different classes for the change in behavior.
One is enough, because you can change the behavior based on weither the class is on or off.
Let's say I want my element to have a red hover event in one way.
And want it to have a blue hover event the other way with CSS.
Then this is the way to go:
$('#toggle').click(function(){
$('.normal').each(function(){
$(this).toggleClass('active');
});
});
JSFiddle Demo
Here we use a button to toggle all the divs and change their CSS behavior, looks easy now right?
However if you need to toggle Javascript/jQuery events as well this won't do. In that case you will need to use 3 other methods to manage this; .on(), .off(), and .hasClass().
$('#toggle').click(function(){
$('.normal').each(function(){
if($(this).hasClass('active')){
$(this).off('click');
} else {
$(this).on('click', function(){
alert('You are clicking on an active div.');
});
}
$(this).toggleClass('active');
});
});
JSFiddle Demo 2
As you can see we have added an if statement. If the element has the .active class we turn .off() the .click(). And if there isn't an active class we turn the .click() .on(). Under the if statement we always toggle the .active class. So this doesn't have to be placed inside the if statement.
I hope this clears everything up for you, good luck!
Old Answer:
It is better to use .toggleClass() here.
Use a first class on the element for the default properties and a second like .active for example for the interaction.
Also, using a .on('click', function(){}) bind will make you able to add interaction that will be bound instantly once the element is toggled.
Here's a fiddle: http://jsfiddle.net/NCwmF/2/
I little jQuery plugin for that. Removes the current smart class (if any) and adds the new smart class. If called without parameter className the current smart class gets only removed.
$.fn.smartToggle = function (className) {
var dataId = 'smartToggle';
return this.each(function () {
var $el = $(this);
$el
.removeClass($el.data(dataId) || '')
.addClass(className)
.data(dataId, className);
});
};
​use it like every other jQuery method:
$('body').smartToggle('myClass');
NEW, SIMPLER ANSWER
Works similar to before, with 2 additions: 1.) works if there is no class initially and 2.) works if other functions change the elements class in between calls. I also changed the function name so it doesn't interfere with jQuerys native toggleClass.
$.fn.fancyToggleClass = function(new_class) {
return this.each(function() {
// get the last class this function added (if exists) or false (if not)
var $this = $(this),
toggled_class = $this.data('toggled-class') || false;
// if we dont have an original class, then set it based on current class
if (toggled_class) {
$this.removeClass(toggled_class);
}
// add new class and store as data,
// which we check for next time function is called
$this.addClass(new_class).data('toggled-class', new_class);
// alert the class, just as a check to make sure everything worked!
// remove this for production, or switch to console.log
alert('element class: ' + $this.attr('class'));
});
}
updated fiddle: http://jsfiddle.net/facultymatt/xSvFC/3/
OLD ANSWER
I would suggest storing the original class in the elements data attribute. Then, your function can check if this data is set, and if so clear the elements class adding the original class from the elements data and also the new class you passed in the function.
If data is not set, the function will store the current class as data the first time it runs.
Check out this fiddle for a working example with comments: http://jsfiddle.net/facultymatt/xSvFC/
here is the code. It's a jquery function so it can be called on any element (and is chainable too!)
$.fn.toggleClass = function(new_class) {
return this.each(function() {
// cache selector for this
$this = $(this);
// get original class (if exists) or false (if not)
var original_class = $this.data('original-class') || false;
// if we dont have an original class, then set it based on current class
if (!original_class) {
original_class = $this.attr('class');
$this.data('original-class', original_class);
// we do have an original class, so we know user is now trying to add class
// here we clear the class, add the original class, and add the new class
} else {
// assign the original class, and new class,
// and a space to keep the classes from becoming one
$this.attr('class', original_class + ' ' + new_class);
}
// alert the class, just as a check to make sure everything worked!
// remove this for production, or switch to console.log
alert('element class: ' + $this.attr('class'));
});
}
Hope this helps!
To avoid a global variable you can use data attribute as #ankur writes. Here is a working solution for your problem:
function myToggle(element, newClassName) {
if (!$(element).data('baseclassname')) {
$(element).data('baseclassname', $(element).attr('class'));
}
$(element)
.attr('class', $(element).data('baseclassname'))
.addClass(newClassName);
}
Does this do your job?
var smartToogle = function (element, preExistingClassName, newClassName) {
$(element)[0].className = preExistingClassName + ' ' + newClassName;
};
Just use hasClass. But you'll have to tell the function what both classes are:
function smartToggle(element, class1, class2) {
var $element = $(element);
if ($element.hasClass(class1)) {
$element.removeClass(class1);
$element.addClass(class2);
}
else {
$element.removeClass(class2);
$element.addClass(class1);
}
}
$(function(){
var smartToggle = function (element, newClassName) {
var elementClasses = element.attr('class');
element.addClass(newClassName);
// check if there is more than one class on the element
if(elementClasses .indexOf(' ') >= 0){
var oldClassNames = elementClasses.split(" ");
if (oldClassNames[oldClassNames.length - 1] !== newClassName) {
element.removeClass(oldClassNames[oldClassNames.length - 1]);
}
}
};
smartToggle($('.test'), 'newclass');
smartToggle($('.test'), 'newclass2');
});
Demo - http://jsfiddle.net/Q9A8N/ (look at the console to see what it is doing on each pass)
That should do what you want but as #T.J. Crowder said it is rather fragile and assumes that the class you want to remove is the last one on the element.
As an answer to your question, I would go with ankur's answer
As a follow-up to Sem's answer, regarding the handling of jQuery events :
you can use the on function to handle any jquery event from a parent node, based on a live filter :
function myToggle(element, newClassName) {
if ($(element).data('oldClassName')) {
$(element).toggleClass($(element).data('oldClassName'));
}
$(element).data('oldClassName', newClassName);
$(element).toggleClass(newClassName);
}
//event delegation : 'on' is called on the $('.divContainer') node, but we handle
//clicks on '.divItm' items, depending on their current class
$('.divContainer')
.on('click', '.divItm.plain', function(){ myToggle( this, 'red' ); })
.on('click', '.divItm.red', function(){ myToggle( this, 'blue' ); })
.on('click', '.divItm.blue', function(){ myToggle( this, 'plain' ); });
//initialize each item with the 'plain' class
myToggle( $('.divItm'), 'plain' );
Here is the jsFiddle.
You will note that the function called each time you click on an item depends on its "live" class, and that you don't need to manually enable/disable click handlers each time an item changes class.
You can learn more details from the documentation page.
var smartToogle = function (element, newClass) {
var $element = $(element),
currentClass = $element.data('toggle-class');
if (currentClass != newClass) $element.data('toggle-class',newClass).removeClass(currentClass || '');
$element.toggleClass(newClass);
};
or the other variant:
$.fn.smartToogle = function (newClass) {
currentClass = this.data('toggle-class');
if (currentClass != newClass) this.data('toggle-class',newClass).removeClass(currentClass || '');
this.toggleClass(newClass);
};
In this implementation you'll have to keep the a reference to this instance of fancytoggle.
var fancytoggle = function(el, oldClass){
// create a function scope so we'll have a reference to oldClass
return function(newClass) {
// toggle the old class and the new class
$(el).toggleClass(oldClass+ ' ' + newClass);
// update the new class to be the old class
oldClass = newClass;
};
};
for your example the code would look something like.
var bodytoggle = fancytoggle('body', 'pre-existing-class-name');
bodytoggle('new-class');
// 'new-class' replaces 'pre-existing-class-name'
bodytoggle('new-class-2');
// 'new-class-2' replaces 'new-class'
to see it in action refer to http://jsfiddle.net/aaf2L/6/

jQuery unbind click event function and re-attach depending on situation

The code below I use to create a sliding menu. I need to know how to unbind the function attached to the click event and re-attach it some other time. (using jQuery 1.7.2)
$(document).ready(function(){
$('.section').hide();
$('.header').click(function(){
if($(this).next('.section').is(':visible'))
{
$('.section:visible').slideUp()
$('.arrows:visible').attr("src","right.gif")
}
else
{
$('.section').slideUp();
$(this).next('.section').slideToggle();
$(this).find('.arrows').attr("src","down.gif")
});
});
The code below is what I have so far
$('#printVers').click(function(){
if($('#formVersion').val() != "Print")
{
$('.header').unbind('click');
}
else
{
//else re-attach functionality?
}
});
Thanks
Simply make a named function. You can go low tech here and back to basics to unbind and reattach specific events.
function doStuff()
{
if($(this).,next('.section').is(':visible'))
...
}
$('.header').on('click', doStuff);
$('.header').off('click', doStuff);
Instead of unbind and re-bind, I suggest you to add a simple class to .header and check for the class in the click handler. See below,
$('#printVers').click(function(){
if($('#formVersion').val() != "Print")
{
$('.header').addClass('dontClick');
} else {
$('.header').removeClass('dontClick');
}
});
And in your .header click handler,
$('.header').click(function(){
if ($(this).hasClass('dontClick')) {
return false;
}
//rest of your code
If you insist on having a unbind and bind, then you can move the handler to a function and unbind/bind the function any number of time..
You can try something like this.
$('#printVers').click(function(){
if($('#formVersion').val() != "Print")
{
$('.header').addClass('clickDisabled');
}
else
{
$('.header').removeClass('clickDisabled');
}
});
And then in the click handler check for this class.
$(document).ready(function(){
$('.section').hide();
$('.header').click(function(){
if(!$(this).hasClass('clickDisabled')){
...
...
}
});
});
Why not make that top section a function, and then call it in your else statement?
You could try setting a variable as a flag. var canClick = ($('#formVersion').val() != 'Print'); Then in the click handler for your .header elements check to see if canClick is true before executing your code.
If you still want to remove the handler you can assign the events object to a variable. var eventObj = #('.header').data('events'); That will give you an object with all the handlers assigned to that object. To reassign the click event it would be like $('.header').bind('click', eventObj.click[0]);
After trying so hard with bind, unbind, on, off, click, attr, removeAttr, prop I made it work.
So, I have the following scenario: In my html i have NOT attached any inline onclick handlers.
Then in my Javascript i used the following to add an inline onclick handler:
$(element).attr('onclick','myFunction()');
To remove this at a later point from Javascript I used the following:
$(element).prop('onclick',null);
This is the way it worked for me to bind and unbind click events dinamically in Javascript. Remember NOT to insert any inline onclick handler in your elements.
You could put all the code under the .click in a separated function
function headerClick(){
if($(this).next('.section').is(':visible'))
{
$('.section:visible').slideUp()
$('.arrows:visible').attr("src","right.gif")
}
else
{
$('.section').slideUp();
$(this).next('.section').slideToggle();
$(this).find('.arrows').attr("src","down.gif")
}
}
and then bind it like this:
$(document).ready(function(){
$('.section').hide();
$('.header').click(headerClick);
});
$('#printVers').click(function(){
if($('#formVersion').val() != "Print")
{
$('.header').unbind('click');
}
else
{
$('.header').click(headerClick);
}
});

Categories

Resources