click event not working when changing id or class - javascript

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

Related

I'm trying to attach events using on() based on changing selectors

I have a button that can be in 2 different states (lets say Lock and Unlock). When I click on the button, I update the class on the button to reflect the binary opposite state. Each class has a different event attachment function using on(string, callback). For some reason the event being triggered remains the first callback assigned based on the original class.
HTML:
<button class="lock">Lock</button>
<button class="unlock">Unlock</button>
JavaScript:
$(document).ready(function() {
$('.lock').on('click', function() {
// Perform some magic here
console.log('Lock!');
$(this).removeClass('lock')
.addClass('unlock')
.html('Unlock');
});
$('.unlock').on('click', function() {
// Perform some magic here
console.log('Unlock!');
$(this).removeClass('unlock')
.addClass('lock')
.html('Lock');
});
});
https://jsfiddle.net/c283uaog/ for testing.
Expected console output when clicking on the same button repeatedly:
Lock!
Unlock!
Lock!
Actual console output:
Lock!
Lock!
Lock!
Any assistance would be greatly desired
use event Delegation
$(document).on('click','.lock', function() {
$(document).on('click','.unlock', function() {
updated Demo
Or use in single function with toggleClass
$(document).on('click', '.lock,.unlock', function () {
$('#output').html($(this).attr('class'));
$(this).toggleClass('lock unlock').text($(this).attr('class'));
});
ToggleClass demo
I'd do it this way, attaching only one event: http://jsfiddle.net/jozu47tv/
$(".lock").on('click', function(e) {
e.preventDefault();
if($(this).hasClass("lock")) {
$(this).removeClass("lock").addClass("unlock");
console.log("lock -> unlock");
} else {
$(this).removeClass("unlock").addClass("lock");
console.log("unlock -> lock");
}
})
Use Event Delegation method, Try this updated fiddle,
$(document).ready(function() {
$(document).on('click', '.lock', function() {
$('#output').html('Lock!');
$(this).removeClass('lock')
.addClass('unlock')
.html('Unlock');
});
$(document).on('click', '.unlock', function() {
$('#output').html('Unlock!');
$(this).removeClass('unlock')
.addClass('lock')
.html('Lock');
});
});
Probably, this question could answer you in a better way:
jQuery .on function for future elements, as .live is deprecated
$(document).on(event, selector, handler)
Change your html to this:
<button class="locker lock" >Lock</button>
<button class="locker unlock"">Unlock</button>
<div id="output">Output</div>
and your Js to this:
$(document).ready(function() {
$('.locker').on('click', function() {
if($(this).hasClass("lock")){
$(this).removeClass("lock");
$(this).addClass("unlock");
$(this).html("unlock");
}
else if($(this).hasClass("unlock")){
$(this).removeClass("unlock");
$(this).addClass("lock");
$(this).html("lock");
}
});
});

Adding an on event to an e.currentTarget?

A variety of elements on my page have the content editable tag.
When they are clicked I do this:
$('[contenteditable]').on('click', this.edit);
p.edit = function(e) {
console.log(e.currentTarget);
e.currentTarget.on('keydown', function() {
alert("keydown...");
});
};
I get the current target ok, but when I try to add keydown to it, I get the err:
Uncaught TypeError: undefined is not a function
It's a native DOM element, you'll have to wrap it in jQuery
$(e.currentTarget).on('keydown', function() {
alert("keydown...");
});
e.currentTarget should equal this inside the event handler, which is more commonly used ?
It's a little hard to tell how this works, but I think I would do something like
$('[contenteditable]').on({
click : function() {
$(this).data('clicked', true);
},
keydown: function() {
if ($(this).data('clicked'))
alert("keydown...");
}
});
Demo
First issue is you are trying to use jQuery methods on a DOM element. Second issue is I do not think you want to bind what is clicked on, but the content editable element itself.
It also seems weird to be adding the event on click instead of a global listener. But this is the basic idea
$(this) //current content editable element
.off("keydown.cust") //remove any events that may have been added before
.on('keydown.cust', function(e) { //add new event listener [namespaced]
console.log("keydown"); //log it was pressed
});
Edited: I had a fail in code. It works fine now.
Getting your code, I improved to this one:
$(function(){
$('[contenteditable]').on('click', function(){
p.edit($(this));
});
});
var p = {
edit: function($e) {
console.log($e);
$e.on('keydown', function() {
console.log($(this));
alert("keydown...");
});
}
}
You can check it at jsFiddle
You need to wrap the e.currentTarget(which is a native DOM element) in jQuery since "on" event is a jQuery event:
$(e.currentTarget).on('keydown', function() {
alert("keydown...");
});
EDIT:
$('[contenteditable]').on('click', p.edit);
p.edit = function(e) {
$(e.currentTarget).on('keydown', function() {
alert("keydown...");
});
};
You're defining p.edit AFTER $('[contenteditable]').on('click', p.edit); resulting in an error since p.edit doesn't exist when declaring the on.
In case you don't know, you are defining p.edit as a function expression, meaning that you have to define it BEFORE calling it.

Disable CSS link for 1 second after it has been clicked

I'm trying to have a CSS link disabled for 1 second after it has been clicked.
I have tried this without success;
In the header:
<script type="text/javascript">
$(function() {
$("#link").click(function() {
$("#link").attr("disabled", "disabled");
setTimeout(function() {
$("#link").removeAttr("disabled");
}, 2000);
});
});
</script>
Html:
the link text
CSS:
.link:diabled {
some values here.. }
You have a class="link", but with $("#link") you are addressing the id called link.
So write $(".link") everywhere instead of $("#link").
By the way: with .link:disabled you won't address the link as this only works on inputs and buttons. If you need to address it, use .link[disabled="disabled"] { ... } or even better add a class to it called disabled_link and then do in CSS .disabled_link { ... }.
There are quite a few problems here:
You are using # (the ID selector), but your html is using classes.
<a> does not have a disabled attribute
If it did, you would probably want to use .prop instead of .attr
If you change code to use classes, $(".link").prop("disabled", true) would affect all anchors, so you should probably use this.
Because disabled does not exist for <a>, the :disabled selector does not seem to work for CSS.
A working solution would be something like this:
$(".link").click(function() {
var $this = $(this);
$this.addClass('disabled');
setTimeout(function() {
$this.removeClass('disabled');
}, 2000);
});
$(document).on('click', '.disabled', function (e) {
e.preventDefault();
});
http://jsfiddle.net/ExplosionPIlls/PaYcc/
'link' is a class and you are using it as ID. Do $('.link') instead of $('#link').
I think this approach works better. The other allows you to click the link multiple times and mess up the setTimeout this unbinds the event and then re-attaches the event after the setTimeout ex: double click the link
$(".link").click(linkBind);
function linkBind(){
var $this = $(this);
$this.addClass('disabled');
$this.unbind('click');
setTimeout(function() {
$this.removeClass('disabled');
$this.bind('click', linkBind);
}, 2000);
}
$(document).on('click', '.disabled', function (e) {
e.preventDefault();
});
http://jsfiddle.net/PaYcc/1/

jQuery, Triggering event from Class

Please take a look at the following code and fiddle.
CODE
$("#enable").click(function(e) {
if (!$("#enable").data('isOn')) {
$("#holder").find('.clickable').each(function(d) {
$(this).css('border', '1px solid red');
$(this).addClass('clickEnabled');
});
$("#enable").data('isOn', true);
} else {
$("#holder").find('.clickable').each(function(d) {
$(this).css('border', '');
$(this).removeClass('clickEnabled');
});
$("#enable").data('isOn', false);
}
});
$(".clickEnabled").click(function(e) {
alert('clicked');
});
Fiddle: http://jsfiddle.net/qAuwt/
I am basically trying to toggle a "clickEnabled" class on elements when a button is pressed. The toggling is working as the border is changing however the clickEnabled class is not responding to click events
There are no .clickEnabled elements when you set the event handler. You can still catch the click event, though:
$(document).on("click", ".clickEnabled", function(){
alert("Hello, world!");
});​
Change:
$(".clickEnabled").click(function (e) {
alert('clicked');
});
To:
$(".clickable").click(function (e) {
if ( $(this).hasClass("clickEnabled") )
{
alert('clicked');
}
});
As #araxanas mentioned, the .clickEnabled don't exist on load. So I switched the selector to .clickable, which do. However, you only want to handle the click when they're enabled. That's why I've added the conditional. It'll only alert if the clicked element has the clickEnabled class.
Also, it might help to move the css out of javascript, that way you can see visually if the class is there or not, see my updated fiddle.
The problem is that when page loaded, the click event handler binds to no elements (because there is no element with class 'clickEnabled').
The solution is to change the .click() method to .live() method:
$(".clickEnabled").live('click', function (e) {
alert('clicked');
});

Jquery append input element and send data from that input element

I have this simple HTML code:
<div id="new_gallery">
<p id="add_gallery">Add new gallery</p>
</div>
and jQuery code:
<script>
$("#add_gallery").click(function() {
$("#new_gallery").append('<input name"new_gallery" />Add');
$(this).remove();
});
$("#create_new_gallery").on('click', function(){
alert('1');
});
</script>
First function is working, but second one is not. I need to create new input element, send data via ajax, and then delete the input element and append a p element once again. How can I do this?
When the second statement runs, the element #create_new_gallery does not exist yet so it does nothing.
You can do the binding to the click event after you created the element for instance, this ensures the element exists in the DOM:
$("#add_gallery").click(function() {
$("#new_gallery").append('<input name="new_gallery" />Add');
$(this).remove();
$("#create_new_gallery").on('click', function() {
alert('1');
});
});​
DEMO
Here is a little bit more optimized version. It's a bit non-sense to append an element and have to re-query for it (event though querying by id is the fastest method. Besides, it's best to use the chaining capabilities of jQuery afterall:
$("#add_gallery").click(function() {
var $gallery = $("#new_gallery");
$('<input name="new_gallery" />').appendTo($gallery);
$('Add')
.on('click', function() {
alert('1');
})
.appendTo($gallery);
$(this).remove();
});​
DEMO
#create_new_gallery doesn't exist when you bind its click event.
Here is what your code should look like:
$("#add_gallery").click(function() {
var newG = $("#new_gallery");
$('<input name"new_gallery" />').appendTo(newG);
$('Add').appendTo(newG).on('click',
function() {
alert('1');
});
$(this).remove();
});
Notice that getting $("#new_gallery") into a variable avoid to look for it twice.
$(document).ready(function () {
$("#add_gallery").click(function() {
$("#new_gallery").append('<input name"new_gallery" />Add');
$(this).remove();
$("#create_new_gallery").on('click', function(){
alert('1');
});
});
});
DEMO: http://jsfiddle.net/39E4s/2/
​
Try live to handle the events fired for elements added after the page has loaded.
$("#create_new_gallery").live('click', function(){
alert('1');
});
http://api.jquery.com/live/

Categories

Resources