Cloning Javascript Event Object
Solution 1:
Above code will not copy any getters/setters properly. Try:
functioncloneEvent(e) {
if (e===undefined || e===null) returnundefined;
functionClonedEvent() {};
let clone=newClonedEvent();
for (let p in e) {
let d=Object.getOwnPropertyDescriptor(e, p);
if (d && (d.get || d.set)) Object.defineProperty(clone, p, d); else clone[p] = e[p];
}
Object.setPrototypeOf(clone, e);
return clone;
}
Solution 2:
For your purposes I'd just make it a prototype of a new object constructor and override the ones you want changed. Cloning in JS gets messy due to the circular reference issue so it may not be the quick and dirty solution you were hoping for.
functioncloneEventObj(eventObj, overrideObj){
if(!overrideObj){ overrideObj = {}; }
functionEventCloneFactory(overProps){
for(var x in overProps){
this[x] = overProps[x];
}
}
EventCloneFactory.prototype = eventObj;
returnnewEventCloneFactory(overrideObj);
}
//So add your override properties via an object
$el.click(function(e){
var newEventObj = cloneEventObj(
e,
{ target:document.body }
);
doSomething(newEventObj);
});
//or just stick 'em on manually after spitting the object out/*...
var newEventObj = cloneEventObj(e);
newEventObj.target = document.body
...*/
In this case the 'cloned' object is the prototype object of the new object. 'this.' properties are checked for before the prototype object so these will override. Or you could just attach properties after the object is built.
Solution 3:
Option 1: Making a new event with modification
You could make an Object.assign
-alike using proxies and construct a new event without modifying the original event
Example:
functionEventModifier (evt, obj) {
const proxy = newProxy(evt, {
get: (target, prop) => obj[prop] || target[prop]
})
returnnew evt.constructor(evt.type, proxy)
}
onclick = evt => {
evt = newEventModifier(evt, { altKey: true })
// Dispatch the new event on something elseconsole.log('clicked with alt key:', evt.altKey) // always true
}
This way you will use the same options as the original event that includes bubble, cancelable, key modifier, etc (doe it don't include any target as you are meant to dispatch the modified event on something else)
Option 2: Define new properties
Keeping the original event but override a key using Object.defineProperty
you could use defineProperties if you want to add more than just one.
onclick = evt => {
Object.defineProperty(evt, 'target', { value: document.querySelector('script') })
console.log('target:', evt.target)
}
Solution 4:
Inspired by Kofifus answer I just do that
functioncloneEvent(type, event) {
var evt = newEvent(type);
returnObject.setPrototypeOf(evt,event);
}
or just
function cloneEvent(event){
return Object.create(event)
}
it returns a new object that protects you from edit the original object. but let you read and edit the property. thanks to js prototype chain
Post a Comment for "Cloning Javascript Event Object"