Is $event necessary in Vuejs event handler? - javascript

I noticed people pass $event to listener functions, like this:
<li v-for="entry in entries">
<div #dragenter="doStuff($event, entry)">
...
doStuff(event, entry){...
But is this really necessary? If I don't need to access $event object in the doStuff(), can I just pass my entry variable only? I noticed it works, but I want to know if it's something OK to do, or is $event there for some reason?

You only need to pass $event if you want to deal with the original DOM event
From the Vue.js docs (highlighting added by me):
Sometimes we also need to access the original DOM event in an inline statement handler. You can pass it into a method using the special $event variable:
So, it's not a requirement, but an option. And it can indeed come in handy sometimes. But I normally omit it if I'm not making use of it.

It depends to the use case, sometimes you need to get the event object so you should pass it as a first parameter with that name $event like handle($event [,...]), if you don't need it you could simply pass your other parameters handle([,...]) without that parameter.

You can omit $event if you don't need to know some detail, such as which key is pressed for keyboard event. Also, the order of parameter is not fixed, just match them on both html and js part is okay.

$event in vue event-handlers
...are there to access the eventData that is passed through to the event handler.
E.g.
In native DOM-Events you have several properties on the event object that might be of interest to you (target especially).
In vue-emitted Events you can pass data: $emit('event-name', eventData). Your $event variable will take the value of this eventData.
$event is a special keyword vue uses. It allows you to pass the eventData as well as custom parameters to your event handlers.
Here is the official doku

Related

Passing object as a parameter in a template literal in javascript

I currently have an object which I want to pass as a parameter to another function inside a template literal:
var template = `<button onclick="onclick(${object})"></button>`;
However, this makes the parameter become a string value: [object Object] and doesn't pass the parameter. Is there any way to pass this parameter into the function?
Thank you very much in advance.
You are going to need to represent your object as a string. You can do this using JSON.stringify:
var template = `<button onclick="handleClick(${JSON.stringify(obj).split('"').join(""")})"></button>`;
You will need to escape double quotes (which this code does), and single quotes if used for your onclick event (this code doesn't).
onclick="onclick" actually calls window.onclick - meaning that it picks up clicks anywhere. You should use a different name (such as handleClick).
I would suggest refraining from using inline event listeners for reasons like this, and because they can cause issues if you ever need to adopt a content-security-policy.

SAPUI5 Data Binding get the value changed in change event

I am changing a model on websocket messages. I attached a change event function to it:
oBindingModel.attachChange(function(oEvent){}
Now, inside the function, I need to know which value has changed. I searched trough the oEvent Object as well as the returned object from calling this insinde the function. There is a mEventRegistry with an array named change, but I can not find the value in there. Is there any possiblity?
the object returned from this
Thanks!
In the event handler function, you have access to the oEvent object which contains every information about the source of the event.
To access this object, just call oEvent.getSource() in your anonymous function body.
This will return with the source object, which holds the whole model and a most important thing - the path of the changed property. Just call the oEvent.getSource().getPath() to retrieve this information.
Now you know the path, so you can retrieve the value from the model.

Getting access to $(this) in jQuery's .on() data object?

I am using .on() to add listeners a few items in my DOM - one input range field, and a number of blocks with the class .colorBlock. These event listeners only need to be active intermittently, and I would like to turn them .off() when they are not in use. Doing this means using a named function instead of an anonymous one.
So fair enough, except that I need to pass data into the callback functions. I know I can use the second (third?) argument field to pass in an object to the event, which is readable in the callback, but doing so seems to be scoping this to the event, instead of to the DOM node that .on() was listened on. See below for example:
$('#brushSize').on('touchend', { size: $(this).val() }, utils.setBrushSize);
$('.colorBlock').on('touchstart', { color: $(this).data('color') }, utils.setColor);
In my callback functions, I added an alert for e.data.color and e.data.size, and both call out undefined.
To make matters worse, this is a phone gap app, so I am limited in my options to trace what is getting passed around, so some of what I am assuming could be wrong about what is going on.
Any suggestions?
Thanks.
Let's break down this line:
$('#brushSize').on('touchend', { size: $(this).val() }, utils.setBrushSize);
It's exactly the same (other than the variables) as this:
var sizeValue = $(this).val();
$('#brushSize').on('touchend', { size: sizeValue }, utils.setBrushSize);
E.g., you're calling $(this).val(), and then passing the result of calling it in as part of your data object. So unless this is already what you want to get the value from at that point, it's not going to work.
If you want to get some information from the element when the event happens, just put that code in your event handler. For example, looking at this line:
$('.colorBlock').on('touchstart', { color: $(this).data('color') }, utils.setColor);
It looks to me like you're trying to get the color from the .colorBlock element that was touched. If so:
$('.colorBlock').on('touchstart', function() {
utils.setColor($(this).data('color'));
});
Or if you're going to reuse it:
utils.setColorFromEventElement = function() {
utils.setColor($(this).data('color'));
};
and
$('.colorBlock').on('touchstart', utils.setColorFromEventElement);
Side note:
There's also a possible second problem with that line. You're using utils.setBrushSize as the event handler. Note that within the call to setBrushSize, this will refer to the DOM element on which you hooked the event, not utils. Now, given the name utils, maybe that doesn't matter, but I thought I'd mention it.
More: Mythical methods, You must remember this
The value you're sending in the arguments object is always going to be the number it was when you called the .on() statement. That function's not going to be dynamically re-called every time the event fires.
Personally I think it's really ugly to have the util class go looking for some DOM element and get its value, when as you alluded, what you really want to do is have your util function run in the same scope as the .on() statement.
Your first instinct was probably correct. You don't want an anonymous function, because you want to be able to call off(). Ideally you want a named function that runs in the same scope as the thing that calls the on() statement. So what you want to do is bind the util function to your current scope:
$('#brushSize').on('touchend', utils.setBrushSize.bind(this));
Then in utils.setBrushSize, $(this) is whatever function you called .on() from.
edit Just a warning on this though: when you call off(), you want to call it like this:
$('#brushSize').off('touchend', utils.setBrushSize);
Not on a new scope-bound version of setBrushSize. JQuery should recognize it as equal to the original function you bound and turn it off.
re-edit I'm realizing now that your val() is in $('#brushSize') as that's the "this" you're trying to call... not the function holding the on statement. In that case you can do it this way:
$('#brushSize').on('touchend', utils.setBrushSize.bind($(this)));
So the solution for this particular problem ended up requiring that I strip this bit of code out of Phone Gap and rebuild it in a browser. I was then able to console.log the event that was being sent to the callbacks, and examine them to understand the event object better.
The solutions was to use event.target. This allowed to get the event.target.dataset.color for the .colorBlock listener, and event.target.value from the brushSize range listener.
So for future me, I would be good to have a solid working version of my app in the browser with the phone gap stuff stripped out, to do better testing for problems like this.

Converting a native browser event object to a jQuery event object

I am assigning an event handler function to an element through the native browser onclick property:
document.getElementById('elmtid').onclick = function(event) { anotherFunction(event) };
When I'm in anotherFunction(event), I want to be able to use the event object like I would with the event object you get in jQuery through the .on() method. I want to do this because the jQuery event object has properties and methods such as .pageX, .pageY and .stopPropagation() that work across all browsers.
So my question is, after I've passed in the native browser event object into anotherFunction(), how can I turn it into a jQuery event? I tried $(event), but it didn't work.
The obvious question here is: why don't you just use jQuery .on, .bind, .click etc to assign your event handling functions? The answer: I'm building a page that has a huge table with lots of clickable things on it. Unfortunately this project requires that the page MUST render quickly in IE6 and IE7. Using .on et al in IE6 and IE7 creates DOM leaks and eats up memory very quickly (test for yourself with Drip: http://outofhanwell.com/ieleak/index.php?title=Main_Page). Setting onclick behavior via .onclick is the only option I have to render quickly in IE6 and IE7.
Too long for a comment... Because the documentation is a bit vague on this... (I'm looking at 1.7.1 in the following)
jQuery.Event(event, props):
creates a new object
sets its type property to the event's type property.
sets isDefaultPrevented by normalized calls to all the ways to check if default is prevented.
sets originalEvent to reference the event you passed in.
adds an arbitrary set of properties provided by the props object argument.
sets a timestamp.
marks object "fixed".
What you get is basically a new object with a few additional properties and a reference to the original event - no normalization other than isDefaultPrevented.
jQuery.event.fix(event):
ignores objects that have already been marked "fixed".
makes a writable copy (by way of jQuery.Event()) and normalizes the properties mentioned here.
ETA:
Actually, looking closer at the code, jQuery.event.fix() should work - in the way described by #Beetroot-Beetroot. It's all that jQuery does to create the jQuery event object in an event dispatch.
You want jQuery.event.fix.
new jQuery.Event(nativeEvent)
Stores nativeEvent as the originalEvent property.
Handles some bubbling logic.
Timestamps the event
Marks the event as "jQuery's got this"
Gives it all the bubbling/default-preventing functions.
Note at this point the event doesn't have any "eventy" properties, just originalEvent, timeStamp, and the bubbling/default-preventing functions.
jQuery.event.fix(nativeEvent)
Does all the above
Figures out specific fixes ("fix hook") it will need to apply depending on the event type
Copies over a default set of properties from nativeEvent, plus specific ones from the fix hook
Fixes cross-browser issues with the target and metaKey properties
Applies specific cross-browser fixes and normalizations for the fix hook.
Try this:
document.getElementById('elmtid').onclick = anotherFunction;
with:
function anotherFunction(evt){
evt = $.event.fix(evt || window.event);//Note need for cross-browser reference to the native event
...
}
http://jsfiddle.net/Wrzpb/

Passing 'event' into the function as an argument

I'm novice with both JS and jQuery, and I'm a little bit confused about what situations would require you to pass event as an argument into the function, and what situations you would not need to.
For example:
$(document).ready(function() {
$('#foo').click(function() {
// Do something
});
});
versus
$(document).ready(function() {
$('#foo').click(function(event) {
// Do something
});
});
The event argument has a few uses. You only need to specify it as an argument to your handler if you're actually going to make use of it -- JavaScript handles variable numbers of arguments without complaint.
The most common use you'll see is to prevent the default behavior of the action that triggered the event. So:
$('a.fake').click(function(e) {
e.preventDefault();
alert("This is a fake link!");
});
...would stop any links with the class fake from actually going to their href when clicked. Likewise, you can cancel form submissions with it, e.g. in validation methods. This is like return false, but rather more reliable.
jQuery's event object is actually a cross-browser version of the standard event argument provided in everything but IE. It's essentially a shortcut, that lets you use only one code path instead of having to check what browser you're using in every event handler.
(If you read non-jQuery code you'll see a lot of the following, which is done to work around IE's deficiency.
function(e) {
e = e || window.event; // For IE
It's a pain, and libraries make it so much easier to deal with.)
There's a full accounting of its properties in the jQuery docs. Essentially, include it if you see anything you need there, and don't worry otherwise. I like to include it always, just so I never have to remember to add it in later if I decide that it's needed after all.
You only need the event if you're going to use it in the body of the handler.
Since you are using jQuery, you only put event as an argument if you need to use the event in the handler, such as if you need the key that was pressed on a keypress event.
In JS, without jQuery or Prototype etc., you need to pass the event as a parameter for standards compliant browsers like Firefox, but the event is not passed as an argument in IE. IE actually maintains a global variable window.event. So in your handler (sans library) you need to check if the argument is undefined; if so, grab the global variable.
function eventHandler(evt) {
var theEvent = evt || window.event;
//use the event
}
But a library like jQuery takes care of that for you.
I honestly don't recommend using a library until you have learned the language. But if this is for a job, the by all means use the library, but learn the details of JS on your own, so you can better appreciate it.

Categories

Resources