4340


event.target には click などのイベント発生時にイベント発生元のDOM要素がセットされていると思いますが、jQuery の ajax()
を非同期で実行した場合は XMLHttpRequest オブジェクトが入っていました。

変数の値がDOM要素の場合だけ特定の処理を行いたいです。

event.target に限らず、変数・プロパティに設定されている値がDOM要素かどうかはどのようにしたら判定できるでしょうか？

ちなみに、`typeof(event.target)` はclickイベントの時も、ajax()の時も`object` でした。


CC BY-SA 3.0
2015-01-09T15:14:12.603
4339
2015-01-09T16:22:39.637
3925
question
javascript jquery html ajax dom
変数がDOM要素かどうかを判定する方法


同じ質問が本家にありますね。  
大分古いですが。

[Javascript isDOM — How do you check if a Javascript Object is a DOM
Object?](https://stackoverflow.com/a/384380/2513010)

完全な回答はリンク先を参照していただくとして（回答そのものはそんなに長くありません）、前半だけ引用します

[code]

    function isElement(obj) {
      try {
        //Using W3 DOM2 (works for FF, Opera and Chrom)
        return obj instanceof HTMLElement;
      }
      catch(e){
        //Browsers not supporting W3 DOM2 don't have HTMLElement and
        //an exception is thrown and we end up here. Testing some
        //properties that all elements have. (works on IE7)
        return (typeof obj==="object") &&
          (obj.nodeType===1) && (typeof obj.style === "object") &&
          (typeof obj.ownerDocument ==="object");
      }
    }
    
[/code]

`obj instanceof HTMLElement` で確認できる場合はそれを利用し、  
そうでない場合は、

  * そのオブジェクトのデータ型が "object"
  * nodeTypeが 1 (`ELEMENT_NODE`)
  * styleプロパティのデータ型が "object "
  * ownerDocumentプロパティのデータ型が "object"

以上すべてを満たせば、関係性からHTMLElementでしょうと判断しています。

別の回答でフレームワークの機能を使って確認するというのもあるようです。

ただ気を付けて欲しいのが、たとえばjQueryなどフレームワークがラップしているオブジェクトは条件にあてはめられるとは限りません(多くの場合当てはまりません)。

たとえばChromeで、

[code]

    <div id="hoge"></div>
    
[/code]

があったとして

[code]

    var x = document.getElementById("hoge");
    if(x instanceof HTMLElement) Console.log("true");
    if(typeof x.style === "object") Console.log("true");
    
[/code]

どちらもtrueと出力されますが、

[code]

    var jqx = $("#hoge");
    if (jqx instanceof HTMLElement) Console.log("true");
    if (typeof jqx.style === "object") Console.log("true");
    
[/code]

はどちらも出力されません。  
以下ならtrueと出力されます。

[code]

    if (jqx[0] instanceof HTMLElement) Console.log("true");
    if (typeof jqx[0].style === "object") Console.log("true");
    
[/code]

`DOM要素`という言葉でどの範囲を想像しているかわかりませんが、フレームワークを使っている場合は気を付けてください。


CC BY-SA 3.0
2015-01-09T15:39:21.290
4340
2015-01-09T15:39:21.290
2017-05-23T12:38:55.307
-1
728
4339
answer


**Angular.js** に
[`isElement`](https://docs.angularjs.org/api/ng/function/angular.isElement)
があったなと思ったので、そっちの[ソース](https://github.com/angular/angular.js/blob/e9bf93d510a6a0c105d8f5d036ec35c7ce08a588/src/Angular.js)を追ってみました。

[code]

    function isElement(node) {
      return !!(node &&
        (node.nodeName  // we are a direct element
        || (node.prop && node.attr && node.find)));  // we have an on and find method part of jQuery API
    }
    
[/code]

  * Element であるか → [nodeName](https://developer.mozilla.org/en/docs/Web/API/Node.nodeName) を持つか
  * jQuery でラップされた要素であるか → [prop/attr/find](http://api.jquery.com/category/manipulation/general-attributes/) を持つか

ぐらいしか見ていないですね。これで十分なのでしょう。（ただ `{nodeName:"monkey"}` で騙せそう・・・）

一方、 **jQuery** の方は [`Node.nodeType`](https://developer.mozilla.org/en-
US/docs/Web/API/Node.nodeType) を見ているだけのようでした。まとめると、こんな感じ:

[code]

    function isNodeQ(obj) { // jQuery 式
        return obj && obj.nodeType && obj.nodeType === 1;
    }
    
    function isNodeA(obj) { // Angular 式
        return obj && obj.nodeName;
    }
    
[/code]

一方、StackOverflow 英語版には多く質問がありました。様々なのでどれとっていいかわかりませんねこれ。  
あえてピックアップすると、

  * [Javascript isDOM — How do you check if a Javascript Object is a DOM Object?](https://stackoverflow.com/questions/384286/javascript-isdom-how-do-you-check-if-a-javascript-object-is-a-dom-object)

この質問の [mcmlxxxiii からの回答](https://stackoverflow.com/a/384380/1372495)にあるコード
`isNode`, `isElement` がなかなか興味深いパラノイドなチェックをしています。ブラウザが最新の物であれば、 `Node` と
`HTMLElement`
のインスタンスであるかのチェックが有効なんですね。まあ実際は、プロパティを１つ２つ存在チェックすれば、考えなくても良いぐらいのことだと。


CC BY-SA 3.0
2015-01-09T16:09:50.260
4344
2015-01-09T16:22:39.637
2017-05-23T12:38:55.250
-1
4978
4339
answer