Event delegation detecting outside clicks in (pure) JS? - javascript

Essentially, what I want to do is place an event listener on a list of dynamically generated elements. When clicking on those elements, the element changes to the <input> tag so the user may alter it. Clicking outside of that element would change the <input> tag back to the original <div> tag. Since only one element would have an input tag at a time, I just used querySelector("input") to search for the element, and detected if the click happened on that <input> element. If it did not, switch it back to <div>
My issue is that it's to my understanding that checking for clicks outside of an element, it would require a listener on the entire document, but when I checked for inside clicks, I used event delegation. However, with two separate listeners, it seems that one automatically undoes the other. Immediately after clicking on an element within the list, the the <input> tag switches back to <div> because the click happened when the element was a <div> thereby not allowing any user alteration.
How can I fix this issue? I was thinking that two separate event listeners wouldn't work, but I can't have one event listener both listen onto the entire document, and the list I apply event delegation onto.
I am fairly new to Javascript, so I would greatly appreciate any answers or corrections to my methodology. Thank you in advance.

Related

Unable to edit javascript in Chrome dev tools

I am attempting to edit some javascript code that is in the html of the page (not an imported js file). I am able to set break points and step through them, but I can not edit the javascript during the execution or before/after execution. I prettified ({}) and un-prettified the files. The code piece is not minified in this section.
Can I do this?
Does it matter that the code is inside an attached event. Ie a click etc.
I am useing jquery obviously.
I could have sworn this used to be a common feature. But it has been over a year since I have done a lot of javascript.
Using chromium / chrome there are several methods to modify the html of an existing document. At devtools
Select Elements tab, right click on the element to modify, select Edit as HTML , make modifications in frame containing element, then click outside of editor frame
Select Sources tab, select Snippets tab, right click and select New , write javascript, to execute in existing window press ▶ at right panel to run javascript in Snippets middle panel in existing window. For example if $("body").on("click", function() {alert(123)}) is added as a Snippet clicking body element should call alert(123). The event should also be listed in Event Listeners at right panel of devtools when inspecting element. Removing the listener may be somewhat more challenging; even if you click remove when hovering over the listener at right panel, as the event is already attached to the element. The simplest method would be to add a namespace to the event $("body").on("click.abcnamespace", handler), then call $("body").off("click.abcnamespace")
Modifying text existing handlers will not automatically affect , or cancel the event handler previously attached to the element. The simplest approach would be to copy and save existing javascript containing event handler, select Elements tab , right click on element that has event listener, select Event Listeners at right panel, when hovering over the window, document or HTMLElement having event attached a button should be displayed that says Remove. Click that button to remove the event listener. You should then be able to modify the saved event listener and add it back to the existing document with modifications being applied

How can I make 'clickable' elements have selectable text on iOS touch devices?

I have an element (a div) that has a number of javascript touch and mouse handlers on it. Apparently, this means the element is 'clickable', and it seems you are not able to select text on clickable elements on the iPad.
Is there any way around this? The event handlers are necessary for this to work right, but I'd also like users to be able to select and copy the text.
One solution is to make the div contenteditable=true. The event handlers still work, and I'm able to long-press to bring up the selector. But this would create its own set of problems and I'd like to avoid contenteditable if I can.
After some tinkering, I've found a workaround solution: Put the mouse and click handlers on the window instead of the element. Then, check the event target in the handler to see if the element of interest is what was clicked.
Not ideal, but it seems to work. I'm able to long-press and create a selection on an iPad.

Can I trigger a JQuery "change" event on an arbitrary HTML element type?

Say I have a JQuery object, el, that has selected an element. Is it legal, safe, and reasonable to call el.trigger("change") if the selected element is a DIV? What about other element types? For that matter, can I call el.change()?
The JQuery documentation for .change() says:
The change event is sent to an element when its value changes. This event is limited to <input> elements, <textarea> boxes and <select> elements.
It's not clear to me what "limited" means here. It might be referring to the fact that these are the only three element types that will produce these events automatically, but it could instead mean that other elements aren't allowed to.
Empirically, Chrome v28 seems to allow it, but I want to know if I can expect it to work in general.
Goal
I have a pseudo-control that's composed of a set of buttons and spans wrapped in a div. Each instance of the control maintains and manages a value, which is modified by clicking the control's buttons. When the value changes, I need to send an event out from the div so that the rest of the page can react. I don't want to listen for the click events outside the control, since that couples the surrounding code to the controls' internals and not all clicks change the value.
I could create a new event name, but the built-in "change" event seems like conceptually correct, so I'd rather use it if I can. As an added bonus, my page already a "change" handler bound the right place with the right behavior (because I have some input and select controls on the page, too).
I need to support IE8 and up, in case the answer varies by browser make and version.
There are no restrictions, you can trigger any event type you like on any HTML element.
The jQuery documentation is simply telling you that change is only automatically triggered on <input>, <textarea> and <select>

JavaScript events on related elements

I am wondering is the following behavior correct.
I have a label element linked to an input element via the "for" attribute, should this yield two click events on a single user click on the label? Specifically, put a click listener on window. Then, define checkbox with a label element linked to it using attribute "for". Click on the label text. The result is that checkbox will be checked and you will see two click events. http://jsfiddle.net/k55uD/2/
If this behavior is correct, are there more such cases, attributes, or whatever? Some spec would be nice.
Any help is appreciated.
P.S. I update the post with the example.
Clicking the label will trigger any onclick function attached to that label and any onclick attached to the input itself. Clicking the input will trigger only the onclick for the input.
This is very easy to test. See here:
http://jsfiddle.net/zptw3/
The DOM would treat each element separately, so both the label and the element it is 'for' can have event handlers defined. So yes, if both elements have an onclick handler and the click is within each element, both events will fire.
However this is something you have to define, you don't get a second click by default on the label just because it is 'for' the other element.
Basically, it is up to you - you can set it up to raise two events or a single event but out of the box you will get one event raised for the element you defined the handler on.
This explains events and event order pretty well, as well as offering some advise about browser quirks.
http://www.quirksmode.org/js/events_order.html
EDIT:
If you Specifically, put a click listener on window. Then you will get both events due to propagation, again this is explained in the link provided.

Javascript performance ? - Put events in html tag, or bind them?

I'm wondering which is better for performance... I have a "web app" sort of thing. It has a lot of javascript. When a button is clicked, a hidden div becomes visible. This new div has 5 buttons. Which is better for performance:
1.) put the button click events in the html tag of each button like onClick="alert('hey');"
2.) Attach events to each button when the div is visible, and then remove the events when I hide the div containing the buttons?
The reason I ask is because I imagine the page might get bogged down if the events in the html tags are constantly there. I figure the page might be faster to only have those events when the user can see the buttons to click them.
Any help is great! Thanks!
I would use event delegation.
This way you can freely add/remove any buttons without worrying about attaching events on each one of them. This approach is also more memory efficient, since you always have one single event handler instead of N ones directly on each button.
Unless those events are causing something to act as a link (which it seems Google learned to read) the put all this JS outside your HTML. It makes your code tidier and more maintainable.
Can't be sure about performance.
Keeping the event handlers registered when the elements are hidden will have no impact on performance, since the events won't fire.
Whether to use HTML attributes or the DOM to register event handlers isn't a matter of performance, it's a matter of clean design. You'll want to keep presentation as separate from behavior as possible. This means that if you use attributes, they should only bind the event to a handler (i.e. call a single function) rather than contain more complex code. That is, don't:
<button onclick="if ('red'==this.parent.style.backgroundColor) {...}">...</button>
do:
<button onclick="clickColorButton(event)">...</button>

Categories