克隆javascript事件对象

时间:2012-09-24 22:10:09

标签: javascript

有人知道如何对本机javascript事件对象进行深层复制/克隆吗?我知道我可以创建一个新的事件对象并手动设置适当的属性以匹配原始事件,但如果有一种方法可以克隆它会更容易。

4 个答案:

答案 0 :(得分:10)

出于您的目的,我只是将它作为新对象构造函数的原型并覆盖您想要更改的对象。由于循环引用问题,JS中的克隆变得混乱,因此它可能不是您希望的快速和肮脏的解决方案。

function cloneEventObj(eventObj, overrideObj){

   if(!overrideObj){ overrideObj = {}; }

   function EventCloneFactory(overProps){
       for(var x in overProps){
           this[x] = overProps[x];
       }
    }

    EventCloneFactory.prototype = eventObj;

    return new EventCloneFactory(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
...*/

在这种情况下,“克隆”对象是新对象的原型对象。 '这个。'在原型对象之前检查属性,以便这些属性将覆盖。或者您可以在构建对象后附加属性。

答案 1 :(得分:9)

以上代码不会正确复制任何getter / setter。尝试:

function cloneEvent(e) {
    if (e===undefined || e===null) return undefined;
    function ClonedEvent() {};  
    let clone=new ClonedEvent();
    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;
}

答案 2 :(得分:1)

选项1:通过修改创建新事件

您可以使用proxies进行function EventModifier (evt, obj) { const proxy = new Proxy(evt, { get: (target, prop) => obj[prop] || target[prop] }) return new evt.constructor(evt.type, proxy) } onclick = evt => { evt = new EventModifier(evt, { altKey: true }) // Dispatch the new event on something else console.log('clicked with alt key:', evt.altKey) // always true }的操作,并在不修改原始事件的情况下构造一个新事件

示例:

Object.defineProperty

这样,您将使用与原始事件相同的选项,包括气泡,可取消,键修饰符等(它不包含任何目标,因为您打算将修改后的事件分派到其他事件上)

选项2:定义新属性

保留原始事件,但使用onclick = evt => { Object.defineProperty(evt, 'target', { value: document.querySelector('script') }) console.log('target:', evt.target) }覆盖键,如果要添加多个事件,则可以使用defineProperties。

{{1}}

答案 3 :(得分:0)

受Kofifus的启发回答我就这么做了

function cloneEvent(type, event) {
    var evt = new Event(type);
    return Object.setPrototypeOf(evt,event);
}