JSFiddle - React, Tailwind, and code Playground
HTML
Try to click on black pixels of the underscore <i>and release the mouse <b>below</b> it</i> (but still within the button) - or vice-versa:<br>
<button onclick="clickHandler()"> click me ___ </button>
<hr>
Alternatively, click on the "empty" part of the button and release the mouse on the image (the other way rould would start to drag the image):<br>
<button onclick="clickHandler()"><img src="https://encrypted.google.com/images/logos/ssl_logo.png"></button>
CSS
button {
font-size: 40px;
font-weight: bold;
padding: 20px;
}
JavaScript
window.clickHandler = function() {
alert("clicked!");
};
// workaround only necessary for WebKit browsers
if (navigator.userAgent.indexOf('AppleWebKit/') >= 0)
(function() {
/* Note: using a timer might seem a ugly solution, but really should work fine
in any situation. I don't expect this to be a race situation and the timeout
value really isn't important. The timeout really is only used to put the
timer callback (the simulated 'click') at the end of the event queue. In case
the browser already emits the 'click' itself it will do so before the timer
callback is called regardless of the actual time that has passed. */
var clickBtn = null;
var timer = null;
function findButton(ev) {
var elem = ev.srcElement;
while (elem && elem.tagName!="BUTTON")
elem = elem.parentNode;
return elem; // null if no button
}
function startClickSimulation(btn) {
// don't start 2+ timers at once
stopClickSimulation();
timer = setTimeout(function() {
var e = document.createEvent('Events');
e.initEvent('click', true, true);
btn.dispatchEvent(e);
}, 1);
}
function stopClickSimulation() {
if (timer) {
clearTimeout(timer);
timer=null;
}
}
document.body.addEventListener("mousedown", function(ev) {
clickBtn = findButton(ev);
});
document.body.addEventListener("mouseup", function(ev) {
var btn = findButton(ev);
if (clickBtn && clickBtn===btn) {
startClickSimulation(clickBtn);
}
});
document.body.addEventListener("click", function(ev) {
stopClickSimulation();
}, true);
})();