覆盖事件属性 [英] Override event properties

查看:39
本文介绍了覆盖事件属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何覆盖事件属性?我这样做的原因是因为我想在鼠标事件上覆盖像 pageX 这样的属性,并且该属性是只读的.

How can I override event properties? The reason I'm doing this is because I want to override properties like pageX on mouse event and that property is read-only.

我第一次尝试这个

context.addEventListener(type, function (e) {
    var Event;

    Event = function () {

        this.pageX = pageX;
        this.pageY = pageY;

        this.preventDefault = function () {
            e.preventDefault();
        };

        this.stopPropagation = function () {
            e.stopPropagation();
        };

        this.stopImmediatePropagation = function () {
            e.stopImmediatePropagation();
        };
    };

    Event.prototype = e;

    callback.call(context, new Event());
}, false);

不幸的是,它好得令人难以置信.它不适用于某些浏览器(至少是 Chrome).无法设置属性 pageX,因为只读状态是以某种方式从事件对象继承的.

Unfortunately, it's too good to be true. It's not working on some browsers (Chrome at least). Property pageX cannot be set because read-only state is somehow inherited from event object.

然后我尝试了

context.addEventListener(type, function (e) {
    var evt = {},
        i;

    for (i in e) {
        if (e.hasOwnProperty(i)) {
            evt[i] = e[i];
        }
    }

    evt.pageX = pageX;
    evt.pageY = pageY;

    evt.preventDefault = function () {
        e.preventDefault();
    };

    evt.stopPropagation = function () {
        e.stopPropagation();
    };

    evt.stopImmediatePropagation = function () {
        e.stopImmediatePropagation();
    };

    callback.call(context, evt);
}, false);

此方法有效,但比第一种方法慢约 100 倍.我真的不想走这条路,否则每次使用都会感觉很糟糕.

This one works, but is about 100 times slower than first method. I really would not want to go this way or I will feel bad every time I use it.

我考虑过放弃.我可以将像 pointX 这样的属性添加到原始事件并在那里添加 pageX 的值.再说一次,如果某些浏览器决定添加属性 pointX 并将其设为只读,我的所有代码都会被破坏.

I considered about giving up. I could just add property like pointX to original event and add value of pageX there. Then again, if some browser decides to add property pointX and make it read-only, all my code will be broken.

欢迎提供任何建议.

更新:现在它可以工作了,感谢 Esailija!我在下面添加解决方案.

Update: Now it works thanks to Esailija! I add solution here below.

document.body.addEventListener('mousedown', function (e) {
    var Event = function () {};

    Event.prototype = e;

    Event = new Event();

    Object.defineProperty(Event, 'pageX', {
        value: 999
    });

    console.log(Event);

}, false);

推荐答案

无法设置属性 pageX,因为只读状态是以某种方式从事件对象继承的.

Property pageX cannot be set because read-only state is somehow inherited from event object.

您可以使用 Object.defineProperty.

You can overrule that assignment behavior by using Object.defineProperty.

而不是自定义,只使用一次构造函数,你应该去Object.create.它甚至还有第二个参数,类似于 defineProperties,因此您可以将代码缩短为

And instead of the custom, only once used constructor you should go for Object.create. It even has a second argument that works like defineProperties, so you can shorten your code to

context.addEventListener(type, function (e) {
    callback.call(context, Object.create(e, {
        pageX: {value: pageX /* configurable, enumerable, writable? */},
        pageY: {value: pageY /* configurable, enumerable, writable? */}
    }));
    // I'd guess you don't even need the explicit "super" calls
    // for preventDefault, stopPropagation and stopImmediatePropagation
}, false);

这篇关于覆盖事件属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆