Trying to click() a button with no onclick event - javascript

I'm trying to click Medium's clap button with .click().
Here's what I've tried:
On a medium post, I run let btn = document.getElementsByClassName('clapButton')[0]; to get the clap button, then run btn.click();.
After inspecting the button, it doesn't have an onclick event, so i'm not sure if i'm getting the wrong element, or if there's some other way to trigger it.
Is there some jquery code or something that's attaching the event to the button differently? Thanks!
Edit
Sorry for missing details, i'm trying to run the code through a firefox extension. The code also doesn't work through firefox developer's console (I ran the code above). I'm not sure why it seems to work on Chrome just fine.

Your question is pretty vague, but I'll try to address it from as many angles as I can.
One: if you check the value of btn.onclick and get null or undefined, that doesn't necessarily mean the button doesn't have a click handler. There are two ways to add event listeners to elements:
btn.onclick = function() { ... };
btn.addEventListener('click', function() { ... });
In the latter case, the function won't be assigned to the onclick property of the element. addEventListener can actually be used to add multiple listeners to the same object, all of which will trigger when the event occurs.
Two: it's also possible that the button itself really doesn't have any click handlers at all. However, if any of its ancestors do, then those handlers will also be triggered when the button is clicked. This is called event propagation or bubbling, if you want to read up on it.

Related

Can cancel onclick event after blur(focusout)?

Because I have a check function, and check function happens in textarea when blur and click save button.
All things are good except one case. When I in textarea, I directly click the button. This will happen twice check (first check to happen in a blur, and then happen in onclick event). I don't like it.
I solve this problem using two methods.
1: Use one flag to detect whether check before. When click saves button, check this flag.
2: Use mouse-down replaces of onclick method and event.preventDefault. This first check will happen mouse-down, and not trigger blur.
I think the other method. Firs check happens in a blur, and then "not" happen in onclick event. So I want to know Can cancel onclick event after blur(focus out)? If not why? (I don't know how to cancel or I don't find solutions. Thanks.
Code like
blur() {
checkfunction();
}
onclick() {
checkfunction();
save();
}
you can use event.stopPropagation();
example:
blur(){
// code textarea
};
onclick(e){
e.stopPropagation();
// code button
};

jQuery trigger(clickEvent) behaves differently to clicking the item

I have a HTML5 canvas element, which the user can interact with, it has an onclick handler that just catches the event and stops it, as follows:
this.canvas.onclick = function(e){
$("#mycanvas")[0].focus();
e.stopPropagation();
e.bubbles = false;
};
I have an onclick handler on the document, as follows:
document.onclick = function(e){
//do something I only want done when the canvas is NOT clicked
}
When I click on the canvas, as expected the document.onclick handler is not fired. However, I also need to be able to trigger the click programatically, for this I am using jQuery:
$("#mycanvas").trigger($.Event(savedClickEvent));
when this code runs, the document.onclick handler is triggered. From looking at the jQuery.trigger code, it seems to be wanting not only stopPropagation(), but also preventDefault().
Why is there a discrepancy between the requirement of preventDefault() on click, and on trigger? Is this a bug in jQuery that I need to workaround, or should I not be calling stopPropagation() without preventDefault() - my understanding of these two functions is that they do fairly different things.
Bonus question: Why does $("#mycanvas")[0].click return function(){[native code]}? I suspect this is what is causing the problem.
Edit:
It seems jQuery doesn't support inline event handlers. Using addEventListener fixed the problem for click but not for mouseup - I ended up getting around this issue by not using jQuery at all, instead I used document.getElementById("mycanvas").dispatchEvent(savedEvent). I left this open in case I get a meaningful response to the bug report (https://github.com/jquery/jquery/issues/3660#issuecomment-299667529)

Method for triggering certain click event using .trigger() but suppressing all others

My situation is that I am trying to trigger a single event using the jQuery .trigger() method. However the element I am triggering has multiple click event listeners.
Actually finding what these listeners are and what they trigger from the source code is probably not viable as its included in the sites main JS file and its all minified and pretty much unreadable.
At the moment I know that the element when clicked performs some kind of ajax call and loads more data into the DOM of the page (which is what i want to trigger), however it also displays an overlay (which is what I want to suppress temporarily).
As its just an overlay there are workaround I can make; using a display:none on it straight after click etc. However it would be much more elegant if i could somehow suppress all click events on this element except the desired event.
Any ideas if this is actually possible? And if so how I would go about it?
You need to register your own event at the top of the event chain. And cancel the event chain in your event. Here is a solution with writing a custom jquery extention.
$.fn.bindFirst = function (which, handler) {
var $elm = $(this);
$elm.unbind(which, handler);
$elm.bind(which, handler);
var events = $._data($elm[0]).events;
var registered = events[which];
registered.unshift(registered.pop());
events[which] = registered;
}
$("#elm").bindFirst("click", function(e) {
// edit: seems like preventing event does not work
// But your event triggers first anyway.
e.preventDefault();
e.stopPropagation();
});
Reference:
https://gist.github.com/infostreams/6540654
EDIT:
https://jsfiddle.net/8nb9obc0/2/
I made a jsFiddle and it seems like event preventing does not work in this example. There might be another solution.

Synchronising browser events in JS

This is a bit of an abstract question, but I've been pondering its usefulness, and maybe it's either already been solved or inspires someone to do something based on it.
Well recently I ran across an issue whereby three browser events were fired, all as the result of a single user interaction: click, blur and focus. When the user clicks from one input to another, these events occur; and a similar set occur when the user tabs from one to another.
The trouble I had was that they fired in this order: blur, focus, click. It meant that, if the blur event caused DOM changes, the click event could be affected. I really wanted click, blur, focus - but that's not what the browser gave me.
I figured a general utility could be produced, capturing and cancelling browser events, then synchronising them and firing a single handler for all three. Perhaps extending the Event class so that the event could be reinstated.
Is there a more abstract design pattern I can use here? Something that will allow me to set up an arbitrary number of event listeners, and then fire a single event when all are complete? Does it have an implementation already? All advice welcome.
Dont need to break head around this! you can always trigger these events Programmatically
Note: object referenced here is any element selected using javascript selector.
Initially onBlur & onFocus do event.preventDefault which allows onClick to do its job first
var clicked=false;
object.onblur = function(e) {
if (!clicked) {
e.preventDefault
}
};
object.onfocus = function(e) {
if (!clicked) {
e.preventDefault
}
};
inside click event undo the above preventions and trigger the events in the order you wanted
object.onclick=function(){
clicked=true;
//Do anything
object.unbind('blur'); //this do undo prevent default
object.unbind('focus'); //this do undo prevent default
object.blur(); //in order you want
object.focus();
//make sure to put condition if click clicked
};
Thats it ! Hope it helps

Single user action firing two events - second event doesn't trigger

I’m running into this issue where a single action by the user is supposed to trigger two events but it only triggers the first one.
The scenario:
A user enters some text into a special field that modifies the layout on focusout , after entering the text, without leaving the field, they click a button.
What’s happening?
I have a focusout event on a text box and click event on a button. What I see is the focusout event gets fired but the click event never does.
I’ve encapsulated this in a jsfiddle:
http://jsfiddle.net/fCz6X/13/
$('#theText').focusout(function (){
$("#focusevent").text("Focusevent");
console.log("focus");
});
$('#theButton').click(function (){
$("#clickevent").text("Clickevent");
console.log("click");
});
So if you click in the text field then click the button I’d expect both events to fire, but we only see the focus out event.
I put in a temporary fix for this by having the mousedown event fire the button instead of a click event (this fires before the focusout event) but that is causing some other behaviors and issues that I don’t want to see. Due to those I think optimal solution is finding a way to get the focusout and click events to both fire. Does anyone have thoughts on how to fix this problem?
Edit: After seeing initial responses I dug a little deeper, the issue here is that the focusout event is changing the page layout which very slightly pushes the location of the button down. The click event triggers after the focusout is done but since the button is no longer in the exact same location, nothing happens.
Here is an updated fiddle that shows my problem
http://jsfiddle.net/fCz6X/11/
It's because you're calling alert - the focusout event fires, but before the browser recognizes you've clicked the button, the alert box blocks it.
Change your event handler to console.log or something else that's non-obtrusive and you'll be ok.
It is the Alert that is blocking.
Some browser security prevents firing too many window.alert at the time.
When trying with other triggers, it looks. You may try console.log()
$('#theText').on("focusout",function (){
$("#theText").val($("#theText").val()+"flb");
});
$('#theButton').on("click",function (){
$("#theText").val($("#theText").val()+"but");
});
I believe this is because the focusout event fires first, executing the handler, and the alert then prevents the browser from recognizing the click.
Try again with console.log instead of alert - it's less invasive.
As Joe said, the blocking alert call is what is breaking the event. Using a non-blocking call you will see both events.
If you really need to perform an alert like this, though, you can defer calling 'alert' until later using setTimeout()
$('#theText').focusout(function (){
setTimeout(function() { // alert after all events have resolved
alert("focus left text box");
}, 0);
});
Edit: In your updated fiddle the reason the click event never fires is because no click event occurs. If you move the button out from under the mouse on mousedown, there is no followup mouseup which is what initiates the 'click' event.
You may need to reconsider other aspects of your design. Your solution of using 'mousedown' is the best you can achieve because it's the only event that actually occurs.

Categories