質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Internet Explorer

Internet Explorer(IE;MSIE)はマイクロソフトが開発したウェブブラウザです。Microsoft Windowsに組み込まれています。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Q&A

1回答

2541閲覧

ChildNode#remove の存在判定コードを書くには?

think49

総合スコア18162

Internet Explorer

Internet Explorer(IE;MSIE)はマイクロソフトが開発したウェブブラウザです。Microsoft Windowsに組み込まれています。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

0グッド

0クリップ

投稿2016/04/11 02:07

ChildNode#remove の Polyfill 作成経緯

ChildNode#remove は親ノードを指定不要なので便利ですが、IE11- で Polyfill を適用しないと使えないという欠点があります。
そこで Polyfill を書くことを試みました。
定義する場所としては ChildNode.prototype.remove を指定するのが妥当と思われますが、未対応の IE11- が ChildNode の DOM Interface Object を持っているわけがありません。
そこで Element.prototype.remove を定義する事にしました。

JavaScript

1Element.prototype.remove = function remove () { 2 if (this.parentNode) { 3 this.parentNode.removeChild(this); 4 } 5};

次に Google Chrome 49.0.2623.112 m, Firefox 45.0.1 で ChildNode#remove が定義されている場所を確認したところ、次の結果になりました。

JavaScript

1Element.prototype.remove; // function remove () 2Object.getOwnPropertyDescriptor(Element.prototype, 'remove'); // {writable: true, enumerable: true, configurable: true} 3document.createElement('p').remove === Element.prototype.remove; // true 4ChildNode; // ReferenceError: ChildNode is not defined

ChildNode は存在せず、Element.prototype.remove が定義されているようです。
今後も Element.prototype.remove に存在するか不明なので 'remove' in document.createElement('p') で存在判定する事にしました。

JavaScript

1if (typeof Element === 'function' && !('remove' in document.createElement('p'))) { // IE11- 用の Polyfill 2 Element.prototype.remove = function remove () { 3 if (this.parentNode) { 4 this.parentNode.removeChild(this); 5 } 6 }; 7}

ChildNode#remove の定義場所はどこが正しい?

MDNにある Polyfill コードでは Element.prototype.remove が定義されています。

DOM Standard の仕様書側では Interface ChildNode で定義されており、Element との関連性がわかりませんでした。

実際のところ、ChildNode#remove はどこに定義するのが正しいのでしょうか。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

Element - Web APIs | MDN
では

Methods

Inherits methods from its parents Node, and its own parent, EventTarget, and implements those of ParentNode, ChildNode, NonDocumentTypeChildNode, and Animatable.

とあるので、本来ならChildNode interfaceで定義すべきでしょう。
が、あくまでinterfaceであるため、実装はElementで行うのが無難なんじゃないでしょうか?

投稿2016/04/11 02:46

tkturbo

総合スコア5572

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

think49

2016/04/11 03:44 編集

> 本来ならChildNode interfaceで定義すべきでしょう。 その説明ですと、ChildNode.prototype.remove に定義するように実装が変更される可能性を示しているように読めます。 > が、あくまでinterfaceであるため、実装はElementで行うのが無難 Element も Interface だと思いますが、なぜ Element が無難なのでしょうか。 また、出来れば、仕様に即した説明が欲しいです。MDN も悪くはありませんが、仕様書を読むとその説明は少し違うのではないかと感じる説明がしばしば見られます。
tkturbo

2016/04/11 03:56

MDNのChildNodeの説明文に「ChildNode is a raw interface and no object of this type can be created; it is implemented by Element, DocumentType, and CharacterData objects.」というのが出てます。 Element#remove()、DocumentType#remove()、CharacterData#remove()でそれぞれ挙動が変わるので、Element#remove()で実装するということなのではないでしょうか?
think49

2016/04/11 15:23

> ChildNode is a raw interface and no object of this type can be created; it is implemented by Element, DocumentType, and CharacterData objects. 私は下記のように翻訳しました。 「ChildNode は raw interface (生の interface) であり、このタイプのオブジェクト(ChildNode)は作成出来ません。これ(ChildNode)は Element, DocumentType, CharacterData オブジェクトによって実装されます。」 MDN は Mozilla が運営するサイトであり、Firefox の実装にそった説明であると理解しています。 Firefox については上記の実装になっているのでしょう。 しかし、Google Chrome, Safari, IE ...etc (Firefox 以外のブラウザ) が MDN の規定に従う理由はありません。 というわけで WHATWG の DOM Living Standard の規定に該当規定がないか探しているのですが、見つかっておりません。 改めて読むと NoInterfaceObject とあるので ChildNode が DOM Interface Object を持たない実装で正しいのではないかという考えを持ち始めましたが、明確に書かれた規定が見つかりませんでした。 https://dom.spec.whatwg.org/#interface-childnode > Element#remove()、DocumentType#remove()、CharacterData#remove()でそれぞれ挙動が変わるので、Element#remove()で実装するということなのではないでしょうか? 私の理解では挙動が変わるという記述は見受けられませんでしたが、どのような理屈でその結論に至ったのでしょうか。 WHATWG の規定では Interface に応じて挙動を変更する規定はありませんでした。 https://dom.spec.whatwg.org/#dom-childnode-remove The remove() method, when invoked, must run these steps: (remove() メソッドが呼び出された場合、次の手順を実行しなければなりません:) 1. If context object’s parent is null, terminate these steps. (コンテキストオブジェクトの親ノードが null ならば、強制終了する) 2. Remove the context object from context object’s parent. (コンテキストオブジェクトを親ノードから削除する)
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問