onclick handler doesn’t always run while child elements are being updated - javascript

I have a row of <a> elements which have onclick handlers:
<a onclick="selectCoin('MER');">
<div id="MER">
...
</div>
</a>
The interior of the <div> child gets overwritten continuously to update some text inside the buttons. The updating is done by querying the #MER selector, and assigning to innerHTML. I noticed that the onclick handlers don’t always run if the <div> element is being updated in the background. Oftentimes, I have to click it two or three times before the onclick hander actually gets invoked. If I make the <div> elements static, the onclick handlers run consistently and reliably.
Why does updating the <div> child cause the onclick handler to stop working consistently? How do I fix this issue, while still updating the contents of the button?

To generate a click event, an element must receive a mousedown followed by a mouseup.
If the element goes away after the mousedown and is replaced with a new one, the click event is not sent.
You could do your own mousedown/mouseup detection on the <a> element, but if nothing inside the element is really clickable, you can disable mouse events on the child elements, so that they all occur on the <a> element
on your "MER" div:
style="pointer-events:none;"
Working fiddle:
https://jsfiddle.net/8h17rcpz/

click events are only generated if a mousedown and mouseup pair of events are fired consecutively on the same element, which is not going to happen if it gets swapped between down and up events.
The simplest solution would be to replace onclick in HTML source with onmouseup. What side effects or undesirable behavior that might produce is not possible to assess from the information provided.

Related

Any other way to detect click outside?

The common method is to attach a click event listener on body and check if e.target is your element, or if e.target contains your element.
This is fine and it works, but i was wondering if there some other way to do this that does not require attaching events on some other element outside your target, like body?
My use case is a select box component for vuejs. It doesn't feel right to attach click listener on bodies for each select box component.

Javascript blur event on wrapper div

I have inner input field and a wrapper div element.
I have added contenteditable attribute to the div element in order to be able to set focus on it.
I would like to catch the onblur event of the div.
Now, If I'm in focus on the input field and click with the mouse on different place in the screen
the blur event of the input field is called of course but not the blur event on the div.
Of course this makes sense - this is how the browser works.
But anyway,
I was wondering if and how it is possible to achieve that.
<div id="wrapperDiv" contenteditable class="wrapperDivClass">
<input id="innerId">
</div>
For blur event to fire on an element, the element needs to receive focus first. But elements do not receive focus by default.
You can add tabindex="0" or contentEditable to your div so it will receive focus.
See it in action: http://jsfiddle.net/t25rm/
Answered here:
Div - onblur function
Issue solved when I changed the blur event to focusout
From MDN web docs:
The focusout event is fired when an element is about to lose focus. The main difference between this event and blur is that the latter doesn't bubble.
This is exactly what I needed.

Trigger something if both inputs are blurred ONLY

I have a <form> containing two text <input>s side-by-side. When both of these inputs lose focus, I want to do some stuff (send an Ajax request to server and replace them with something else in the DOM). However if I click or tab from one of the inputs to the other, I don't want to do those things.
Setting an onBlur event handler on the <form> element works fine using my setup, but there doesn't seem to be any way to determine if the other form input is my next target. If I examine document.activeElement in my handler, it points to the <body> element (in Chrome) at that point. Only afterwards does it change to the other input.
Is there any way to reliably do what I'm asking? Solutions involving jQuery or other libraries are fine.
So it turns out that event.relatedTarget was what I was looking for - this will return the DOM node receiving focus on a blur event, so it's just a matter of setting a conditional to see if it matches the other field.
However, while this works great in Chrome, relatedTarget currently isn't implemented properly in other browsers. Apparently there's a couple of workarounds:
In IE11, document.activeElement does actually get set to the receiving element at the time the event fires, so you can use that.
In Firefox, apparently event.explicitOriginalTarget can be used instead.
Try ..
Set a global variable that stores what you last blurred from. Call it x.
Set a blur event on all elements, and set x to the last element you blurred from.
Set a focus event on all elements, and if x is not one of your two elements, then run your script.
Give to them both ids, like this:
<input id="id1" />
<input id="id2" />
Then, with jQuery, you can call blur() nested with the two ids.
$('#id1').blur(function(){
$('#id2').blur(function(){
//do your thing
});
});

(Why) does accessing outerHeight cancel click/mouseup/focus event?

I've encountered a weird issue - accessing any DOM element's outerHeight, or simply logging that element to browser's console in a blur event seems to cancel the click event that caused the blur - when some special criteria is met.
Here's what I'm trying to do:
There are 2 inputs, first is initially visible, the other hidden
When the first input receives focus, the 2nd input will be shown
When the 2nd input receives focus, it remains shown
When both inputs lose focus, and none of them are focused, the 2nd input will be hidden
However, it seems that when I simply try to do something like $('body')[0].outerHeight in my blur event handler, the second input never receives the click or focus. Since it's too much to simply write down, here's a link to JSFiddle that demonstrates the issue: http://jsfiddle.net/7K2Ha/3/
Note - it happens the same with plain JS
Can anybody explain why this happens and are there ways around this?
Firstly, you bind focus/blur events to all .jq inputs. And then you add next event handlers (which means, that all of them will be executed - including the first one, which removes the has-focus class).
Check this fiddle, line 20: fiddle here.
$('#input3').unbind('blur').on('blur', //...
The problem is not specific to offsetHeight, and I believe if you comment out that line you don't get the effect simply because the browser will not call an empty function block for performance/optimizer reasons.
It seems to come down to the execution order of the events (especially problematic when more than one jquery event of the same type is wired up).
Check out what happens when you wire up the blur/mouseover/etc. events that all $('input.jq') elements have in common at the very end: http://jsfiddle.net/7K2Ha/6/
All I did was move the topmost javascript block to the bottom, and suddenly it works. In that case, the focus event seems to occur before the blur event. Notice how before the focus would never be called.
As a more robust solution, I'd only work with one event that covers both:
$('input.jq')
.on('focus', function() {
// get focus'ed elements parent
var thisParent = $(this).parent('div')
thisParent.addClass('has-focus');
// get all other parents
var otherParents = $('input.jq').parent('div').not(thisParent);
otherParents.removeClass('has-focus');
})
See updated JSfiddle.

JavaScript autoclick child node element

I've been endlessly looking for a working way to automate a mouse click on a specific element using javascript (I'm making a user-script). The structure is like the below:
<div id="elementContainer">
<div class="item1" style="width: 50px; height: 50px;">AutoClick Here!</div>
</div>
item1 is the thing I want to automate a click on. I've tried lots of approaches, e.g. getting the element and creating/initialising/dispatching a 'click' event on it, calling .click() on it etc, but to be honest I'm new to javascript and don't hugely know what I'm doing!
I can happily get the element and make changes to it (like changing the innerHTML), but want to be able to simulate/automate a click on it too. I would be very grateful for any advice on how to proceed.
Many thanks in advance!
Calling .click() on the element should work just fine.
var container = document.getElementById('elementContainer'),
innerDiv = container.getElementsByClassName('item1');
innerDiv.click();
That said:
The click method is intended to be used with INPUT elements of type button, checkbox, radio, reset or submit. Gecko does not implement the click method on other elements that might be expected to respond to mouse–clicks such as links (A elements), nor will it necessarily fire the click event of other elements.
Non–Gecko DOMs may behave differently.
When a click is used with elements that support it (e.g. one of the INPUT types listed above), it also fires the element's click event which will bubble up to elements higher up the document tree (or event chain) and fire their click events too. However, bubbling of a click event will not cause an A element to initiate navigation as if a real mouse-click had been received.
Have you bound any click event handlers to that <div>?
Read this: http://www.howtocreate.co.uk/tutorials/javascript/domevents

Categories

Resources