In javascript DOM this refers to the element clicked which seems more logical than in .NET where this refers to the parent. Why this choice?
The button is also a class. If it was truly OOP it would consider button as first class citizen also. So It's not a question of paradigm here it's rather a question of implementation. My hypothesis is that was probably easier for MS to do so because the physical module exists for parent not for child.
But for us it is a pity since you have to cope with this sender which seems as it is foreign to the button whereas it is himself !
They are different systems and different paradigms.
In .NET, your handlers are passed a "sender" argument which contains the object. The handlers reside in the form object or user control, so "this" refer to that class (if you do a double-click type of adding a handler). If you manually created the handler, then it can be part of any object (not necessarily the form object), and "this" will map to different things. .NET events are also not bubbled or captured.
In DOM, your handlers are not passed a "sender" argument. However, "this" refers to the object. In DOM, events can bubble or captured.
There is no reason why the designer of JavaScript cannot provide a "sender" argument though, and map "this" back to the object holding the handler. In my opinion, these were just historical choices being made when the world was much simpler.
In C# the handlers are methods of the Form object and thus this also references this object.
However, I think you can use one of the handler's arguments to get the element related to the event.
Related
Here, it reads, "Therefore, this interface can be obtained by using binding-specific casting methods on an instance of the Node interface."
What does it mean that the interface can be "obtained" by "using the binding-specific casting methods?"
What are "binding specific casting methods?"
I understand that the word "binding" here is referring to a language binding. And, that "casting methods" are specific to the binding. But, it still isn't clear to me what the sentence means.
Practically, I would like to create an instance of an Object that inherits from EventTarget.prototype, and call EventTarget.prototype's addEventListener on it.
I understand that that is not possible. It is discussed here. I think the reason it is not possible may be related to this question.
IDL language bindings.
The link in the post is to a DOM2 specification of an "EventTarget" interface, written in IDL ("Interface Definition Language"). As a definition language, IDL describes what must be provided in a an interface written in a real language such as JavaScript, Java, MicoSoft Visual Basic for applications, or C++ for example.
"this interface can be obtained by using binding-specific casting methods on an instance of the Node interface."
is a technical way of saying "use the methods and properties documented for the language you are using, on a DOM node, rather than the exact wording of the specification provided here. The most binding we are most familiar with in web pages is, of course, for JavaScript. "Casting methods" may refer to how the implementation would automatically perform conversions between programming language and the DOM as required - e.g. converting JavaScript numbers to and from integer representations in some DOM attributes.
EventTargetPrototype
In Firefox this in object in the prototype chain of DOM nodes containing addEventListener and associated functions. Again it Firefox you can access it as
Object.getPrototypeOf( Node.prototype))
and then create an object prototyped on it, using
Object.create(Object.getPrototypeOf( Node.prototype))
This didn't work for dispatching events however. It seems additional support ( perhaps the Node interface as well?) is required. Using a HTMLSpanElement for the target "node object" worked in Firefox for dispatching and listening to an event without adding it to the DOM:
let a = document.createElement("SPAN");
a.addEventListener( "custom", function() {console.log("wow");}, false);
a.dispatchEvent( new CustomEvent("custom"));
Would I use this in production code? Definitely not. Except if thousands had tested it before me, in every browser type I might wish to support!
Since ReactJS uses event delegation, is there a way to access the internal node/events mapping?
It doesn't have to be pretty, wrapping one of the responsible functions (like the equivalent of jQuery's on()) and doing custom housekeeping would work fine and would actually be preferable to accessing that data through an object of some sort.
If I could get the selector, event and handler (optional) that'd be great, as I'm already doing this for jQuery.
The reason I'm asking is because I'm trying to optimize Arachni for ReactJS applications and having prior knowledge of which elements actually have event handlers (and what they are) would result in a much more efficient scan.
In addition, that data would be of great value when scanning web applications for non security reason's as well, you could gather some very interesting stats that way.
I have a backbonejs app that works something like this:
[Backbone MODEL] <----> [Backbone VIEW] <----> [DOM ELEMENT]
The model and view are created and assigned to local variables within a function scope. If I remove the dom element (by calling jQuery().empty() on it's parent element), will this delete all references to the View & subsequently the Model to avoid zombie objects/memory leaks?
As long as you are never assigning the model or view variables to anything that will stick around. Be wary of closures around the variables, don't attach the variables as attributes of any other object, don't attach the view or model to any events from any other objects. Then yes, this will clean itself up.
But those are some pretty strict rules to abide by and don't play well with most apps. You should be handling the removal of event handlers explicitly, and deleting any attribute on any object you had created.
I have a few articles related to this (seems likely you've read at least one of them, already):
The classic Zombies post: http://lostechies.com/derickbailey/2011/09/15/zombies-run-managing-page-transitions-in-backbone-apps/
an implementation of the zombie's cleanup code, plus more, as an object on it's own: http://lostechies.com/derickbailey/2011/12/12/composite-js-apps-regions-and-region-managers/
Memory management in JavaScript and Backbone: http://lostechies.com/derickbailey/2012/03/19/backbone-js-and-javascript-garbage-collection/
As you may or may not be aware as of jQuery 1.7 the whole event system was rewritten from the ground up. The codebase is much faster and with the new .on() method there is a lot of uniformity to wiring up event handlers.
One used to be able to access the internal events data and investiate what events are registered on any given element, but recently this internal information has been hidden based on the following scenario...
It seems that the "private" data is ALWAYS stored on the .data(jQuery.expando) - For "objects" where the deletion of the object should also delete its caches this makes some sense.
In the realm of nodes however, I think we should store these "private" members in a separate (private) cache so that they don't pollute the object returned by $.fn.data()"
Although I agree with the above change to hide the internal data, I have found having access to this information can be helpful for debugging and unit testing.
What was the new way of getting the internal jquery event object in jQuery 1.7?
In jQuery 1.7, events are stored in an alternate location accessible through the internal $._data() method (but note that this method is documented as for internal use only in the source code, so use it at your own risks and be prepared for it to change or disappear in future versions of the library).
To obtain the events registered on an element, you can call $._data() on that element and examine the events property of the returned object. For example:
$("#yourElement").click(function() {
// ...
});
console.log($._data($("#yourElement")[0]).events);
Should I pair every data() call with a later removeData() call?
My assumptions: jQuery's remove() will remove elements from the DOM, and if I don't have any other references to remove, I don't have to do any more clean up.
However, if I have some javascript var or object referring to one of the elements being removed, I'll need to clean that up, and I'm assuming that applies to jQuery's data function, too, because it's referencing the elements somehow.
So if I do need to call removeData before remove, is there a shortcut to remove all data associated with an element or do I have to call each explicitly by name?
Edit: I looked through the source code and confirmed what Borgar and roosteronacid said. Remove takes the elements out of the dom and deletes any events and data stored with them - which is convenient, but makes me wonder when you would use removeData(). Probably not often.
jQuery's data does not keep a reference to the element so that you don't need to worry about memory leaks. Its intended purpose is to solve this exact problem.
A slight simplification of how it works:
An id member is added to each "touched" DOM node. All subsequent actions involving that DOM element use that id.
var theNode = document.getElementById('examplenode');
theNode[ 'jQuery' + timestamp ] = someInternalNodeID;
You can access the id using the same function jQuery uses:
someInternalID = jQuery.data( document.body );
When you append data to the node it stores that on the jQuery object, filed under the node's internal id. Your $(element).data(key,value) translates internally to something like:
jQuery.cache[ someInternalNodeID ][ theKey ] = theValue;
Everything goes into the same structure, including event handlers:
jQuery.cache[ someInternalNodeID ][ 'events' ][ 'click' ] = theHandler;
When an element is removed, jQuery can therefore throw away all the data (and the event handlers) with one simple operation:
delete jQuery.cache[ someInternalNodeID ];
Theoretically, you may therefore also remove jQuery without leaks occurring from any references. jQuery even supports multiple separate instances of the library, each holding it's own set of data or events.
You can see John Resig explaining this stuff in the "The DOM Is a Mess" presentation.
The whole point of jQuery is to abstract away from crappy JavaScript implementations and bugs in browsers.. such as memory leaks :)
.. Yup; all associated data to an element will be removed when that element is removed from the DOM.
By and large, javascript is fairly good about knowing when it's appropriate to collect the garbage, and unless you're writing very large-scale or long-running client-side apps, I'd say the memory involved is mostly inconsequential and trying to second-guess it isn't gonna gain you a lot.
Determining what unfinished lexical closures or other tricky javascript in jQuery might still be accessing your given data could be pretty complicated in some cases.
As far as I'm aware, though, if you store a reference to whatever you got with jQuery's data function then it would continue to exist after the element is removed, so removing that reference would be necessary as well. Some simple test cases would give you a more definite answer.