Morning,
When using Element#observe(), is it necessary to call Element#stopObserving() to completely get rid of the event handler?
Or will some inbuilt mechanism realize that the handler is no longer necessary when the Element gets removed in any way (.update() on a parent, not just .remove()) ?
Updating large dynamic lists with several bindings per entry every now and then. Drawbacks when using something like
ul.update(''); data.each(..
ul.insert(X); X.bind(..); ..);
Thanks!
If an element is no longer part of the DOM then garbage collection will probably deal with it's handlers, but that will depend on the browser.
I would suggest you not worry about what is out of your control and look at using Event.on() instead.
Related
This may not be the most clear way of asking what I'm asking but, I have a plugin that manages multiple grouped elements. It is my understanding that a plugin should be capable of destroying itself when the need/want arises. So my question is, is there any kind of hook that either jQuery or JavaScript will fire when a DOM element is removed from the page to assist in JavaScript's garbage collection and avoid memory leaks from event handlers and such? If I am unclear in what I am asking I apologize but I honestly don't know the best way to ask this question
Yes, there is. Although you will need either jQuery UI or to write your own special event. The problem is it only works if the element is removed using jQuery. Aside from that, you would need to use DOM events or the recommended solution - DOM Mutation Observers.
These questions should help you further:
jQuery - Trigger event when an element is removed from the DOM
How to detect element being added/removed from dom element?
By the way, that is the keyword you missed - "event". That's what these "hooks" are called in jQuery/DOM.
TLDR Below
JS Fiddle To Demo
I've been really involved in recreating the tools that are foundations of premiere JS Libraries to better improve my skills. Currently I'm working on functional data-binding a la Angular.
The idea of data-binding is to take data and bind it to elements so that if manipulated all elements subscribed will change accordingly. I've gotten it to work but one thing I hadn't considered going into it was the issue with innerHTML vs value. Depending on the element you need to change one or the other( in the demo above you'll see that I needed to specifically single out the button element in a conditional statement because it has both, but that's kind of a fringe case )
The issue is that in order to capture a SPAN tag update I needed to trigger an event to happen, and the easiest one to manipulate for Text Boxes/Textareas was 'keyup'.
In my function then, if you pass in an element with no value property we assume you're going to be updating innerHTML, and we setup an observer to determine if the element ever mutates, and if it ever does, the observer will emit a 'keyup' event.
if (watchee.value == void(0)) {
var keyUpEvent = new Event('keyup');
var observer = new MutationObserver(function(mutations) {
mutations.forEach(function(mutation) {
watchee.dispatchEvent(keyUpEvent);
});
});
observer.observe(watchee, {
childList: true
});
}
Now it may just be my paranoia, but it seems like I might be tunneling into a can of worms by faking 'keyup' on an element that doesn't natively have that support.
TLDR:
I'm curious if there's an alternative way to make, a.e. a span tag reactive other than faking a 'keyup'/'keydown'/'change' event? For instance, is there a way that I can make my own pure event(by pure I mean not reliant on other events) that checks if innerHTML or value has changed and then performs a function? I know that this is probably possible with a timer, but I feel like that might hinder performance.
EDIT: just an aside. In the demo the function called hookFrom works by taking a DOM node and returning a function that will take the receiving dom node and continues to return a function that will take additional receiving dom nodes. :
hookFrom(sender)(receiver);
hookFrom(sender)(receiver)(receiver2);
hookFrom(sender)(receiver)(receiver2)(receiver3)(receiver4)...(receiver999)...etc
JS Fiddle To Demo (same as above)
There is nothing inherently wrong with creating a similar event on a DOM node that doesn't natively have that functionality. In fact this happens in a lot of cases when trying to polyfill functionality for separate browsers and platforms.
The only issue with doing this sort of DOM magic is that it can cause redundancy in other events. For instance the example given in this article: https://davidwalsh.name/dont-trigger-real-event-names shows how a newly minted event using the same event name can cause problems.
The advice is useful, but negligible in this specific case. The code adds the same functionality between text boxes, divs, spans, etc... and they are all intentionally handled the same way, and if the event would bubble up to another event, it would be intentional and planned.
In short: There is a can of worms that one can tunnel into while faking already explicitly defined event names, but in this case, the code is fine!
I am making mouse click events and I'm trying to dispatch it to some node several times in a row. For that I am using the same MouseEvent object and for some reason this approach does not work. Yet, when I create event manually each time, system works. Does anybody know what is the reason for this behavior?
I've tried to change the timeStamp, but problem still occurs. I can solve the problem like I mentioned before, but I am interested in how this MouseEvent and corresponding dispatching and handling subsystems really work. MouseEvent specification that I've found on MDC pages seems to lack a lot of information.
Tnx for the help!
This is actually a security mechanism, dispatching an event that has been dispatched before isn't allowed. An event always has additional data associated with it, for example whether it comes from a trusted source (user's keyboard rather than JavaScript code). Some attacks (mostly against MSIE because it had mutable event objects) were using this - they caught a trusted event, changed it and dispatched it again elsewhere (changing might not always be required, dispatching it at a different element is enough for some attacks). In the end disallowing redispatching of events turned out to be the best solution. After all, this functionality isn't really required: creating a new event object with identical properties (minus hidden data) isn't exactly hard.
Pretty much all the security issues in this area were related to the file input control. Some time ago Firefox decided to change the file input UI radically and disallow entering the file name directly. I wonder whether this change made redispatching of events a non-issue. I doubt that anybody will be willing to risk opening this can of worms again however.
I think the reason you can't reuse the same MouseEvent object is because the event system maintains some internal state in the event objects so they can implement things like bubbling and cancelling. You may just have to stick with creating distinct event objects.
Reading Document Object Model Events may give you a better understanding of how the DOM event system works.
Without knowing what you have now ill just go under assumption.
Make an event function:
function clickEvent(event) {
//do something
}
Attach it:
obj.onclick = clickHandler;
And you can do this multiple times to multiple objects.
I have a grid and there is a column which contains <a> anchor tag with some additional information in <data-..> tag and has a class name <class='myspeciallink'>. And in my unobtrusive JS script I select all the elements with that class name and apply live('click'). I need that to be live() because the grid gets generated in the runtime.
What happens inside the live('click') handler? I use that additional data and add a <div> to the page based on that data. Which in its turn used to generate jQuery UI dialog. It works great on my computer.
But! How could that work in real-world? Should I be bothered about possible performance implications? I feel that applying live() on more than a dozen elements instantaneously
would affect the performance. Especially with rather complicated handler like mine - it needs to get the data, parse the data, create a div, apply a dialog and etc.
Does that smell like a bad design? Could you suggest a different approach or my concerns are unfounded? Can I use some sort of a profiler tool to find the bottlenecks in my javascript?
UPD: Still nobody suggested any profiling tool. firebug and chrome dev tools are good, but maybe there is something even better?
live("click") is actually better up-front from a performance standpoint: Instead of binding an event handler to each matched element, you're applying a single event handler which waits for events to bubble up and then sees if the element that triggered the event matches the selector .live was called on.
Compare this to $('selector').click(...) which does loop over each element and bind a new event handler. live('click') has no additional overhead regardless of how many page elements match its selector. Depending on how many elements your selector matches, using .live can avoid a delay of up to a few seconds during the initial load of each page.
However, the event handler must check each event which bubbles up against its selector, to see if there is a match. This is going to add a small amount of overhead to every click event, but chances are very good that your users will not notice the difference.
Peter bailey also has a nice post about this: Performance difference between jQuery's .live('click', fn) and .click(fn)
I'm dynamically adding a lot of input fields through jQuery but the page gets really slow when reaching 200+ inputs (think of the page like a html excel sheet). This is fine really because this scenario is not very common. However, when I dynamically remove the input fields from the page using jQuery's htmlObj.remove() function, the page is still slow as if there were hundreds of inputs still there. Is there any way to explicitly free memory in jQuery/javascript?
My experience with this is from using Firefox. When using Internet Explorer, the page is really slow from the start but that's a whole different story.
The technique I'm using is called event delegation as it's supposed to be the least memory resourceful approach, compared to having all handlers explicitly bound to every object on the page.
Sadly, blur and focus events do not work with event delegation and therefore I need to bind these to every input. This could possibly be the memory hog here. Also, in Firefox it seems I can't use checkboxes for 'changed' or 'key[down|up]' events in event delegation as these checkbox events do not bubble up to the document. Here binding explicitly too.
Anyone can share some experience with this? Can't really show a demo right now as the site has not been launched yet.
Thx.
read this, I'm sure it will help.