I am trying to simulate keypresses in a web application, it is for an embedded system but it uses a Webkit derived browser. I have tested the code in Chrome and get the same error.
I tried to use code snippets from this example from Yahoo, but I keep getting the same error when firing the event using dispatchEvent. "target" is an HTML element in the DOM tree.
function fireEvent(target) {
var evt = document.createEvent("UIEvent");
evt.initEvent("keypress", true, true);
target.dispatchEvent(evt);
}
It always throws:
"Error: UNSPECIFIED_EVENT_TYPE_ERR: DOM Events Exception 0"
I have tried createEvent("Events") as well and it always boils down to the same exception, both on the embedded system and in Chrome.
Ok, when doing further testing, it seemed that when all key event parameters was properly initialised, then dispatchEvent worked without fireing an exception.
The following code works.
function fireEvent(target) {
var evt = document.createEvent("Events");
evt.initEvent("keypress", true, true);
evt.view = window;
evt.altKey = false;
evt.ctrlKey = false;
evt.shiftKey = false;
evt.metaKey = false;
evt.keyCode = 0;
evt.charCode = 'a';
target.dispatchEvent(evt);
}
Keypress is an UIEvent. You should use initUIEvent( 'type', bubbles, cancelable, windowObject, detail ) rather than initEvent(). But for firefox, which implements a keyEvents, you should create a KeyEvents and initKeyEvents().
This one is old thread, just to update it I am adding another answer so that it makes more sense to any one.
initEvent() is deprecated It is still supported in some browsers but avoid using it.
There is better concise way to create events like this
function fireEvent(target) {
var event = new Event('build');
// Listen for the event.
target.addEventListener('build', function (e) { ... }, false);
// Dispatch the event.
target.dispatchEvent(event);
}
To add more data to the event object, the CustomEvent interface exists and the detail property can be used to pass custom data.
For example, the event could be created as follows:
var event = new CustomEvent('build', { 'detail': target.dataset.time });
Reference: Creating and Triggering Events
Related
I don't understand the motivation behind window.event or window.event.srcElement. In what context should one use this? What exactly does it represent in the DOM?
Here what w3school says about event object:
Events are actions that can be detected by JavaScript, and the event
object gives information about the event that has occurred.
Sometimes we want to execute a JavaScript when an event occurs, such
as when a user clicks a button.
You can handle events using:
node.onclick = function(e) {
// here you can handle event. e is an object.
// It has some usefull properties like target. e.target refers to node
}
However Internet Explorer doesn't pass event to handler. Instead you can use window.event object which is being updated immediately after the event was fired. So the crossbrowser way to handle events:
node.onclick = function(e) {
e = e || window.event;
// also there is no e.target property in IE.
// instead IE uses window.event.srcElement
var target = e.target || e.srcElement;
// Now target refers to node. And you can, for example, modify node:
target.style.backgroundColor = '#f00';
}
Not sure if this difference has been changed in newer browser versions but basically, "In the Microsoft event accessing model there is a special property window.event that contains the last event that took place." (from reference)
So, to write an event handler compatible across browsers you'd need to do something like this:
function doSomething(e) {
if(!e) {
var e = window.event;
}
var ele = e.target || e.srcElement;
// get the clicked element
// srcElement for IE, target for others
}
element.onclick = doSomething;
Reference:
http://www.quirksmode.org/js/events_access.html
function IndentifyMe(){
alert("You clicked on " + window.event.srcElement.tagName);
}
<body onclick = "IndentifyMe()">
Try this code, with lots of element in body tag, and try clicking different element
Events are the lifeblood of user interaction. Without events, you
couldn't interact with the page.
Event handlers are used to invoke some JavaScript when a certain action happens. If you want some
behavior to be triggered when the user moves their cursor over an element, you use the onmouseover
event handler.
"DOM Scripting: Web Design with JavaScript and the Document Object Model: Second Edition"
In a book, the code for handling mouseDown event is like this:
mousedownhandler: function (ev) {
mouse.down = true;
mouse.downX = mouse.x;
mouse.downY = mouse.y;
ev.originalEvent.preventDefault();
}
So my question is why use ev.originalEvent.preventDefault(); but not ev.preventDefault(); or return false; in this case (HTML5 game)?
jQuery alters the event methods / data in the returned event.
Using event.originalEvent, you're able to retrieve this back.
For example jQuery strips the dataTransfer api for dragged items, using the originalEvent you can use it again.
docs: "jQuery normalizes the following properties for cross-browser consistency ... To access event properties not listed above, use the event.originalEvent object"
In the proposed case it's used to access the preventDefault method (which stops the default action) as it's not included in the jQuery event.
See the definition of preventDefault in jQuery 3.1.1:
jQuery.Event.prototype = {
// ...
preventDefault: function() {
var e = this.originalEvent;
this.isDefaultPrevented = returnTrue;
if ( e && !this.isSimulated ) {
e.preventDefault();
}
},
// ...
};
So basically it will just call native preventDefault. If you are using jQuery I would use its method, it will also update isDefaultPrevented which might be useful if you want to check it (but you could also use native .originalEvent.defaultPrevented).
If you don't care about isDefaultPrevented and know the event has not been simulated by jQuery, then calling native preventDefault might be few milliseconds faster. That's the only potential advantage I can think of, but this definitely won't be a bottleneck.
Returning false in a jQuery event listener is like using both preventDefault and stopPropagation.
I use to know if the event was actually triggered by a physical mouse click. This is useful for avoiding the use of captchas on submit forms.
Here is the thing.
I'm need to open a new tab and draw something on the new opened tab.
I add event listener like that:
div3.addEventListerner("onmousedown",MouseDown(NewWindow.event),false);
But the firefox throw errors about the code in the MouseDown() function when the page is loading. The error is not throwed when I move the mouse.
function MouseDown(event)
{
if(!event)
{
var event = window.event;
}
X = event.pageX;//Throw error here.
Y = event.pageY;
So, there is anyone who knows how to fix this Problem?????
Remove the var from var event = window.event. The variable is already declared (as an argument), so re-declaring it with var can only lead to problems.
To be specific, due to hoisting, here is what your code boils down to:
function MouseDown(event) {
var event; // = undefined
if( !event) { // always true
event = window.event; // undefined in modern browsers
}
X = event.pageX; // ERROR!
}
Without the var, all is well!
When you're using addEventListener(), Event object is passed automatically in all browsers supporting the said method. However, you're calling your eventhandler immediately in argument. Instead you should pass a reference:
div3.addEventListener("mousedown", MouseDown, false);
Notice also "mousedown" without on. In the handlerfunction, event always exists, no need to check it for older IEs, since they don't support addEventListener.
I am writing an event dispatcher in JavaScript and I've decided to base on standard js CustomEvent class. I can't find out how to detect if event propagation was stopped in the listener (via e.stopPropagation()). Should I rather write an Event object implementation myself?
You have two possible solutions:
The first solution
The Event.cancelBubble property is a historical alias to Event.stopPropagation(). But it has the difference to the function Event.stopPropagation() because Event.cancelBubble we could read like follows:
var isPropagationStopped = event.cancelBubble; // true if it was stopped, or false if not
The next solution
You could override the stopPropagation method on the base Event object and set your own flag in the overridden method like follows:
var isPropagationStopped = false;
var stopPropagationFuncTemp = Event.prototype.stopPropagation;
Event.prototype.stopPropagation = function()
{
isPropagationStopped = true;
stopPropagationFuncTemp.apply(this, arguments);
};
Now if isPropagationStopped == true then it is stopped.
As far as I can tell, there is no way but to spy on the Event.prototype.stopPropagation function.
The CustomEvent will have a boolean property defaultPrevented if the attribute cancelable was set to true and the event's preventDefault() method was used.
var evt = new CustomEvent("custom", {cancelable : true});
console.log(evt.defaultPrevented);
evt.preventDefault();
console.log(evt.defaultPrevented);
Browser Support: Chrome 18, IE 9, Edge, Opera 11, Safari 5.
Just as an idea: why not overwriting the stopPropagation function like this?
const nativeStopPropagation = Event.prototype.stopPropagation;
Event.prototype.stopPropagation = function() {
console.log('stopPropagation called');
nativeStopPropagation.call(this);
};
Where the "console.log('Propagation stopped');" is, you can basically put any callback function.
Also works for preventDefault() the exactly same way.
Soluton found here: Is there a way to overwrite event objects and do what I prefer instead?
Best regards
Christian
Have you tried ?
e.isPropagationStopped()
Or
event.isPropagationStopped()
Just as the title says I'm curious if I'm guaranteed to get an event object inside of a Javscript event handler. The main reason I'm asking is that I've seen onClick event handlers that look like this.
function(e) {
if(e && e.target) {
//Code in here
}
}
Which seems wrong to me, but I know Javascript can have minor variances across browsers. Is there some time at which it's appropriate to check for the event object? Or the event target? It seems like you'd have to have a target to fire off an event.
No. Older versions of windows don't pass the event argument to the event handler. They have it in a global variable window.eventand the target is in .srcElement. Other than that exception, you should always get an event structure.
A work-around for the older versions of IE is this:
function(e) {
if (!e) {
e = window.event;
e.target = e.srcElement;
}
// code that uses e here
}
But, usually, this is addressed at a higher level by the function that you use to install event handlers. For example:
// add event cross browser
function addEvent(elem, event, fn) {
if (elem.addEventListener) {
elem.addEventListener(event, fn, false);
} else {
elem.attachEvent("on" + event, function() {
// set the this pointer same as addEventListener when fn is called
window.event.target = window.event.srcElement;
return(fn.call(elem, window.event));
});
}
}
Depending on the browser compatibility they are looking to achieve, this may be an acceptable solution. However, for older version of IE, the event object is a part of the global window object. In order to get the target in that case you would want window.event.srcElement, as there is no target.
More info here on the event object for IE.