如何确定 Javascript 对象是不是为事件?

Posted

技术标签:

【中文标题】如何确定 Javascript 对象是不是为事件?【英文标题】:How to determine if Javascript object is an event?如何确定 Javascript 对象是否为事件? 【发布时间】:2010-11-30 08:12:47 【问题描述】:

确定 javascript 对象是否为事件的最安全方法是什么?

【问题讨论】:

@Tim Down:因为我需要区分随机 JS 对象、html 元素和作为参数发送给我的函数的事件。 【参考方案1】:

探查可能的“未知”对象以获取您希望找到的属性和方法是一种相当好的做法。

因此,假设您拥有一个事件对象,并在对其进行操作之前对其进行探测,例如

if (event.target)

   //looks like we're an event, hide the target
   var e=$(event.target);
   e.hide();

请务必注意,我并不是建议您测试“目标”以查看它是否是一个事件:您正在测试目标,因为您将要使用该属性。我的目标是,与其试图弄清楚一个对象是否是事件,不如探测该对象以查看它是否会按照您期望的方式运行,然后使用这些行为。

这样的代码应该在具有不同支持的浏览器上正常降级,或者让您利用特定于浏览器的扩展,例如

if (event.initKeyEvent)

    //gecko 1.9+
    event.initKeyEvent(...)

【讨论】:

同样,事件示例在 IE 中不起作用,IE 具有 srcElement 属性而不是 target。 您误会了 - 您不是在测试“目标”以查看它是否是一个事件,而是在测试目标 因为您将要使用该属性。我所追求的是,​​与其试图弄清楚一个对象是否是事件,不如探测该对象以查看它是否会以您期望的方式表现,然后使用这些行为。 很公平。我不认为它真的回答了最初的问题,但是我不明白为什么你需要测试一个对象是否是一个事件。 现在有一个有趣的想法...我只需要 Event 对象的三个属性(如果它真的是一个对象),所以我将检查它是否具有所有三个并确保它们的类型是我需要的那些。如果用户白痴到给我发送一个具有可用值的假对象,那完全是她的错。谢谢! 我必须注意,我提出这个问题的原因正好相反,我想确保一个对象不是一个事件。仍然可以接受 Paul Dixon 的建议,只需检查对象是否符合您的预期。 if($(object).is('div')) 做事...。这将确保元素不是事件对象。【参考方案2】:

我不知道是否有可靠的方法来做到这一点,但我认为你最好的方法是鸭式打字。

无论如何,您可以根据情况检查给定对象是否具有您想要使用的预期属性,就像Paul 指出的那样。

【讨论】:

【参考方案3】:

这个 isEvent 函数检查未知对象的构造函数,将其转换为字符串,然后搜索已知事件类型:

function isEvent(o)
    //grab the constructor for the unknown object
    var c=o.constructor;
    //convert constructor to string
    var s=c.toString(); 
    /* declare IE RegExp pattern to match for 'object [Event]' */
    if(document.all)
        //set regExp pattern for IE
        var ptr=/\[object Event\]/;     
    else
        /* declare FIREFOX regExp pattern to match for 'object [*Event]' since it has
           several event types:
        UIEvent 
        KeyboardEvent
        MouseEvent
        FocusEvent
        WheelEvent
        CompositionEvent
        StorageEvent
        CustomEvent (Requires Gecko 6.0)
        MutationEvent

        Both Custom and Mutation events are not recognized prior to Gecko 6.0,
        so if you want to use these, adjust regExp accordingly */
        var ptr=/\[object (Keyboard|Mouse|Focus|Wheel|Composition|Storage)Event\]/; 
       
return ptr.test(s);  

【讨论】:

【参考方案4】:

我也有同样的担忧。于是我着手证明,离解也越来越近了。

function isEvent(a)
    var txt, es=false;
    txt = Object.prototype.toString.call(a).split('').reverse().join('');
    es = (txt.indexOf("]tnevE") == 0)? true: false; // Firefox, Opera, Safari, Chrome
    if(!es)
        txt = a.constructor.toString().split('').reverse().join('');
        es = (txt.indexOf("]tnevE") == 0)? true: false; // MSIE
    
    return es;

我在

中测试了这个功能 Ubuntu 11.64 上的 FF 和 Opera 12.0 Wine-Ubuntu 上的 Safari 5.0 WinXP 上的 G.Chrome 19 和 MSIE 8

我希望这会有所帮助。

【讨论】:

【参考方案5】:

老问题,但显然根据这个,event.type 是跨浏览器:

http://www.quirksmode.org/js/events_properties.html

RameshVel 在对他的回答进行编辑时添加了这一点,但投票率很低。

当然,最安全的方法是遵循公认答案的指导,但碰巧我想丢弃该对象,如果它是一个事件。

【讨论】:

【参考方案6】:

使用instanceof怎么样?只要事件对象是使用构造函数new Event()创建的,例如:

var e = new Event('click');
e instanceof Event; // true

如果是事件处理程序中的事件参数,虽然它的类型是对象,但它包含原生事件作为属性,所以可以使用它来代替:

function myEventHandler(e) 
   e.originalEvent instanceof Event; //true

这里需要注意的是,实际值可能会因浏览器而异,特别是当事件是触摸事件时,请参阅here 和其中的引用。对我来说不是问题。

【讨论】:

【参考方案7】:

您可以检查对象是否具有属性 originalEvent;

event.hasOwnProperty('originalEvent')

例如:

// var event
var
  isObject = typeof event  ==='object', // is the given argument an object
  isEvent  = isObject ? event.hasOwnProperty('originalEvent') : false; 
if(isEvent) 
  // var `event` is an event!
 else 
  // var event is NOT an event!

【讨论】:

originalEvent 是 jQuery 的东西,对吧?这是值得注意的。这种抽象是我以前喜欢 jQuery 的原因。

以上是关于如何确定 Javascript 对象是不是为事件?的主要内容,如果未能解决你的问题,请参考以下文章

Javascript - 无法确定 JSON 对象是不是包含 true

确定 UIWebView 是不是处理事件

JavaScript中如何判断一个对象是不是具有给定的属性

Javascript 触摸对象

# yyds干货盘点 # 一文解读JavaScript事件对象和表单对象

深入理解JavaScript的闭包特性 如何给循环中的对象添加事件