Clicking on a button that has onClick already on - javascript

I know this sounds silly, but I need to create a function that finds a button that has onClick attached to it. And then clicks it.
So like:
<div onclick="coolFunction()" class="coolClass">
<p>Click Me!</p>
</div>
I tried searching for it by doing something like this:
$('.coolClass').attr('onClick') == 'coolFunction()'
Which did actually find it, the problem is I don't understand how can I click on it because it's in an if method.

Your selector would be something more like $('[onclick="coolFunction()"]').
So to do what you describe, you could do this
$('[onclick="coolFunction()"]').trigger('click');
Although, unless coolFunction() cares about being explicitly by this DOM element, you could just call coolFunction(), without having it piggy-back on your click handler.
Update: With an argument
// Note selector is less specific, but still targeted
$('[onclick^="coolFunction"]').trigger('click');
With, this, you can trigger the click handler, and coolFunction(var) in your HTML would work as expected.

if ( $('.coolClass').attr('onClick') == 'coolFunction()' )
{
$('.coolClass').click();
}

$('.coolClass').each(function() {
$this = $(this);
if ($this.attr('onClick') == 'coolFunction()') {
$this.trigger('click')
}
});
This will select all elements with .coolClass, check if the onClick attribute matches the coolFunction call and trigger the click event on that element.

As couzzi said, you can first verify if all the elements of the class coolClass have the attribut coolFunction and when it's the case you can just apply what you want to do on them.
$('.coolClass').each(function() {
$this = $(this);
if ($this.attr('onClick') == 'coolFunction()') {
$this.trigger('click')
}

Related

removeEventListener on class name after one click

I'm trying to write some Javascript to get click event on all elements with class from an array. Everything works fine, but I need it unclickable only until second condition in klikej() function is met. Once the click event fires, then the item with that class shouldn't be clickable. I've tried using removeEventListener and/or handle it with PreventDefaults(), but nothing works. I need to use only vanilla Javascript - no jQuery or anything else. Could you please help me?
poleRandomKaret.forEach(karta => {
document.querySelectorAll(`.${karta}`).forEach(element => {
element.addEventListener('click', event => {
console.log("klik");
klikej(event, element);
});
});
});
function klikej(event, element) {
let kliknuteKarty = document.querySelectorAll('[data-ovoce]');
if (kliknuteKarty.length < 2) {
element.setAttribute('data-ovoce', 'otoceno');
}
kliknuteKarty = document.querySelectorAll('[data-ovoce]');
if (kliknuteKarty.length === 2) {
kliknuteKarty[0].className === kliknuteKarty[1].className ? console.log("yes") : console.log("nope");
kliknuteKarty.forEach(element => {
element.removeAttribute("data-ovoce");
});
}
}
EDIT: The item shouldn't be clickable until the second condition in klikej() function is met. I'm trying to do memory game using vanilla JS. Function klikej() sets data attribute to an item and once there are two items with identical data attributes, it'll print in console "yes". If they're two different data attributes, they needs to be clickable again.
If you remove event listener, and will need to listen again, you would need to add it again or listen with something else. If I would need to recognize if something was clicked, I would add property to the element in the listener callback, so something like:
// before anything else we check if it was clicked before
if (element.clicked) {
// do your magic when element was already clicked
} else {
// do different magic with not yet opened element here
}
// after you did everything needed
// set the clicked attribute to true or false (if you need "unclick" it)
element.clicked = true;
It isn't directly answer to your question but hopefully another view to possible solution - if I understood you correctly, you do something when it was clicked and something else when it wasn't yet clicked and here you have control for both cases.
You can add an option called once as the third parameter of the addEventListener, which makes the event listener execute once.
element.addEventListener('click', function(e){
console.log('clicked'); // This will be executed once.
}, {once: true});

How to fire a double-click on click()

I am working with jaccordian and am wondering how JavaScript can fire a dblclick() when the user fires a single click. The trick is that it should only happen on specific classes.
One can use https://developer.mozilla.org/en-US/docs/Web/API/EventTarget.dispatchEvent in most moddern browsers or just call .trigger - http://api.jquery.com/trigger/ in case you are using jQuery.
i cannot know exactly what you want BUT
if you want the double click to be on a different selector then you can simply do this
$('.your_selector').click(function() {
$('.another_seletor').dblclick();
});
while if you want to fire the double click to the same selector then i you just cal $('selector').click() inside you $('selector').click(function())
here:
$('foo').click(function() {
$('foo').click();
});
finally (i hope this is what you want), the pseudo code is like this:
$(many_selectors).click {
//do a lot of code
//but
if(class of clicked element is foo)
do a double click
}
this case it is the same like the second example but you only need to add the following:
var cls_of_elems_w_dbclk = ['class1','class2','class3'];
var class_of_clicked = $(this).attr("class");
if ($.inArray(class_of_clicked, cls_of_elems_w_dbclk) !== -1) {
//then perform a another click
$(this).click();
}

How to use event.target inside jQuery child selector?

I want to check if a child-element of a clicked div has a certain class.
So i do this:
$('.panel').on('click', function (event) { if($(".panel input").hasClass('h5_validator_error')) { event.stopPropagation(); } });
The problem: I have more then one .panel class. Since my whole site gets generated by the user and json-files, i need a dynamic environment without ids.
So, actually my if-statement is preventing all .panel-clicks from doing their job.
I want to do something like this:
if($(event.target + ".panel input").hasClass('h5_validator_error')) { event.stopPropagation(); }
So i want to select all input - elements from the clicked div without
having an array and loop through it.
Is this possible? Or what is the most efficient way of selecting child-elements of the clicked one?
You should rather use this to get the targeted element:
$(this).find("input").hasClass('h5_validator_error');
or
$('input',this).hasClass('h5_validator_error');
You shoud make the dom object $(event.target) and then apply the jquery method on it.
Try this:
$('.panel').on('click', function (event) {
if($(event.target).find('input').hasClass('h5_validator_error')){
alert('true');
}
else{
alert('false');
}
});
Working Example

Stop propagation for a specific handler

Let's say I have custom dropdown(). When the button is clicked I want to bring up the menu, and when the user clicks outside of the menu I want it to close. So I do something like this:
$(myDropDown).mousedown(dropDownMouseDown);
$("html").mousedown(htmlMouseDown,myDropDown);
function dropDownMouseDown(event) {
event.target.open();
event.stopPropagation();//I need this line or else htmlMouseDown will be called immediately causing the dropDown-menu to close right before its opened
}
function htmlMouseDown() {
this.close();
}
Well, this works. But what if I add two of these? If I click to open the first, then the same on the second then both will be open because dropDownMouseDown stops the propagation so that htmlMouseDown never gets called for the first.
How do I get around this?
If I only had these two then adding some logic for that would of course be easy, but if the quantity is dynamic? Also I might not want to call event.stopPropagation() because it will do strange stuff to other libraries I'm using which listen for that event too?
I also tried putting this line:
$("html").mousedown(htmlMouseDown,myDropDown)
inside the dropDownMouseDown-handler but it will be called immediately anyway once the bubbling reaches the html-element.
Assuming you have a selector for your dropdows, (let's say ".dropdown"), I would try to use '.not()'
$('.dropdown').mousedown(dropDownMouseDown);
$("html").on('mousedown', htmlMouseDown);
function dropDownMouseDown(event) {
event.target.open();
}
function htmlMouseDown(event) {
$('.dropdown').not($(event.target)).close();
}
Here is a fiddle in the same idea with css classes :
http://jsfiddle.net/eFEL6/4/
What about using a variable that contains the last openened one ? There are probably many other ways of doing this, but here is a way I could think of:
var lastOpened = null; // initially nothing is open (unless something is)
Then:
function dropDownMouseDown(event) {
if (lastOpened != null) { // if one is still open
lastOpened.close(); // close it
lastOpened = null; // nothing is open anymore
}
event.target.open();
lastOpened = event.target; // now this one is open
event.stopPropagation();
}
function htmlMouseDown() {
this.close();
lastOpened = null; // nothing is open
}
That should work in a way that the last opened one always close itself before opening a new one.
Thanks for the answers. They're really appreciated. I did figure out a way of doing it that I'm satisfied with. Here's how:
$(myDropDown).mousedown(dropDownMouseDown);
$("html").mousedown(myDropDown,htmlMouseDown);//Pass in the dropDown as the data argument, which can then be accessed by doing event.data in the handler
function dropDownMouseDown(event) {
event.target.open();
}
function htmlMouseDown(event) {
if (event.target!=event.data)//event.target is the element that was clicked, event.data is set to the dropdown that this handler was added for. Unless these two elements are the same then we can...
event.data.close();///close the dropdown this handler was added for
}
Can't believe I didn't think of that. In my case though the element that opens/closes has child-elements so event.target could be one of the child elements instead of the element that the handler was attached to. So I changed my html-element-handler to this:
function htmlMouseDown(event) {
var element=event.target;
while (element) {
if (element==event.data)
return;
element=element.parentElement;
}
event.data.hide();
}

jQuery: Get return of an onclick-function from an anchor

Is there a way to get the return-value of an onclick-function like confirm into a jQuery-function?
I have links which have an onclick-event for confirmation which returns true or false:
<a onclick="return confirm('Sure?');" class="delete" href="delete.php">Delete</a>
This is a given structure and I have no possibility in changing it.
But I would like to do something like this:
$('a.delete').click(function() {
if (confirm_from_onclick == true) {
//do some more before really returning true and following the link
}
});
If there is no way for you to change the HTML markup, you need to remove the complete onclick inline-handler from that node and to it in your unobtrusive event handler.
This could look like:
$(function() {
$('a').each(function(_, anchor) {
var onclk = anchor.onclick; // store the original function
anchor.onclick = null; // delete/overwrite the handler
$(anchor).bind('click', function() {
if( onclk() ) {
// do something
}
return false; // call stopPropagation() + preventDefault()
});
});
});
Since you're dealing with an onclick inline-event handler, you cannot stop or prevent that from firing with an unobtrusively bound event handler. It'll always fire first, so you need to completely remove the original event.
You don't really need to store the function, you also could just set the onclick to null and rewrite the logic in your own event handler. I did it for convenience only.
Demo: http://jsfiddle.net/em9KP/
Really simple answer and might not be exactly what you're looking for, but why not remove the "onclick" event from the anchor, then handle everything inside the click function?
As in, create the confirm dialog inside the function.
<a class="delete" href="delete.php">Delete</a>
$('a.delete').click(function(e) {
e.preventDefault();
if (confirm('Sure?')) {
//do some more before really returning true and following the link
}
});
EDIT:
Sorry! Missed the part where you mentioned that it's a set structure and you have no way of changing it. Working on an alternative.

Categories