Only run function on element click with specific attribute - javascript

Now I would expect this function to only run when clicking on a <a data-popup="true"></a> element however it's running on every <a> click.
(function($) {
$(document).ready(function() {
$('a').data('popup', 'true').click(function(e) {
console.log($(this).data('popup'));
e.preventDefault();
});
});
})(jQuery);

The .data() method get/sets data associated with the element; it doesn't filter the elements like you are expecting. You are actually setting a key/value pair of data on all the anchor elements and then attaching an event listener to all the anchor elements. In other words, when you set data with the .data() method, the original jQuery object is returned (which means that the .click() method is still attaching a click event handler to all the originally selected anchor elements).
You are looking for an attribute selector. In this case, the selector a[data-popup="true"] will select anchor elements with a data-popup attribute value of true.
$('a[data-popup="true"]').click(function(e) {
console.log($(this).data('popup'));
e.preventDefault();
});

Below code will attach data for all existing a link in the code.
$('a').data('popup', 'true').click(function(e)
you may try this:
<a id="popid" data-popup="true"></a>
(function($) {
$(document).ready(function() {
$('#popid').click(function(e) {
console.log($(this).data('popup'));
e.preventDefault();
});
});
})(jQuery);
To check popup for all a link, you may try below.
(function($) {
$(document).ready(function() {
$('a').click(function(e) {
if ($(this).data('popup')){
console.log($(this).data('popup'));
e.preventDefault();
}
});
});
})(jQuery);
or
$('a[data-popup="true"]').click(function(e) {
console.log($(this).data('popup'));
e.preventDefault();
});

Related

EventListener not working with anchor tel:XXXXXXXXX

I have a tag with href="tel:XXXXXXXXX", and I need catch the click event.
I have tested the following code on chrome: $(document).on('click',console.log). If i click on this tag browser it calls the application, but does not trigger a click event.
$("a[href^='tel']").on('click', console.log);
This is working, but I my have a problem with content load by ajax. My code has loaded a page and after some time application added content by ajax. When i use $(document).on('click', ("a[href^='tel']", console.log), there is a problem.
$("a[href^='tel']").on("click", function(e){
e.preventDefault(); e.stopPropagation();
console.log(this);
alert(this.getAttribute("href"));
})
//or if you want to delegate your function
$(document).on('click', "a[href^='tel']", function(e){
e.preventDefault(); e.stopPropagation();
console.log(this);
alert(this.getAttribute("href"));
});
This will bind an event listener to all click on a tags with a href attribute and prevent the click itself. After click, you'll be able to use your console to see which element was click and what href was used.
Ok, i found resolve.
I use earlier event "mousedown" and change attr "href" to "only number" for disable action click.
Code:
const click2dial_Event = function(e) {
e.preventDefault();
let a = $(this), number;
if (a.attr('href') !== '#') {
number = a.attr('href');
number = number.substr(4);
a.attr('href', '#');
a.attr('data-dial', number)
a.addClass('click-to-dial');
} else {
number = a.attr('data-dial');
}
//...
};
$(document).on('mousedown', "a[href^='tel']", click2dial_Event);
$(document).on('mousedown', '.click-to-dial', click2dial_Event);
This would get the phone number from the a tag starting with a value of tel upon clicking it.
$("a[href^='tel']").on("click", function(e) {
var hrefText = this.getAttribute("href");
var str = hrefText;
var res = str.split(":");
alert(res[1]);
});
On Initial Load
I would first recommend that you wait for the initial DOM to be ready before binding any events to elements.
// DOM ready shorthand
$(function() {
$("a[href^='tel']").on('click', function(e) {
// Do work here
});
});
AJAX Content
If you are adding additional elements after the initial load you will have to bind events to those new elements as well.
You could also do something like adding a data attribute to the elements that you've bound click events to and only add to ones that don't yet have that data attribute - but that's additional unnecessary work.
Full Example Code
// DOM Ready Shorthand
$(function() {
// Click Handler
function clickEvent(e) {
// Do work here
}
// Bind click event to initial tels
$("a[href^='tel']").on('click', clickEvent);
// Arbitrary AJAX request for demonstration (wherever yours may be)
$.ajax('/newContent')
.done(function(html) {
// Adding our response HTML to the page within #someElement
$('#someElement').append(html);
// Bind click event to the new tel elements scoped to the returned html
$("a[href^='tel']", html).on('click', clickEvent);
});
});

Detecting class on HTML element not working correctly

I have a button and when it is clicked it should add a class to the HTML element, but then when the .class is clicked, it isn't detected.
This is the use case:
Click button - "testerclass" will be added to HTML element
Click "testerclass" - removes that class from that element
The detection for when "testerclass" is clicked only seems to work when the class exists before the page load, not when I add the class manually after load. Is this something to do with the problem?
I have tried to recreate the problem on jsfiddle, but I can't recreate the use case where the class is already added to the HTML element, as I can't edit that on jsfiddle.
But here is jsfiddle one, In this one you can see that the buttonone adds a class to HTML, but the detection for clicks on .testerclass never come through.
And here is jsfiddle two. In this one, I have changed the .testerclass selector to html, and this shows that HTML clicks are bubbling through (which I was unsure of when I first hit this problem).
And offline I created a third testcase where the HTML element already had the testerclass, and it detected the clicks sent through to it.
$(document).ready(function() {
$('button.1').click(function() {
$('html').addClass('testerclass');
$('.test').append('"testerclass" added to html<br />');
});
$('.testerclass').click(function() {
$('.test').append('testerclass clicked and removed<br />');
$('html').removeClass('testerclass');
});
});
Edit: I also tried doing this with a slightly different method of:
$('html').click(function() {
if(this).hasClass('testerclass') {
//do stuff
}
});
but that didn’t work either.
Since the testerclass is dynamic, you need to use event delegation to handle events based on that. Which will require us to register the event handler to the document object that causes another problem because the click event from the button will get propagated to the document object which will trigger the testerclass click handler as well. To prevent this from happening you can stop the event propagation from the button.
$(document).ready(function () {
$('button.1').click(function (e) {
e.stopPropagation();
$('html').addClass('testerclass');
$('.test').append('"testerclass" added to html<br />');
});
$(document).on('click', '.testerclass', function () {
$('.test').append('testerclass clicked and removed<br />');
$('html').removeClass('testerclass');
});
});
Demo: Fiddle
You need to stop the propagation to the html so the other click handler does not pick it up.
$('button.1').on("click", function(evt) {
$('html').addClass('testerclass');
$('.test').append('"testerclass" added to html<br />');
evt.stopPropagation();
});
$(document).on("click", function() {
$('.test').append('testerclass clicked and removed<br />');
$('html').removeClass('testerclass');
});
Other option would be to add one event handler and use the event target to see if it is the button or not and change the content that way.
$(document).on("click", function (evt) {
var isButton = $(evt.target).is(".btn");
var message = isButton ? '<p>"testerclass" added to html</p>' : '<p>"testerclass" clicked and removed</p>'
$('html').toggleClass('testerclass', isButton);
$(".test").append(message);
});
JSFiddle: http://jsfiddle.net/69scv/
here's a neat way to do it
$('html').on('click', function(e) {
var state = !!$(e.target).closest('button.1').length;
var msg = state ? 'class added' : 'class removed';
$(this).toggleClass('testerclass', state);
$('.test').append(msg + '<br>');
});
FIDDLE
You add a class to html element, so when this class is clicked, it means the html element is click. Now the problem is when you click any where in page, it will remove this class away from html! Let try add this class to body element instead.
$(document).ready(function() {
$('button.1').click(function() {
$('body').addClass('testerclass');
$('.test').append('"testerclass" added to html<br />');
});
$('.testerclass').click(function() {
$('.test').append('testerclass clicked and removed<br />');
$('body').removeClass('testerclass');
});
});
And now you can check it:
$('html').click(function() {
if(this).hasClass('testerclass') {
//do stuff
}
});

Click event of 'a' tag in jquery

I need to trigger click events of "a" tags which are in "deletable" class. I saw some similar question in SO, but following code doesn't work for me. What i'm trying to do is to delete relevant <li> from <ul>.
$(document).ready(function () {
$('.deletable').live("click", function () {
alert("test"); // Debug
// Code to remove this <li> from <ul>
});
});
<form ...>
<ul>
<li>OneDelete</li>
<li>TwoDelete</li>
<li>ThreeDelete</li>
</ul>
</form>
I assume i'm using incorrect object hierarchy inside $('...') tag. But i don't have enough js/jquery/DOM knowladge to solve this problem. please help.
EDIT
Thanks for the answers, but none of them works for me. Actually i'm adding <li>s dynamically. There maybe a problem. Please check,
#sps - a listbox
#add - a button
#splist - another listbox
#remove - a button
$(document).ready(function() {
$('#add').click(function(e) {
var selectedOpts = $('#sps option:selected');
if (selectedOpts.length == 0) {
alert("Nothing to move.");
e.preventDefault();
}
$('#splist').append($(selectedOpts).clone());
$('ul').append('<li>' + selectedOpts.text() + 'Remove' + '</li>');
e.preventDefault();
});
$('#remove').click(function(e) {
var selectedOpts = $('#splist option:selected');
if (selectedOpts.length == 0) {
alert("Nothing to move.");
e.preventDefault();
}
$(selectedOpts).remove();
e.preventDefault();
});
});
The .live() method of jQuery has been deprecated. You can get similar functionality using $('body') and delegating to .deletable like I did in the following code:
$('body').on('click', '.deletable', function(e){
e.preventDefault();
// this is the li that was clicked
$(this).parent().remove();
});
The preventDefault method is used to keep the link from loading a new page should there be something targeted in the href attribute. If you keep the same HTML structure as you have in your example, then you can simply take the anchor element (this) and grab the parent, then remove it from the DOM.
It would be wise to, instead of using $('body'), target the container for the .deletable anchors, which, in this case, would be $('ul'). The function would look like this:
$('ul').on('click', '.deletable', function(e){
e.preventDefault();
// this is the li that was clicked
$(this).parent().remove();
});
Using $('body') means that every event on the page would have to be filtered to see if it originated from a .deletable anchor. By scoping it to the ul preceding your li's, you limit the number of times your function is called increasing performance.
Some things first: if you're using jQuery 1.9, the .live() function is not anymore supported. Versions prior, that particular function is deprecated anyway, so you shouldn't really use it.
That being said, your syntax looks about correct. So I'm assuming that it's your hierarchy inside the handler function that's incorrect.
Something like this should work if you're trying to delete the parent <li>:
$('.deletable').on('click', function (e) {
// since you're working with a link, it may be doing wonky default browser stuff
// so disable that for now
e.preventDefault();
// then we delete the parent li here:
$(this).parent('li').remove();
});
If you really want to make that into a delegate signature, something like this should work:
$('form').on('click', '.deletable', function (e) {
// same banana
});
you can use $('a.deletable') selector ... this finds the <a> with class deletable.
u can go through the on delegate events too.. here is the docs
try this
$('a.deletable').on("click",function(){
alert("test"); // Debug
// Code to remove this <li> from <ul>
$(this).parent("li").remove();
});
if in case your <li> is added dynamically..
$(document).on("click",'a.deletable',function(){ .... //even more better if u replace the document with closest elements to a.deletable ..like $(form)
live() is depricated..
$('a.deletable').live("click",function(){
alert("test"); // Debug
$(this).parent('li').remove();
});

jQuery function run when clicking on anchor with a specific value

I would like a function to run when a specific anchor with the `value="frb" is clicked.
This is the anchor
Accept
this is what i tried:
$('body').on('click', value[frb], function(e) {
e.preventDefault();
});
this doesnt work, i cant find any examples that use this, is it possible?
value is not valid attribute to anchor tag. Instead of that you can use data-value like following:
HTML
Accept
jQuery
$('body').on('click', 'a[data-value=frb]', function(e) {
e.preventDefault(); // prevent page reload
alert( this.href );
});
Working sample
Note:
Already #Musa mentioned about data attribute, but in his jQuery snippet used a[value=frb] which will not work.
The second parameter of .on() should be a selector string
$('body').on('click', 'a[value=frb]', function(e) {
e.preventDefault();
});
also a tag doesn't have a value attribute, you should use a data attribute instead
Accept
try this:
$(function(){
$('a[value=frb]').click(function(e) {
e.preventDefault();
});
});
It assigns the function to all anchors with the specified 'value' attribute.
working demo http://jsfiddle.net/KQy36/
OR http://jsfiddle.net/WP7JS/
API: http://api.jquery.com/on/
Oh by the way: http://www.w3schools.com/tags/tag_a.asp (To see valid a tag attribute)
Anyhoo, Hope this helps,
code
$('a[value="frb"]').on('click', function(e) {
alert('yeah wha?');
e.preventDefault();
});​
OR apart of another post below mine. :)
$('a').on('click', function(e) {
if ($(this).attr("value") === "frb") {
alert('yeah wha? I am frb');
e.preventDefault();
} else {
alert('not frb');
e.preventDefault();
}
});​
Since there is no value attribute for the link tag we need to make a change to the html:
<span class="frb">Accept</span>
Then add this to register the click event.
$(document).ready(function(){
$('span.frb').click(function(e) {
e.preventDefault();
});
});

jQuery click function acting strange when adding/removing classes

I have two list items that, when clicked, should change classes from '.off' to '.on'. Only one element should be '.on' at a time so when one is already turned on and the other is clicked both elements should change classes from '.off' to '.on' and vice versa. If a list item with a class of '.on' is clicked it should change classes to '.off'
The problem I am having is when a list item with class '.on' is clicked it still runs the click function as if it had a class of '.off'
My html:
<ul>
<li>ABOUT</li>
<li>SUBMIT</li>
</ul>
My javascript (running on jQuery 1.7.1)
$('.off').click(function(event) {
event.preventDefault();
$(".on").addClass("off").removeClass("on");
$(this).addClass("on").removeClass("off");
});
$('.on').click(function(event) {
event.preventDefault();
$(this).addClass("off").removeClass("on");
});
Does anyone know what is going on here? Is there something wrong in my code or have I encountered some sort of bug here?
http://jsfiddle.net/ZC3CW/6/
The selectors you're using to bind the event using click() are used to select the elements to add the event handler to. The selector is not considered when the handler is run.
You should be looking for something more like this:
$('li').click(function(event) {
event.preventDefault();
if ($(this).hasClass('off')) {
$(".on").addClass("off").removeClass("on");
$(this).addClass("on").removeClass("off");
} else { // $(this).hasClass('on');
$(this).addClass("off").removeClass("on");
}
});
You might want to make the li selector more explicit by adding a class/id to the ul or li's.
To confuse things further, you could also do this (if you're using jQuery > 1.7);
$(document).on('click', '.off', function(event) {
event.preventDefault();
$(".on").addClass("off").removeClass("on");
$(this).addClass("on").removeClass("off");
});
$(document).on('click', '.on', function(event) {
event.preventDefault();
$(this).addClass("off").removeClass("on");
});
This is because the .on() function works by attaching the event handler to the selected elements (document), and will only execute the handler (the function) on the event specified (click) if the element that the event originated from matches the selector .off at the time the event fired, not at binding time.
I would suggest adding a click handle to a different selector, this should work for you...
$("ul li a").click(function(e){
e.preventDefault();
if($(this).hasClass("off")){
$("ul li a").addClass("off").removeClass("on");
$(this).addClass("on").removeClass("off");
}
else{
$(this).addClass("off").removeClass("on");
}
});
The problem is that jQuery handlers get attached at page load and remain the same regardless of changing their classes. Use live('click', handler) on('click', handler) instead of click().
Edit: just noticed that .live() is deprecated in jQuery 1.7.
The problem as I see it is that your "on" class is not in play at the time of the click event, so your $('.on').click method is never being called.
Try re-assigning your events after changing classes (example follows) :
var assignClicks = function () {
$('.off').click(function(event) {
event.preventDefault();
$(".on").addClass("off").removeClass("on");
$(this).addClass("on").removeClass("off");
assignClicks();
});
$('.on').click(function(event) {
event.preventDefault();
$(this).addClass("off").removeClass("on");
assignClicks();
});
};
assignClicks();
Hope this helps,
Pete
The click is bound to the element not the class.
Maybe you can attach the events to the elements and detect/toggle the elements classes:
$('li').click(function(event) {
event.preventDefault();
if( $(this).hasClass('on') ) {
$(this).removeClass('on');
}
else {
$(this).addClass('on');
$(this).siblings().removeClass('on');
}
});

Categories