js9 ドキュメント
問題一覧
1
1つ目は、これはJavaScriptコードのグローバルオブジェクトであり、グローバルオブジェクト の章で説明するとおりです。 2つ目は、これは “ブラウザウィンドウ” を表し、ウィンドウを制御するためのメソッドを提供します。 function sayHi() { alert("Hello"); } // グローバル関数は window のプロパティとしてアクセス可能 window.sayHi();
2
ドキュメントオブジェクトモデル、略して DOM は、ページ全体のコンテンツを変更可能なオブジェクトとして表現します。 document オブジェクトはページのメインの “エントリーポイント” です。これを使って、ページ上のものを変更したり作成することができます。 例: // 背景色を赤に変える document.body.style.background = 'red'; // 1秒後に戻す setTimeout(() => document.body.style.background = '', 1000);
3
ブラウザオブジェクトモデル(BOM)は document 以外のすべてと連携するブラウザ(ホスト環境)により提供される追加オブジェクトです。 画像のようなオブジェクトがBOM 関数 alert/confirm/prompt もまた BOM の一部です: それらは直接は document と関係はしませんが、ユーザとコミュニケーションをとる純粋なブラウザメソッドを表します。
4
ブラウザとオペレーティングシステムのバックグラウンドの情報を提供します。 多くのプロパティを持っていますが、最も広く知られている2つのプロパティはこれです: navigator.userAgent – 現在のブラウザについて, navigator.platform – プラットフォームについて(Windows/Linux/Macなどを分ける)
5
現在のURLを読み、ブラウザを新しいURLへリダイレクトできます。 これは、location オブジェクトを使う方法です: alert(location.href); // 現在のURLを表示 if (confirm("Go to wikipedia?")) { location.href = 'https://wikipedia.org'; // 別のURLへリダイレクト }
6
タグのツリー構造で、 スペースのテキストノードがちょいちょいはさまってる。 テキストノードは常に末端ノードである。 改行: ↵ (JavaScript では \n として知られています) スペース: ␣ スペースと改行は文字や数字と同様、完全に有効な文字です。これらはテキストノードを形成し、DOMの一部になります。従って、例えば、上の例では <head> タグは <title> の前にいくつかのスペースを含まれており、そのテキストは #text ノードになります(改行といくつかのスペースのみが含まれています)。
7
もしHTMLファイルが "Hello" という言葉のみだった場合、ブラウザはそれを <html> と <body> でラップし、必須の <head> を追加します。 Tableの自動補正は、 <table id="table"><tr><td>1</td></tr></table> である場合画像のように <tbody>が追加される。
8
document – DOM に入る “エントリーポイント” 要素ノード – HTMLタグ, ツリーのビルディングブロック テキストノード – テキストを含む コメント – 必要に応じて情報をおくことができ、これは表示されません。が JS はDOMからそれを読むことができます。
9
ツールの右側には、次のようなサブのタブがあります: Styles – 組み込みルール(灰色)を含めて、ルール別に現在の要素ルールにCSSが適用されていることがわかります。 ほとんどすべては、下のボックスの大きさ/マージン/パディングを含めて編集できます。 Computed – プロパティによって要素に適用されたCSSを表示する:各プロパティに対して、それを与える規則(CSSの継承などを含む)を見ることができます。 Event Listeners – DOM要素に関連付けられたイベントリスナーを表示します(チュートリアルの次の部分で説明します)。 …など
10
最後に選択した要素は $0 として利用可能で、以前に選択したものは $1 です。 コンソールでコマンドが実行できます。例えば、$0.style.background = 'red' は選択されているリストアイテムを赤にします、このように:
11
<body> = document.body <html> = document.documentElement <head> = document.head
12
Nodeクラスのメソッドで、 childNodes というのがある。 取得されるコレクションは、テキストノードを含むすべての子ノードを持ちます。 プロパティ firstChild と lastChild で最初と最後の子への高速なアクセスができます これらは単なる簡略表記です。子ノードが存在する場合は、常に次のようになります: elem.childNodes[0] === elem.firstChild elem.childNodes[elem.childNodes.length - 1] === elem.lastChild 子ノードがあるかどうかをチェックするための特別な関数 elem.hasChildNodes() もあります。
13
childNodes は配列のように見えます。 が、実際には配列ではなくむしろ コレクション – 特別な配列ライクで反復可能なオブジェクトです。 配列ではないため、配列メソッドは動作しません: alert(document.body.childNodes.filter); // undefined (フィルタメソッドを持っていません!) 最初の1つ目は良いです。2つ目も、配列メソッドが必要な場合は、Array.from でコレクションから “本当の” 配列を作ることができるので許容できます。: alert( Array.from(document.body.childNodes).filter ); // これで使えます
14
これもNodeクラスのメソッド 次のノード(次の兄弟) は nextSibling であり、前のノードは previousSibling です。 親は parentNode として利用可能です。 例えば: // <body> の親は <html> です。 alert( document.body.parentNode === document.documentElement ); // true // <head> の後は <body> に行きます。 alert( document.head.nextSibling ); // HTMLBodyElement // <body> の前は <head> です。 alert( document.body.previousSibling ); // HTMLHeadElement
15
Elementクラスのメソッドを利用する。 children – 要素ノードの子のみです。 firstElementChild, lastElementChild – 最初/最後の要素の子です。 previousElementSibling, nextElementSibling – 隣の要素です。 parentElement – 親の要素です。
16
HTML要素の親ノードはDocumentだが、親要素はnullとなる。 Document null
17
まあ色々あるっぽい。 使う時に調べれ場合と思う。 <table> 要素は次のプロパティをサポートします(上で与えられたものに加えて): table.rows – テーブルの <tr> 要素のコレクションです。 table.caption/tHead/tFoot – 要素 <caption>, <thead>, <tfoot> への参照です。 table.tBodies – <tbody> 要素のコレクション(標準によると多数になれます) です。 <thead>, <tfoot>, <tbody> 要素は rows プロパティを提供します: tbody.rows – 内側の <tr> のコレクション <tr>: tr.cells – 与えられた <tr> の中の <td> と <th> セルの集合です。 tr.sectionRowIndex – 囲んでいる <thead>/<tbody> の内部にある与えられた <tr> の番号です。 tr.rowIndex – テーブル内の <tr> の番号です。 <td> と <th>: td.cellIndex – <tr> で囲まれている内側でのセルの番号です。 使用例: <table id="table"> <tr> <td>one</td><td>two</td> </tr> <tr> <td>three</td><td>four</td> </tr> </table> <script> // "two" の td を取得 let td = table.rows[0].cells[1]; td.style.backgroundColor = "red"; // ハイライト </script>
18
document.getElementById(id) メソッド getElementById は document オブジェクトに対してのみ呼び出し可能です。これはドキュメント全体から指定された id を探します。 elem.querySelectorAll(css) 指定された CSS セレクターに一致する elem 内のすべての要素を返します 例 最後の子要素となるすべての <li> 要素を探します: let elements = document.querySelectorAll('ul > li:last-child'); elem.querySelector(css) もある。 ほかにも elem.getElementsByTagName(tag) elem.getElementsByClassName(className) document.getElementsByName(name) がある
19
要素に id 属性があると、document.getElementById(id) メソッドを使用することで要素が取得できます。 例: <div id="elem"> <div id="elem-content">Element</div> </div> <script> // 要素を取得 let elem = document.getElementById('elem'); // 背景を赤にします elem.style.background = 'red'; </script> また、要素を参照する id で名前付けされたグローバル変数もあります: <div id="elem"> <div id="elem-content">Element</div> </div> <script> // elem は id="elem" の DOM 要素を参照します elem.style.background = 'red'; // id="elem-content" はハイフンがあるので変数名にはできません。 // が、角括弧を使用してアクセスできます: window['elem-content'] </script> ただし、 要素にアクセスするのに、id名のグローバル変数は使わないでください この振る舞いは スペック で説明されているので、標準の1つです。が、主に互換性のためにサポートされています。 ブラウザは JS と DOM の名前空間を混在させることで助けようとします。シンプルなスクリプトであればよいですが、一般的には良いことではありません。名前が衝突する可能性があります。また、JS を見て、HTMLを見なかった場合、変数がどこから来たのかが明白ではありません。
20
疑似クラスも使えます :hover や :active のような CSS セレクタの擬似クラスもサポートされています。例えば、document.querySelectorAll(':hover') はポインタがある要素のコレクションを返します(ネスト順は、最も外側の <html> から最もネストされたものの順です)。
21
elem.matches(css) は単に elem が与えられた CSS セレクタに一致するかをチェックし、true または false を返します。 このメソッドは、要素(配列か何か)を反復処理し、興味のあるものをフィルタしようとするときに便利です。 例えば: <a href="http://example.com/file.zip">...</a> <a href="http://ya.ru">...</a> <script> // document.body.children の代わりに任意のコレクションが可能です for (let elem of document.body.children) { if (elem.matches('a[href$="zip"]')) { alert("The archive reference: " + elem.href ); } } </script>
22
メソッド elem.closest(css) は CSS セレクタにマッチする最も近い祖先を見ます。elem 自身も検索対象に含まれています。 つまり、メソッド closest は要素(elem)から上に進み、親をチェックしていきます。セレクタにマッチしたら、検索を止めその祖先を返却します。 例: <h1>Contents</h1> <div class="contents"> <ul class="book"> <li class="chapter">Chapter 1</li> <li class="chapter">Chapter 1</li> </ul> </div> <script> let chapter = document.querySelector('.chapter'); // LI alert(chapter.closest('.book')); // UL alert(chapter.closest('.contents')); // DIV alert(chapter.closest('h1')); // null (h1 は祖先ではないので) </script>
23
すべての "getElementsBy*" メソッドは ライブ(動的)な コレクションを返します。このようなコレクションは常にドキュメントの現在の状態を反映し、変更があったとき “自動更新” されます。 <div>First div</div> <script> let divs = document.getElementsByTagName('div'); alert(divs.length); // 1 </script> <div>Second div</div> <script> alert(divs.length); // 2 </script> <div>First div</div> querySelectorAll は 静的な コレクションです。これは配列の要素の数が固定されたコレクションということ。→後から増えたり減ったりしない。 <script> let divs = document.querySelectorAll('div'); alert(divs.length); // 1 </script> <div>Second div</div> <script> alert(divs.length); // 1 </script>
24
親子関係を調べるメソッド elemA.contains(elemB) は elemB が elemA の中にある(elemA の子孫)または elemA==elemB の場合 true を返します。
25
階層のルートは EventTarget で、これは Node により継承されています。また他の DOM ノードはそれを継承しています 図のとおり
26
EventTarget – はルートの “抽象” クラスです。 このクラスのオブジェクトは生成されません。これはベースとして機能し、すべての DOM ノードはいわゆる “イベント” をサポートします。
27
Node – もまた “抽象” クラスで、DOM ノードの基底として機能します。 これはコアなツリー機能を提供します。: parentNode, nextSibling, childNodes など(これらは getter です)。 Node クラスのオブジェクトは決して生成されません。 しかし、それを継承した具体的なノードクラス、即ち: テキストノードの Text, 要素ノードの Element や、コメントノードのための Comment などもあります。
28
Element – は DOM 要素のベースクラスです。 nextElementSibling, children や getElementsByTagName, querySelector 等の検索メソッドといった、要素レベルのナビゲーションを提供します。 ブラウザでは、HTML だけでなく、XML や SVG のドキュメントがある場合もあります。 Element クラスは SVGElement、XMLElement、HTMLElement といったより具体的なクラスのベースとして機能します。
29
HTMLElement – は最終的にすべてのHTML要素のベースクラスです。 色々な HTML要素 がこれを継承しています。: HTMLInputElement – <input> 要素のためのクラス, HTMLBodyElement – <body> 要素のためのクラス, HTMLAnchorElement – <a> 要素のためのクラス …など、各タグは固有のプロパティやメソッドを提供する独自のクラスを持っています。
30
DOM ノードのクラス名を見るに、オブジェクトは通常 constructor プロパティを持っていることを思い出してください。 これはクラスコンストラクタを参照し、 constructor.name はその名前です: alert( document.body.constructor.name ); // HTMLBodyElement …もしくはその toString: alert( document.body ); // [object HTMLBodyElement] また、継承チェックに instanceof を使うこともできます: alert( document.body instanceof HTMLBodyElement ); // true alert( document.body instanceof HTMLElement ); // true alert( document.body instanceof Element ); // true alert( document.body instanceof Node ); // true alert( document.body instanceof EventTarget ); // true
31
ほとんどのブラウザは、開発者ツールで2つのコマンドをサポートしています。 console.log と console.dir です。 それらは引数をコンソールに出力します。JavaScript オブジェクトに対しては通常同じ動作をします。 しかし、DOM 要素に対しては異なります。: console.log(elem) は要素の DOM ツリーを表示します console.dir(elem) は DOM オブジェクトとして要素を表示します。 プロパティを調べるのには良いです。
32
elem.nodeType == 1 は要素ノード, elem.nodeType == 3 はテキストノード, elem.nodeType == 9 はドキュメントオブジェクト
33
nodeName または tagName プロパティでそのタグの名前を見ることができます。: 例: alert( document.body.nodeName ); // BODY alert( document.body.tagName ); // BODY tagName プロパティは Element ノードに対してのみ存在します。テキストノードとかにはない <body><!-- comment --> <script> // for comment alert( document.body.firstChild.tagName ); // undefined (not element) alert( document.body.firstChild.nodeName ); // #comment // for document alert( document.tagName ); // undefined (not element) alert( document.nodeName ); // #document </script> </body>
34
innerHTMLプロパティは要素内の HTML を文字列として取得することができます。 Elementクラスのもちもの。 また、それを変更することもできます。なので、ページを変更する最も強力な方法の1つです。 この例は document.body のコンテンツを表示し、その後、コンテンツを完全に置き換えます: <body> <p>A paragraph</p> <div>A div</div> <script> alert( document.body.innerHTML ); // 現在の内容を読む document.body.innerHTML = 'The new BODY!'; // 置き換える </script> </body> 無効な HTML を挿入しようとすると、ブラウザはエラーを修正します。: <body> <script> document.body.innerHTML = '<b>test'; // タグのクローズ忘れ alert( document.body.innerHTML ); // <b>test</b> (修正された) </script> </body> ちなみに スクリプトは実行しません もし innerHTML が <script> タグをドキュメントに挿入した場合、-- HMLT の一部にはなりますが、実行されません。
35
既存のコンテンツが “完全に取り除かれ 、最初から書き直される。 すべての画像やその他のリソースはロードされます。 これは elem.innerHTML+="何か" によって追加された場合でも同様!
36
outerHTML プロパティは要素の完全な HTML を含みます。それは innerHTML に要素自身を加えたようなものです。 例: <div id="elem">Hello <b>World</b></div> <script> alert(elem.outerHTML); // <div id="elem">Hello <b>World</b></div> </script> 注意: innerHTML とは違い、outerHTML への書き込みは可能で、画面的に適用されるが、書き込んだ要素をもう一度参照しても適用されてないように見えるらしい まあ複雑なので、あんまやらんこと
37
nodeValue と data プロパティです。 これら2つは実際の利用においてはほとんど同じで、仕様上少し違いがあるだけです。なので、より短い data を使います。 <body> Hello <!-- Comment --> <script> let text = document.body.firstChild; alert(text.data); // Hello let comment = text.nextSibling; alert(comment.data); // Comment </script> </body>
38
Nodeクラスのもちもので、 要素内の テキスト へのアクセスを提供します: テキストだけで、すべての <tags> を除きます。 textContent への書き込みはとても役立ちます。なぜならテキストを “安全な方法” で書くことができるからです。 例えばユーザによって入力された任意の文字列を表示したいとしましょう。 innerHTML を使うと、すべての HTML タグと一緒に、“HTML として” 挿入されます。 textContent では、すべてのシンボルは文字通り扱われ、“テキスト として” 挿入されます。
39
HTMLElementクラスのhiddenプロパティを利用する <div>Both divs below are hidden</div> <div hidden>With the attribute "hidden"</div> <div id="elem">JavaScript assigned the property "hidden"</div> <script> elem.hidden = true; </script> 技術的には、hidden は style="display:none" と同じ動きです。しかしより短く書けます。
40
value – <input>, <select> や <textarea> (HTMLInputElement, HTMLSelectElement…) のための値。 href – <a href="..."> (HTMLAnchorElement) の href. console.dir(elem) で要素を出力しプロパティを確認することができます。 もしくはブラウザ開発者ツールの Elements タブで “DOM プロパティ” を参照してください。
41
BODY <body> の内容はコメントに置き換えられます。body.tagName == "BODY" なので、コメントは <!–BODY–> です。覚えているように、tagName は HTML では常に大文字です。 コメントは今唯一の子ノードなので、body.firstChild でそれを取得します。 コメントの data プロパティはその内容(<!--...--> の中): "BODY" です。
42
DOM ノードは通常のJavaScriptオブジェクトです。それを変更できます。 例えば、document.body に新しいプロパティを作成してみましょう: document.body.myData = { name: 'Caesar', title: 'Imperator' }; alert(document.body.myData.title); // Imperator 同様にメソッドの追加もできます: document.body.sayHi = function() { alert(this.tagName); }; document.body.sayHi(); // BODY (このメソッドの "this" の値は document.body)
43
直接参照できないので、undefinedとなる。 従って、要素が id または他の 標準の 属性を持っている場合、対応するプロパティが生成されます。しかし、属性が非標準の場合はプロパティは生成されません。
44
すべての属性は次のメソッドでアクセス可能です。: elem.hasAttribute(name) – 存在をチェックします。 elem.getAttribute(name) – 値を取得します。 elem.setAttribute(name, value) – 値を設定します。 elem.removeAttribute(name) – 属性を削除します。 <body something="non-standard"> <script> alert(document.body.getAttribute('something')); // non-standard </script> </body>
45
設定したものを含む全属性は outerHTML で確認できます。 attributes のコレクションは反復可能で、属性は name と value を持っています。 alert( elem.outerHTML ); // (3), 参照 for (let attr of elem.attributes) { // (4) すべてをリスト alert( attr.name + " = " + attr.value ); }
46
データは同期される なので ido newId しかし、プロパティによって例外もある!!
47
例えば、 input.value の同期は 属性から → プロパティの場合のみで、逆は同期されません: <input> <script> let input = document.querySelector('input'); // 属性 => プロパティ input.setAttribute('value', 'text'); alert(input.value); // text // ☓ プロパティ => 属性 input.value = 'newValue'; alert(input.getAttribute('value')); // text (更新されていません!) </script> 上の例では: 属性 value の変更は、プロパティも更新します。 しかし、プロパティの変更は属性に影響を与えません。 この “特徴” は実際には便利な場合があります。なぜなら、ユーザは value を変更する可能性があるからです。その後、HTMLから元の値を復元する場合、元の値は属性にあります。 つまり、プロパティ変更を行うことで、 元の値を属性に保持したままにできる
48
HTMLの書式で記述する場合は、大文字小文字は区別されません。 HTMLでは、要素名や属性名の大文字小文字は区別されません。 ちなみにjsのプロパティとかは大文字小文字区別する なので、プロパティアクセスする場合 下記のように大文字小文字で違うとアクセスできないので注意 <body id="test"> <script> alert(document.body.ID); // undefined </script> </body>
49
style 属性は文字列がもどるが、 style プロパティはオブジェクト、 CSSStyleDeclarationがもどる。 <div id="div" style="color:red;font-size:120%">Hello</div> <script> // string alert(div.getAttribute('style')); // color:red;font-size:120% // object alert(div.style); // [object CSSStyleDeclaration] alert(div.style.color); // red </script>
50
href DOM プロパティは、属性が相対URLや単なる #hash だとしても、常に 完全な URLです。 プロパティアクセスは完全なURLとなる! 以下はその例です: <a id="a" href="#hello">link</a> <script> // 属性 alert(a.getAttribute('href')); // #hello // プロパティ alert(a.href ); // 完全なURLの形式 http://site.com/page#hello </script>
51
HTML から JavaScript へカスタムデータを渡す、 もしくは JavaScript のためにHTML要素を “マークする” 目的として、非標準の属性が使われることがあります。 属性メソッドで値を取得して、 その値を利用して オブジェクトからデータを取得するみたいなことができる。 他にもカスタム属性でセレクタして、 CSSStyleルールをカスタム属性がついたものだけに適用することもできる。 以下のようにスタイルを設定できる .elem[custom-prop="new"] { color: green; } スタイルをあとで消したいなら以下のようにできる。 elem.setAttribute('custom-prop', 'canceled');
52
衝突を避けるために、data-* 属性があります。 "data-" で始まるすべての属性はプログラマのために予約されています。これらは dataset プロパティで利用可能です。 例えば、elem が "data-about" という名前の属性を持つ場合、elem.dataset.about でアクセスできます。 <body data-about="Elephants"> <script> alert(document.body.dataset.about); // Elephants </script> data-order-state のような複数語はキャメルケースになります: dataset.orderState.
53
ドキュメントクラスのメソッド。 要素をつくる let div = document.createElement('div'); テキストノードをつくる let textNode = document.createTextNode('Here I am');
54
ノードのメソッドを利用する node.append(...nodes or strings) – node の末尾にノードまたは文字列を追加します。 node.prepend(...nodes or strings) – node の先頭にノードまたは文字列を挿入します。 node.before(...nodes or strings) –- node の前にノードまたは文字列を追加します。 node.after(...nodes or strings) –- node の後にノードまたは文字列を追加します。 node.replaceWith(...nodes or strings) –- node を与えられたノードまたは文字列で置き換えます。 これらのメソッドの引数は挿入する任意の DOM ノードのリスト、あるいはテキスト文字列(自動的にテキストノードになります)です。 let div = document.createElement('div'); div.className = "alert alert-success"; div.innerHTML = "<strong>Hi there!</strong> You've read an important message."; document.body.appendChild(div);
55
<p>Hello</p>とhrタグを挿入しているが、 <p>Hello</p>はテキストとして挿入されるので以下のようになる <p>Hello</p> <hr> <div id="div"></div> elem.textContent が行うように、文字列は安全な方法で挿入されます。
56
elem.insertAdjacentHTML(where, html)。 最初のパラメータは文字列で、elem を基準にした挿入場所を指定します。次のいずれかでなければなりません: "beforebegin" – elem の直前に html を挿入します, "afterbegin" – elem の中の先頭に html を挿入します, "beforeend" – elem の中の末尾に html を挿入します, "afterend" – elem の直後に html を挿入します. 2つ目のパラメータは “そのまま” 挿入されるHTML文字列です。 例: <div id="div"></div> <script> div.insertAdjacentHTML('beforebegin', '<p>Hello</p>'); div.insertAdjacentHTML('afterend', '<p>Bye</p>'); </script> …は次のようになります: <p>Hello</p> <div id="div"></div> <p>Bye</p>
57
node.remove() 1秒後に削除する例 let div = document.createElement('div'); div.className = "alert"; div.innerHTML = "<strong>Hi there!</strong> You've read an important message."; document.body.append(div); setTimeout(() => div.remove(), 1000);
58
呼び出し elem.cloneNode(true) は、すべての属性とサブ要素を含む要素の “ディープ” クローンを作成します。 elem.cloneNode(false) を呼び出すと、子要素なしのクローンが作られます。 <style> .alert { padding: 15px; border: 1px solid #d6e9c6; border-radius: 4px; color: #3c763d; background-color: #dff0d8; } </style> <div class="alert" id="div"> <strong>Hi there!</strong> You've read an important message. </div> <script> let div2 = div.cloneNode(true); // メッセージをクローンします div2.querySelector('strong').innerHTML = 'Bye there!'; // クローンを変更します div.after(div2); // 既存の div の後に div2 を表示 </script>
59
DocumentFragment はノードのリストを渡すためのラッパーとして使用できる。 特別な DOM ノードです ノードをまとめて管理できる。 DocumentFragment へ他のノードを追加することができます。 これを挿入する際は代わりにそのコンテンツが挿入されます。 DocumentFragment は明示的にはめったに使用されませんが以下のように使用できます。 let fragment = new DocumentFragment(); fragment.append(ノード); 追加先のノード.append(fragment); これを配列に書きなおすとこんなかんじ 追加先のノード.append(…ノードの配列);
60
親の要素をわざわざ指定する必要があるメソッドは現在あまり利用されないメソッド。 親は指定する必要なし parentElem.appendChild(node) parentElem の末尾の子供として node を追加します。 parentElem.replaceChild(node, oldChild) parentElem の子の中で oldChild を node に置き換えます。 parentElem.removeChild(node) parentElem から node を削除します(node がその子であると想定)。 parentElem.insertBefore(node, nextSibling) parentElem の中で nextSibling の前に node を挿入します。 全て、親の指定が必要のない append, prepend, before, after, remove, replaceWith のようなモダンなメソッドがあるのでそれを使う
61
<p>Somewhere in the page...</p> <script> document.write('<b>Hello from JS</b>'); </script> <p>The end</p> document.write(html) の呼び出しは html を “すぐにその場で” ページに書き込みます。 読み込みが完了する前にページにHTMLを追加するメソッド html 文字列を動的に生成することができるので柔軟性があります。 document.writeの呼び出しはページがロードされている間だけ動作します。 なので、setTimeoutとかで呼び出すと動かないらしい。 “ロード後” の段階でも利用できません。 これは DOMの修正がないため 驚くほど速く動作します。DOMがまだビルドされていない間、それは直接ページテキストに書き込み、ブラウザは生成時にそれをDOMを挿入します。 なので、HTMLの動的に多くのテキストを追加する必要があり、またページをロードするフェーズであること、速度を考慮する必要がある場合には役立ちます。ですが、実際にはこれらの要件が一緒に来ることは殆どありません。通常、このメソッドを見るときは、単に古いスクリプトだからと言う理由です。
62
正しいバリアントは次のようになります: firstChildで毎回消す必要がある。 function clear(elem) { while (elem.firstChild) { elem.firstChild.remove(); } } また、よりシンプルな方法として次のように書くこともできます: function clear(elem) { elem.innerHTML = ''; } ダメな例 function clear(elem) { for (let i=0; i < elem.childNodes.length; i++) { elem.childNodes[i].remove(); } } これは動作しません。なぜなら、remove() の呼び出しは集合 elem.childNodes をシフトするからです。 なので、要素は毎回インデックス 0 から開始します。しかし、 i は増加するので、いくつかの要素はスキップされるでしょう。
63
aaa だけのこる。 HTML がまちがっており、ブラウザの自動修正が働いている。 <table> タグの中は 仕様によると、テーブル固有のタグだけが許可されます。 したがって、ブラウザは <table> の 前に "aaa" を追加します。
64
再帰で実装する。 データの前提としては全てオブジェクトであり、プリミティブは関与しない function createTree(container, obj) { container.append(createTreeDom(obj)); } function createTreeDom(obj) { //このメソッドの終了条件は、キー情報のないオブジェクトであること。 if (!Object.keys(obj).length) return; // オブジェクトであればリストを作る let ul = document.createElement('ul'); for (let key in obj) { // リストアイテムを作り、キーをinnerHTMLに設定する let li = document.createElement('li'); li.innerHTML = key; // オブジェクトのvalueをターゲットに再帰の継続を行う その際、終了条件にひっかかっているならば、appendはしない let childrenUl = createTreeDom(obj[key]); if (childrenUl) { li.append(childrenUl); } ul.append(li); } return ul; } let container = document.getElementById('container'); createTree(container, data);
65
良問題なのでやれ
66
良問題やれ
67
どこかに HTML を部分を挿入する必要がある場合、insertAdjacentHTML がベストです。 解決策: one.insertAdjacentHTML('afterend', '<li>2</li><li>3</li>');
68
style プロパティは CSS カスケードなしで、その "style" 属性の値だけを操作します。 プロパティ elem.style は "style" 属性に書かれたものに対応するオブジェクトです。 elem.style.width="100px" の設定は、属性 style="width:100px" を持っているかのように機能します。 複数語のプロパティは、キャメルケースが使われます: background-color => elem.style.backgroundColor
69
classプロパティは、使えない(予約語によって) なのでclassNameプロパティを使う <body class="main page"> <script> alert(document.body.className); // main page </script> </body> classNameはクラス全体の文字列が設定される。 対して、 elem.classList はクラスを 追加/削除/トグル するためのメソッドを持つ特別なオブジェクトです。 例: <body class="main page"> <script> // クラスを追加します document.body.classList.add('article'); alert(document.body.className); // main page article </script> </body>
70
classList のメソッド: elem.classList.add/remove("class") – クラスの追加/削除をします。 elem.classList.toggle("class") – クラスが存在する場合は削除します。なければ追加します。 elem.classList.contains("class") – クラスをの有無をチェックし、 true/false を返します。 それに加え、classList は反復可能です
71
このための特別なメソッドもあります, elem.style.removeProperty('style property'). 次のようにしてプロパティの削除ができます。:
72
elem.style.cssTextで取得できる。 書き込みも可能! div.style.cssText=`color: red !important; background-color: yellow; width: 100px; text-align: center; `; alert(div.style.cssText); 属性を設定することで同じことができます。: div.setAttribute('style', 'color: red...').
73
getComputedStyle(element[, pseudo]) element 値を読み取る要素 pseudo 疑似要素(必要な場合に指定)。例えば ::before。 空文字列または引数なしは要素自身を意味します。 結果は、elem.style のようにスタイルプロパティを持つオブジェクトですが、ここではすべての CSS クラスに関してのものです。 返却値は、elem.style のようにスタイルプロパティを持つオブジェクトです CssStyleDecolationオブジェクト <head> <style> body { color: red; margin: 5px } </style> </head> <body> <script> let computedStyle = getComputedStyle(document.body); // 今やそこからマージンや色を読み取る事ができます alert( computedStyle.marginTop ); // 5px alert( computedStyle.color ); // rgb(255, 0, 0) </script> </body>
74
算出 スタイル値(computed style value)は、CSS カスケードの結果として、すべての CSS ルールと CSS 継承が適用された後の値です。 height:1em または font-size:125% のように見えます。 つまり、CSS適用されたスタイルのまま! 解決 スタイル値(resolved style value)は要素に最終的に適用される値です。 1em or 125% のような値は相対的なものです。ブラウザは計算された値を取り、height: 20px やfont-size: 16px のようにすべての単位を固定し絶対的にします。 ジオメトリ プロパティの場合、解析された値は width:50.5pxのような浮動小数点を持ちます。 つまり、CSS適用されたスタイルの相対値などを解決した値を表示! ずっと以前に、getComputedStyle は算出値を取得するために作られましたが、解決値がはるかに便利であることが分かり、標準が変更されました。 したがって、最近では getComputedStyle は実際にはプロパティの解決された値を返します。通常、ジオメトリ に対しては px です。
75
たとえば、一部のブラウザ(Chrome)では下記のドキュメントに"10px" と表示されていますが、他の一部のブラウザ(Firefox)では – そうではありません: <style> body { margin: 10px; } </style> <script> let style = getComputedStyle(document.body); alert(style.margin); // Firefox では空文字です </script> → getComputedStyle には完全なプロパティ名が必要です paddingやmarginではなく、 paddingLeft や marginTop や borderTopWidth のように、常に正確なプロパティの指定が必要です。 そうしないと、正しい結果が保証されません。
76
:visited CSS 疑似クラスを利用すると、リンクが訪問された状態に対して、色などを設定できる。 これはgetComputedStyleでは取得することができない なぜなら、ユーザがリンクを訪れたことがあるというブラウザの持つ情報を参照してしまうことができるためである。 つまりプライバシーの問題
77
スクロールバーが出ていると、 コンテンツの幅が相対的に狭くなってしまう。 したがって、スクロールバーがなければ、コンテンツの幅は 300px になりますが、スクロールバーの幅が 16px の場合(幅はデバイスやブラウザによって異なる場合があります)、 300-16 = 284px しか残っておらず、我々はそれを考慮する必要があります
78
offsetParent とは次のような、最も近い祖先です。: potision:static(初期値)以外の要素 もしくは <td>, <th>, <table>, もしくは <body> offsetLeft、offsetTopはオフセットペアレントの距離を示す。 なのでexampleのオフセットペアレントはmain を指す potision:absoluteは親要素(オフセットペアレント)に対して絶対配置という意味で、親要素を起点として座標指定した場所に要素を描画する。 なので、指定座標がそのままオフセットの値となり、 180 180が答えとなる。
79
実際以下のoffsetParentの定義に当てはまってはいるけども、 potision:static(初期値)以外の要素 もしくは <td>, <th>, <table>, もしくは <body> nullが返却される状況が存在する。 要素またはその親要素の display プロパティが none に設定されている。 →非表示の要素はオフセットペアレントがない、また要素の親要素が非表示の場合はnullとなる。 要素の position プロパティが fixed(固定位置指定)に設定されている(Firefox は <body> を返します)。 →画面の絶対配置はオフセットペアレントがない 要素が <body> または <html> 要素である。 →ボディとHTMLはオフセットペアレントがない
80
これらは要素の “外側からみたときの”(厳密にはオフセットペアレントからみたときの) 幅/高さを提供します。 もしくは、言い換えると、ボーダーを含むその要素の完全なサイズです。
その他
その他
谷峻輔 · 12問 · 2年前その他
その他
12問 • 2年前LWC
LWC
谷峻輔 · 100問 · 2年前LWC
LWC
100問 • 2年前LWC2
LWC2
谷峻輔 · 28問 · 2年前LWC2
LWC2
28問 • 2年前Javascript
Javascript
谷峻輔 · 100問 · 2年前Javascript
Javascript
100問 • 2年前javascript2
javascript2
谷峻輔 · 58問 · 2年前javascript2
javascript2
58問 • 2年前js1 JavaScript の基礎
js1 JavaScript の基礎
谷峻輔 · 92問 · 2年前js1 JavaScript の基礎
js1 JavaScript の基礎
92問 • 2年前js2 コード品質、オブジェクト基本、データ型
js2 コード品質、オブジェクト基本、データ型
谷峻輔 · 100問 · 2年前js2 コード品質、オブジェクト基本、データ型
js2 コード品質、オブジェクト基本、データ型
100問 • 2年前js3 データ型
js3 データ型
谷峻輔 · 100問 · 2年前js3 データ型
js3 データ型
100問 • 2年前js4 データ型、関数の高度な機能
js4 データ型、関数の高度な機能
谷峻輔 · 100問 · 2年前js4 データ型、関数の高度な機能
js4 データ型、関数の高度な機能
100問 • 2年前js5 関数の高度な機能 オブジェクトプロパティの設定 プロトタイプ, 継承プロトタイプ, 継承、クラス
js5 関数の高度な機能 オブジェクトプロパティの設定 プロトタイプ, 継承プロトタイプ, 継承、クラス
谷峻輔 · 96問 · 2年前js5 関数の高度な機能 オブジェクトプロパティの設定 プロトタイプ, 継承プロトタイプ, 継承、クラス
js5 関数の高度な機能 オブジェクトプロパティの設定 プロトタイプ, 継承プロトタイプ, 継承、クラス
96問 • 2年前js6 クラス Promise, async/await
js6 クラス Promise, async/await
谷峻輔 · 100問 · 2年前js6 クラス Promise, async/await
js6 クラス Promise, async/await
100問 • 2年前js7 Promise, async/await、ジェネレータ, 高度なイテレーション、モジュール
js7 Promise, async/await、ジェネレータ, 高度なイテレーション、モジュール
谷峻輔 · 96問 · 2年前js7 Promise, async/await、ジェネレータ, 高度なイテレーション、モジュール
js7 Promise, async/await、ジェネレータ, 高度なイテレーション、モジュール
96問 • 2年前js8 その他
js8 その他
谷峻輔 · 57問 · 2年前js8 その他
js8 その他
57問 • 2年前Javaとは〜
Javaとは〜
谷峻輔 · 83問 · 2年前Javaとは〜
Javaとは〜
83問 • 2年前Reactクイックスタート
Reactクイックスタート
谷峻輔 · 15問 · 2年前Reactクイックスタート
Reactクイックスタート
15問 • 2年前デザインパターン
デザインパターン
谷峻輔 · 5問 · 2年前デザインパターン
デザインパターン
5問 • 2年前承認申請
承認申請
谷峻輔 · 16問 · 2年前承認申請
承認申請
16問 • 2年前アプリケーションビルダー2
アプリケーションビルダー2
谷峻輔 · 100問 · 2年前アプリケーションビルダー2
アプリケーションビルダー2
100問 • 2年前アプリケーションビルダー3
アプリケーションビルダー3
谷峻輔 · 100問 · 2年前アプリケーションビルダー3
アプリケーションビルダー3
100問 • 2年前アプリケーションビルダー4
アプリケーションビルダー4
谷峻輔 · 100問 · 2年前アプリケーションビルダー4
アプリケーションビルダー4
100問 • 2年前アプリケーションビルダー5
アプリケーションビルダー5
谷峻輔 · 94問 · 2年前アプリケーションビルダー5
アプリケーションビルダー5
94問 • 2年前アプリケーションビルダー6
アプリケーションビルダー6
谷峻輔 · 100問 · 2年前アプリケーションビルダー6
アプリケーションビルダー6
100問 • 2年前アプリケーションビルダー7
アプリケーションビルダー7
谷峻輔 · 100問 · 2年前アプリケーションビルダー7
アプリケーションビルダー7
100問 • 2年前アプリケーションビルダー8
アプリケーションビルダー8
谷峻輔 · 98問 · 2年前アプリケーションビルダー8
アプリケーションビルダー8
98問 • 2年前アプリケーションビルダー9
アプリケーションビルダー9
谷峻輔 · 70問 · 2年前アプリケーションビルダー9
アプリケーションビルダー9
70問 • 2年前フロー
フロー
谷峻輔 · 42問 · 2年前フロー
フロー
42問 • 2年前レポート、ダッシュボード
レポート、ダッシュボード
谷峻輔 · 60問 · 2年前レポート、ダッシュボード
レポート、ダッシュボード
60問 • 2年前SalesCloud
SalesCloud
谷峻輔 · 18問 · 2年前SalesCloud
SalesCloud
18問 • 2年前標準機能
標準機能
谷峻輔 · 72問 · 2年前標準機能
標準機能
72問 • 2年前宣言的開発
宣言的開発
谷峻輔 · 8問 · 2年前宣言的開発
宣言的開発
8問 • 2年前数式、人力規則
数式、人力規則
谷峻輔 · 18問 · 2年前数式、人力規則
数式、人力規則
18問 • 2年前アクセスレベル
アクセスレベル
谷峻輔 · 63問 · 2年前アクセスレベル
アクセスレベル
63問 • 2年前データ型変換
データ型変換
谷峻輔 · 22問 · 2年前データ型変換
データ型変換
22問 • 2年前オブジェクト、項目
オブジェクト、項目
谷峻輔 · 91問 · 2年前オブジェクト、項目
オブジェクト、項目
91問 • 2年前アプリ、タブ
アプリ、タブ
谷峻輔 · 92問 · 2年前アプリ、タブ
アプリ、タブ
92問 • 2年前自動化
自動化
谷峻輔 · 17問 · 2年前自動化
自動化
17問 • 2年前組織、開発モデル
組織、開発モデル
谷峻輔 · 65問 · 2年前組織、開発モデル
組織、開発モデル
65問 • 2年前ボタン、アクション
ボタン、アクション
谷峻輔 · 69問 · 2年前ボタン、アクション
ボタン、アクション
69問 • 2年前インテグレーション
インテグレーション
谷峻輔 · 40問 · 2年前インテグレーション
インテグレーション
40問 • 2年前ページレイアウト、リストビュー、レコードタイプ、プロセス
ページレイアウト、リストビュー、レコードタイプ、プロセス
谷峻輔 · 46問 · 2年前ページレイアウト、リストビュー、レコードタイプ、プロセス
ページレイアウト、リストビュー、レコードタイプ、プロセス
46問 • 2年前標準オブジェクト
標準オブジェクト
谷峻輔 · 42問 · 2年前標準オブジェクト
標準オブジェクト
42問 • 2年前ServiceCloud
ServiceCloud
谷峻輔 · 16問 · 2年前ServiceCloud
ServiceCloud
16問 • 2年前ユーザ、ライセンス、プロファイル、権限セット
ユーザ、ライセンス、プロファイル、権限セット
谷峻輔 · 41問 · 2年前ユーザ、ライセンス、プロファイル、権限セット
ユーザ、ライセンス、プロファイル、権限セット
41問 • 2年前データインポート、エクスポート
データインポート、エクスポート
谷峻輔 · 3回閲覧 · 12問 · 2年前データインポート、エクスポート
データインポート、エクスポート
3回閲覧 • 12問 • 2年前Chatter
Chatter
谷峻輔 · 21問 · 2年前Chatter
Chatter
21問 • 2年前承認申請
承認申請
谷峻輔 · 15問 · 2年前承認申請
承認申請
15問 • 2年前フロー
フロー
谷峻輔 · 44問 · 2年前フロー
フロー
44問 • 2年前レポート、ダッシュボード
レポート、ダッシュボード
谷峻輔 · 65問 · 2年前レポート、ダッシュボード
レポート、ダッシュボード
65問 • 2年前SalesCloud
SalesCloud
谷峻輔 · 18問 · 2年前SalesCloud
SalesCloud
18問 • 2年前標準機能
標準機能
谷峻輔 · 72問 · 2年前標準機能
標準機能
72問 • 2年前宣言的開発
宣言的開発
谷峻輔 · 8問 · 2年前宣言的開発
宣言的開発
8問 • 2年前アクセスレベル
アクセスレベル
谷峻輔 · 52問 · 2年前アクセスレベル
アクセスレベル
52問 • 2年前数式、人力規則
数式、人力規則
谷峻輔 · 17問 · 2年前数式、人力規則
数式、人力規則
17問 • 2年前データ型変換
データ型変換
谷峻輔 · 22問 · 2年前データ型変換
データ型変換
22問 • 2年前オブジェクト、項目
オブジェクト、項目
谷峻輔 · 89問 · 2年前オブジェクト、項目
オブジェクト、項目
89問 • 2年前アプリ、タブ
アプリ、タブ
谷峻輔 · 100問 · 2年前アプリ、タブ
アプリ、タブ
100問 • 2年前自動化
自動化
谷峻輔 · 18問 · 2年前自動化
自動化
18問 • 2年前組織、開発モデル
組織、開発モデル
谷峻輔 · 60問 · 2年前組織、開発モデル
組織、開発モデル
60問 • 2年前ボタン、アクション
ボタン、アクション
谷峻輔 · 69問 · 2年前ボタン、アクション
ボタン、アクション
69問 • 2年前インテグレーション
インテグレーション
谷峻輔 · 40問 · 2年前インテグレーション
インテグレーション
40問 • 2年前ページレイアウト、リストビュー、レコードタイプ、プロセス
ページレイアウト、リストビュー、レコードタイプ、プロセス
谷峻輔 · 44問 · 2年前ページレイアウト、リストビュー、レコードタイプ、プロセス
ページレイアウト、リストビュー、レコードタイプ、プロセス
44問 • 2年前標準オブジェクト
標準オブジェクト
谷峻輔 · 32問 · 2年前標準オブジェクト
標準オブジェクト
32問 • 2年前ServiceCloud
ServiceCloud
谷峻輔 · 17問 · 2年前ServiceCloud
ServiceCloud
17問 • 2年前ユーザ、ライセンス、プロファイル、権限セット
ユーザ、ライセンス、プロファイル、権限セット
谷峻輔 · 18問 · 2年前ユーザ、ライセンス、プロファイル、権限セット
ユーザ、ライセンス、プロファイル、権限セット
18問 • 2年前データインポート、エクスポート
データインポート、エクスポート
谷峻輔 · 11問 · 2年前データインポート、エクスポート
データインポート、エクスポート
11問 • 2年前Chatter
Chatter
谷峻輔 · 21問 · 2年前Chatter
Chatter
21問 • 2年前一時
一時
谷峻輔 · 89問 · 2年前一時
一時
89問 • 2年前一時2
一時2
谷峻輔 · 29問 · 2年前一時2
一時2
29問 • 2年前問題一覧
1
1つ目は、これはJavaScriptコードのグローバルオブジェクトであり、グローバルオブジェクト の章で説明するとおりです。 2つ目は、これは “ブラウザウィンドウ” を表し、ウィンドウを制御するためのメソッドを提供します。 function sayHi() { alert("Hello"); } // グローバル関数は window のプロパティとしてアクセス可能 window.sayHi();
2
ドキュメントオブジェクトモデル、略して DOM は、ページ全体のコンテンツを変更可能なオブジェクトとして表現します。 document オブジェクトはページのメインの “エントリーポイント” です。これを使って、ページ上のものを変更したり作成することができます。 例: // 背景色を赤に変える document.body.style.background = 'red'; // 1秒後に戻す setTimeout(() => document.body.style.background = '', 1000);
3
ブラウザオブジェクトモデル(BOM)は document 以外のすべてと連携するブラウザ(ホスト環境)により提供される追加オブジェクトです。 画像のようなオブジェクトがBOM 関数 alert/confirm/prompt もまた BOM の一部です: それらは直接は document と関係はしませんが、ユーザとコミュニケーションをとる純粋なブラウザメソッドを表します。
4
ブラウザとオペレーティングシステムのバックグラウンドの情報を提供します。 多くのプロパティを持っていますが、最も広く知られている2つのプロパティはこれです: navigator.userAgent – 現在のブラウザについて, navigator.platform – プラットフォームについて(Windows/Linux/Macなどを分ける)
5
現在のURLを読み、ブラウザを新しいURLへリダイレクトできます。 これは、location オブジェクトを使う方法です: alert(location.href); // 現在のURLを表示 if (confirm("Go to wikipedia?")) { location.href = 'https://wikipedia.org'; // 別のURLへリダイレクト }
6
タグのツリー構造で、 スペースのテキストノードがちょいちょいはさまってる。 テキストノードは常に末端ノードである。 改行: ↵ (JavaScript では \n として知られています) スペース: ␣ スペースと改行は文字や数字と同様、完全に有効な文字です。これらはテキストノードを形成し、DOMの一部になります。従って、例えば、上の例では <head> タグは <title> の前にいくつかのスペースを含まれており、そのテキストは #text ノードになります(改行といくつかのスペースのみが含まれています)。
7
もしHTMLファイルが "Hello" という言葉のみだった場合、ブラウザはそれを <html> と <body> でラップし、必須の <head> を追加します。 Tableの自動補正は、 <table id="table"><tr><td>1</td></tr></table> である場合画像のように <tbody>が追加される。
8
document – DOM に入る “エントリーポイント” 要素ノード – HTMLタグ, ツリーのビルディングブロック テキストノード – テキストを含む コメント – 必要に応じて情報をおくことができ、これは表示されません。が JS はDOMからそれを読むことができます。
9
ツールの右側には、次のようなサブのタブがあります: Styles – 組み込みルール(灰色)を含めて、ルール別に現在の要素ルールにCSSが適用されていることがわかります。 ほとんどすべては、下のボックスの大きさ/マージン/パディングを含めて編集できます。 Computed – プロパティによって要素に適用されたCSSを表示する:各プロパティに対して、それを与える規則(CSSの継承などを含む)を見ることができます。 Event Listeners – DOM要素に関連付けられたイベントリスナーを表示します(チュートリアルの次の部分で説明します)。 …など
10
最後に選択した要素は $0 として利用可能で、以前に選択したものは $1 です。 コンソールでコマンドが実行できます。例えば、$0.style.background = 'red' は選択されているリストアイテムを赤にします、このように:
11
<body> = document.body <html> = document.documentElement <head> = document.head
12
Nodeクラスのメソッドで、 childNodes というのがある。 取得されるコレクションは、テキストノードを含むすべての子ノードを持ちます。 プロパティ firstChild と lastChild で最初と最後の子への高速なアクセスができます これらは単なる簡略表記です。子ノードが存在する場合は、常に次のようになります: elem.childNodes[0] === elem.firstChild elem.childNodes[elem.childNodes.length - 1] === elem.lastChild 子ノードがあるかどうかをチェックするための特別な関数 elem.hasChildNodes() もあります。
13
childNodes は配列のように見えます。 が、実際には配列ではなくむしろ コレクション – 特別な配列ライクで反復可能なオブジェクトです。 配列ではないため、配列メソッドは動作しません: alert(document.body.childNodes.filter); // undefined (フィルタメソッドを持っていません!) 最初の1つ目は良いです。2つ目も、配列メソッドが必要な場合は、Array.from でコレクションから “本当の” 配列を作ることができるので許容できます。: alert( Array.from(document.body.childNodes).filter ); // これで使えます
14
これもNodeクラスのメソッド 次のノード(次の兄弟) は nextSibling であり、前のノードは previousSibling です。 親は parentNode として利用可能です。 例えば: // <body> の親は <html> です。 alert( document.body.parentNode === document.documentElement ); // true // <head> の後は <body> に行きます。 alert( document.head.nextSibling ); // HTMLBodyElement // <body> の前は <head> です。 alert( document.body.previousSibling ); // HTMLHeadElement
15
Elementクラスのメソッドを利用する。 children – 要素ノードの子のみです。 firstElementChild, lastElementChild – 最初/最後の要素の子です。 previousElementSibling, nextElementSibling – 隣の要素です。 parentElement – 親の要素です。
16
HTML要素の親ノードはDocumentだが、親要素はnullとなる。 Document null
17
まあ色々あるっぽい。 使う時に調べれ場合と思う。 <table> 要素は次のプロパティをサポートします(上で与えられたものに加えて): table.rows – テーブルの <tr> 要素のコレクションです。 table.caption/tHead/tFoot – 要素 <caption>, <thead>, <tfoot> への参照です。 table.tBodies – <tbody> 要素のコレクション(標準によると多数になれます) です。 <thead>, <tfoot>, <tbody> 要素は rows プロパティを提供します: tbody.rows – 内側の <tr> のコレクション <tr>: tr.cells – 与えられた <tr> の中の <td> と <th> セルの集合です。 tr.sectionRowIndex – 囲んでいる <thead>/<tbody> の内部にある与えられた <tr> の番号です。 tr.rowIndex – テーブル内の <tr> の番号です。 <td> と <th>: td.cellIndex – <tr> で囲まれている内側でのセルの番号です。 使用例: <table id="table"> <tr> <td>one</td><td>two</td> </tr> <tr> <td>three</td><td>four</td> </tr> </table> <script> // "two" の td を取得 let td = table.rows[0].cells[1]; td.style.backgroundColor = "red"; // ハイライト </script>
18
document.getElementById(id) メソッド getElementById は document オブジェクトに対してのみ呼び出し可能です。これはドキュメント全体から指定された id を探します。 elem.querySelectorAll(css) 指定された CSS セレクターに一致する elem 内のすべての要素を返します 例 最後の子要素となるすべての <li> 要素を探します: let elements = document.querySelectorAll('ul > li:last-child'); elem.querySelector(css) もある。 ほかにも elem.getElementsByTagName(tag) elem.getElementsByClassName(className) document.getElementsByName(name) がある
19
要素に id 属性があると、document.getElementById(id) メソッドを使用することで要素が取得できます。 例: <div id="elem"> <div id="elem-content">Element</div> </div> <script> // 要素を取得 let elem = document.getElementById('elem'); // 背景を赤にします elem.style.background = 'red'; </script> また、要素を参照する id で名前付けされたグローバル変数もあります: <div id="elem"> <div id="elem-content">Element</div> </div> <script> // elem は id="elem" の DOM 要素を参照します elem.style.background = 'red'; // id="elem-content" はハイフンがあるので変数名にはできません。 // が、角括弧を使用してアクセスできます: window['elem-content'] </script> ただし、 要素にアクセスするのに、id名のグローバル変数は使わないでください この振る舞いは スペック で説明されているので、標準の1つです。が、主に互換性のためにサポートされています。 ブラウザは JS と DOM の名前空間を混在させることで助けようとします。シンプルなスクリプトであればよいですが、一般的には良いことではありません。名前が衝突する可能性があります。また、JS を見て、HTMLを見なかった場合、変数がどこから来たのかが明白ではありません。
20
疑似クラスも使えます :hover や :active のような CSS セレクタの擬似クラスもサポートされています。例えば、document.querySelectorAll(':hover') はポインタがある要素のコレクションを返します(ネスト順は、最も外側の <html> から最もネストされたものの順です)。
21
elem.matches(css) は単に elem が与えられた CSS セレクタに一致するかをチェックし、true または false を返します。 このメソッドは、要素(配列か何か)を反復処理し、興味のあるものをフィルタしようとするときに便利です。 例えば: <a href="http://example.com/file.zip">...</a> <a href="http://ya.ru">...</a> <script> // document.body.children の代わりに任意のコレクションが可能です for (let elem of document.body.children) { if (elem.matches('a[href$="zip"]')) { alert("The archive reference: " + elem.href ); } } </script>
22
メソッド elem.closest(css) は CSS セレクタにマッチする最も近い祖先を見ます。elem 自身も検索対象に含まれています。 つまり、メソッド closest は要素(elem)から上に進み、親をチェックしていきます。セレクタにマッチしたら、検索を止めその祖先を返却します。 例: <h1>Contents</h1> <div class="contents"> <ul class="book"> <li class="chapter">Chapter 1</li> <li class="chapter">Chapter 1</li> </ul> </div> <script> let chapter = document.querySelector('.chapter'); // LI alert(chapter.closest('.book')); // UL alert(chapter.closest('.contents')); // DIV alert(chapter.closest('h1')); // null (h1 は祖先ではないので) </script>
23
すべての "getElementsBy*" メソッドは ライブ(動的)な コレクションを返します。このようなコレクションは常にドキュメントの現在の状態を反映し、変更があったとき “自動更新” されます。 <div>First div</div> <script> let divs = document.getElementsByTagName('div'); alert(divs.length); // 1 </script> <div>Second div</div> <script> alert(divs.length); // 2 </script> <div>First div</div> querySelectorAll は 静的な コレクションです。これは配列の要素の数が固定されたコレクションということ。→後から増えたり減ったりしない。 <script> let divs = document.querySelectorAll('div'); alert(divs.length); // 1 </script> <div>Second div</div> <script> alert(divs.length); // 1 </script>
24
親子関係を調べるメソッド elemA.contains(elemB) は elemB が elemA の中にある(elemA の子孫)または elemA==elemB の場合 true を返します。
25
階層のルートは EventTarget で、これは Node により継承されています。また他の DOM ノードはそれを継承しています 図のとおり
26
EventTarget – はルートの “抽象” クラスです。 このクラスのオブジェクトは生成されません。これはベースとして機能し、すべての DOM ノードはいわゆる “イベント” をサポートします。
27
Node – もまた “抽象” クラスで、DOM ノードの基底として機能します。 これはコアなツリー機能を提供します。: parentNode, nextSibling, childNodes など(これらは getter です)。 Node クラスのオブジェクトは決して生成されません。 しかし、それを継承した具体的なノードクラス、即ち: テキストノードの Text, 要素ノードの Element や、コメントノードのための Comment などもあります。
28
Element – は DOM 要素のベースクラスです。 nextElementSibling, children や getElementsByTagName, querySelector 等の検索メソッドといった、要素レベルのナビゲーションを提供します。 ブラウザでは、HTML だけでなく、XML や SVG のドキュメントがある場合もあります。 Element クラスは SVGElement、XMLElement、HTMLElement といったより具体的なクラスのベースとして機能します。
29
HTMLElement – は最終的にすべてのHTML要素のベースクラスです。 色々な HTML要素 がこれを継承しています。: HTMLInputElement – <input> 要素のためのクラス, HTMLBodyElement – <body> 要素のためのクラス, HTMLAnchorElement – <a> 要素のためのクラス …など、各タグは固有のプロパティやメソッドを提供する独自のクラスを持っています。
30
DOM ノードのクラス名を見るに、オブジェクトは通常 constructor プロパティを持っていることを思い出してください。 これはクラスコンストラクタを参照し、 constructor.name はその名前です: alert( document.body.constructor.name ); // HTMLBodyElement …もしくはその toString: alert( document.body ); // [object HTMLBodyElement] また、継承チェックに instanceof を使うこともできます: alert( document.body instanceof HTMLBodyElement ); // true alert( document.body instanceof HTMLElement ); // true alert( document.body instanceof Element ); // true alert( document.body instanceof Node ); // true alert( document.body instanceof EventTarget ); // true
31
ほとんどのブラウザは、開発者ツールで2つのコマンドをサポートしています。 console.log と console.dir です。 それらは引数をコンソールに出力します。JavaScript オブジェクトに対しては通常同じ動作をします。 しかし、DOM 要素に対しては異なります。: console.log(elem) は要素の DOM ツリーを表示します console.dir(elem) は DOM オブジェクトとして要素を表示します。 プロパティを調べるのには良いです。
32
elem.nodeType == 1 は要素ノード, elem.nodeType == 3 はテキストノード, elem.nodeType == 9 はドキュメントオブジェクト
33
nodeName または tagName プロパティでそのタグの名前を見ることができます。: 例: alert( document.body.nodeName ); // BODY alert( document.body.tagName ); // BODY tagName プロパティは Element ノードに対してのみ存在します。テキストノードとかにはない <body><!-- comment --> <script> // for comment alert( document.body.firstChild.tagName ); // undefined (not element) alert( document.body.firstChild.nodeName ); // #comment // for document alert( document.tagName ); // undefined (not element) alert( document.nodeName ); // #document </script> </body>
34
innerHTMLプロパティは要素内の HTML を文字列として取得することができます。 Elementクラスのもちもの。 また、それを変更することもできます。なので、ページを変更する最も強力な方法の1つです。 この例は document.body のコンテンツを表示し、その後、コンテンツを完全に置き換えます: <body> <p>A paragraph</p> <div>A div</div> <script> alert( document.body.innerHTML ); // 現在の内容を読む document.body.innerHTML = 'The new BODY!'; // 置き換える </script> </body> 無効な HTML を挿入しようとすると、ブラウザはエラーを修正します。: <body> <script> document.body.innerHTML = '<b>test'; // タグのクローズ忘れ alert( document.body.innerHTML ); // <b>test</b> (修正された) </script> </body> ちなみに スクリプトは実行しません もし innerHTML が <script> タグをドキュメントに挿入した場合、-- HMLT の一部にはなりますが、実行されません。
35
既存のコンテンツが “完全に取り除かれ 、最初から書き直される。 すべての画像やその他のリソースはロードされます。 これは elem.innerHTML+="何か" によって追加された場合でも同様!
36
outerHTML プロパティは要素の完全な HTML を含みます。それは innerHTML に要素自身を加えたようなものです。 例: <div id="elem">Hello <b>World</b></div> <script> alert(elem.outerHTML); // <div id="elem">Hello <b>World</b></div> </script> 注意: innerHTML とは違い、outerHTML への書き込みは可能で、画面的に適用されるが、書き込んだ要素をもう一度参照しても適用されてないように見えるらしい まあ複雑なので、あんまやらんこと
37
nodeValue と data プロパティです。 これら2つは実際の利用においてはほとんど同じで、仕様上少し違いがあるだけです。なので、より短い data を使います。 <body> Hello <!-- Comment --> <script> let text = document.body.firstChild; alert(text.data); // Hello let comment = text.nextSibling; alert(comment.data); // Comment </script> </body>
38
Nodeクラスのもちもので、 要素内の テキスト へのアクセスを提供します: テキストだけで、すべての <tags> を除きます。 textContent への書き込みはとても役立ちます。なぜならテキストを “安全な方法” で書くことができるからです。 例えばユーザによって入力された任意の文字列を表示したいとしましょう。 innerHTML を使うと、すべての HTML タグと一緒に、“HTML として” 挿入されます。 textContent では、すべてのシンボルは文字通り扱われ、“テキスト として” 挿入されます。
39
HTMLElementクラスのhiddenプロパティを利用する <div>Both divs below are hidden</div> <div hidden>With the attribute "hidden"</div> <div id="elem">JavaScript assigned the property "hidden"</div> <script> elem.hidden = true; </script> 技術的には、hidden は style="display:none" と同じ動きです。しかしより短く書けます。
40
value – <input>, <select> や <textarea> (HTMLInputElement, HTMLSelectElement…) のための値。 href – <a href="..."> (HTMLAnchorElement) の href. console.dir(elem) で要素を出力しプロパティを確認することができます。 もしくはブラウザ開発者ツールの Elements タブで “DOM プロパティ” を参照してください。
41
BODY <body> の内容はコメントに置き換えられます。body.tagName == "BODY" なので、コメントは <!–BODY–> です。覚えているように、tagName は HTML では常に大文字です。 コメントは今唯一の子ノードなので、body.firstChild でそれを取得します。 コメントの data プロパティはその内容(<!--...--> の中): "BODY" です。
42
DOM ノードは通常のJavaScriptオブジェクトです。それを変更できます。 例えば、document.body に新しいプロパティを作成してみましょう: document.body.myData = { name: 'Caesar', title: 'Imperator' }; alert(document.body.myData.title); // Imperator 同様にメソッドの追加もできます: document.body.sayHi = function() { alert(this.tagName); }; document.body.sayHi(); // BODY (このメソッドの "this" の値は document.body)
43
直接参照できないので、undefinedとなる。 従って、要素が id または他の 標準の 属性を持っている場合、対応するプロパティが生成されます。しかし、属性が非標準の場合はプロパティは生成されません。
44
すべての属性は次のメソッドでアクセス可能です。: elem.hasAttribute(name) – 存在をチェックします。 elem.getAttribute(name) – 値を取得します。 elem.setAttribute(name, value) – 値を設定します。 elem.removeAttribute(name) – 属性を削除します。 <body something="non-standard"> <script> alert(document.body.getAttribute('something')); // non-standard </script> </body>
45
設定したものを含む全属性は outerHTML で確認できます。 attributes のコレクションは反復可能で、属性は name と value を持っています。 alert( elem.outerHTML ); // (3), 参照 for (let attr of elem.attributes) { // (4) すべてをリスト alert( attr.name + " = " + attr.value ); }
46
データは同期される なので ido newId しかし、プロパティによって例外もある!!
47
例えば、 input.value の同期は 属性から → プロパティの場合のみで、逆は同期されません: <input> <script> let input = document.querySelector('input'); // 属性 => プロパティ input.setAttribute('value', 'text'); alert(input.value); // text // ☓ プロパティ => 属性 input.value = 'newValue'; alert(input.getAttribute('value')); // text (更新されていません!) </script> 上の例では: 属性 value の変更は、プロパティも更新します。 しかし、プロパティの変更は属性に影響を与えません。 この “特徴” は実際には便利な場合があります。なぜなら、ユーザは value を変更する可能性があるからです。その後、HTMLから元の値を復元する場合、元の値は属性にあります。 つまり、プロパティ変更を行うことで、 元の値を属性に保持したままにできる
48
HTMLの書式で記述する場合は、大文字小文字は区別されません。 HTMLでは、要素名や属性名の大文字小文字は区別されません。 ちなみにjsのプロパティとかは大文字小文字区別する なので、プロパティアクセスする場合 下記のように大文字小文字で違うとアクセスできないので注意 <body id="test"> <script> alert(document.body.ID); // undefined </script> </body>
49
style 属性は文字列がもどるが、 style プロパティはオブジェクト、 CSSStyleDeclarationがもどる。 <div id="div" style="color:red;font-size:120%">Hello</div> <script> // string alert(div.getAttribute('style')); // color:red;font-size:120% // object alert(div.style); // [object CSSStyleDeclaration] alert(div.style.color); // red </script>
50
href DOM プロパティは、属性が相対URLや単なる #hash だとしても、常に 完全な URLです。 プロパティアクセスは完全なURLとなる! 以下はその例です: <a id="a" href="#hello">link</a> <script> // 属性 alert(a.getAttribute('href')); // #hello // プロパティ alert(a.href ); // 完全なURLの形式 http://site.com/page#hello </script>
51
HTML から JavaScript へカスタムデータを渡す、 もしくは JavaScript のためにHTML要素を “マークする” 目的として、非標準の属性が使われることがあります。 属性メソッドで値を取得して、 その値を利用して オブジェクトからデータを取得するみたいなことができる。 他にもカスタム属性でセレクタして、 CSSStyleルールをカスタム属性がついたものだけに適用することもできる。 以下のようにスタイルを設定できる .elem[custom-prop="new"] { color: green; } スタイルをあとで消したいなら以下のようにできる。 elem.setAttribute('custom-prop', 'canceled');
52
衝突を避けるために、data-* 属性があります。 "data-" で始まるすべての属性はプログラマのために予約されています。これらは dataset プロパティで利用可能です。 例えば、elem が "data-about" という名前の属性を持つ場合、elem.dataset.about でアクセスできます。 <body data-about="Elephants"> <script> alert(document.body.dataset.about); // Elephants </script> data-order-state のような複数語はキャメルケースになります: dataset.orderState.
53
ドキュメントクラスのメソッド。 要素をつくる let div = document.createElement('div'); テキストノードをつくる let textNode = document.createTextNode('Here I am');
54
ノードのメソッドを利用する node.append(...nodes or strings) – node の末尾にノードまたは文字列を追加します。 node.prepend(...nodes or strings) – node の先頭にノードまたは文字列を挿入します。 node.before(...nodes or strings) –- node の前にノードまたは文字列を追加します。 node.after(...nodes or strings) –- node の後にノードまたは文字列を追加します。 node.replaceWith(...nodes or strings) –- node を与えられたノードまたは文字列で置き換えます。 これらのメソッドの引数は挿入する任意の DOM ノードのリスト、あるいはテキスト文字列(自動的にテキストノードになります)です。 let div = document.createElement('div'); div.className = "alert alert-success"; div.innerHTML = "<strong>Hi there!</strong> You've read an important message."; document.body.appendChild(div);
55
<p>Hello</p>とhrタグを挿入しているが、 <p>Hello</p>はテキストとして挿入されるので以下のようになる <p>Hello</p> <hr> <div id="div"></div> elem.textContent が行うように、文字列は安全な方法で挿入されます。
56
elem.insertAdjacentHTML(where, html)。 最初のパラメータは文字列で、elem を基準にした挿入場所を指定します。次のいずれかでなければなりません: "beforebegin" – elem の直前に html を挿入します, "afterbegin" – elem の中の先頭に html を挿入します, "beforeend" – elem の中の末尾に html を挿入します, "afterend" – elem の直後に html を挿入します. 2つ目のパラメータは “そのまま” 挿入されるHTML文字列です。 例: <div id="div"></div> <script> div.insertAdjacentHTML('beforebegin', '<p>Hello</p>'); div.insertAdjacentHTML('afterend', '<p>Bye</p>'); </script> …は次のようになります: <p>Hello</p> <div id="div"></div> <p>Bye</p>
57
node.remove() 1秒後に削除する例 let div = document.createElement('div'); div.className = "alert"; div.innerHTML = "<strong>Hi there!</strong> You've read an important message."; document.body.append(div); setTimeout(() => div.remove(), 1000);
58
呼び出し elem.cloneNode(true) は、すべての属性とサブ要素を含む要素の “ディープ” クローンを作成します。 elem.cloneNode(false) を呼び出すと、子要素なしのクローンが作られます。 <style> .alert { padding: 15px; border: 1px solid #d6e9c6; border-radius: 4px; color: #3c763d; background-color: #dff0d8; } </style> <div class="alert" id="div"> <strong>Hi there!</strong> You've read an important message. </div> <script> let div2 = div.cloneNode(true); // メッセージをクローンします div2.querySelector('strong').innerHTML = 'Bye there!'; // クローンを変更します div.after(div2); // 既存の div の後に div2 を表示 </script>
59
DocumentFragment はノードのリストを渡すためのラッパーとして使用できる。 特別な DOM ノードです ノードをまとめて管理できる。 DocumentFragment へ他のノードを追加することができます。 これを挿入する際は代わりにそのコンテンツが挿入されます。 DocumentFragment は明示的にはめったに使用されませんが以下のように使用できます。 let fragment = new DocumentFragment(); fragment.append(ノード); 追加先のノード.append(fragment); これを配列に書きなおすとこんなかんじ 追加先のノード.append(…ノードの配列);
60
親の要素をわざわざ指定する必要があるメソッドは現在あまり利用されないメソッド。 親は指定する必要なし parentElem.appendChild(node) parentElem の末尾の子供として node を追加します。 parentElem.replaceChild(node, oldChild) parentElem の子の中で oldChild を node に置き換えます。 parentElem.removeChild(node) parentElem から node を削除します(node がその子であると想定)。 parentElem.insertBefore(node, nextSibling) parentElem の中で nextSibling の前に node を挿入します。 全て、親の指定が必要のない append, prepend, before, after, remove, replaceWith のようなモダンなメソッドがあるのでそれを使う
61
<p>Somewhere in the page...</p> <script> document.write('<b>Hello from JS</b>'); </script> <p>The end</p> document.write(html) の呼び出しは html を “すぐにその場で” ページに書き込みます。 読み込みが完了する前にページにHTMLを追加するメソッド html 文字列を動的に生成することができるので柔軟性があります。 document.writeの呼び出しはページがロードされている間だけ動作します。 なので、setTimeoutとかで呼び出すと動かないらしい。 “ロード後” の段階でも利用できません。 これは DOMの修正がないため 驚くほど速く動作します。DOMがまだビルドされていない間、それは直接ページテキストに書き込み、ブラウザは生成時にそれをDOMを挿入します。 なので、HTMLの動的に多くのテキストを追加する必要があり、またページをロードするフェーズであること、速度を考慮する必要がある場合には役立ちます。ですが、実際にはこれらの要件が一緒に来ることは殆どありません。通常、このメソッドを見るときは、単に古いスクリプトだからと言う理由です。
62
正しいバリアントは次のようになります: firstChildで毎回消す必要がある。 function clear(elem) { while (elem.firstChild) { elem.firstChild.remove(); } } また、よりシンプルな方法として次のように書くこともできます: function clear(elem) { elem.innerHTML = ''; } ダメな例 function clear(elem) { for (let i=0; i < elem.childNodes.length; i++) { elem.childNodes[i].remove(); } } これは動作しません。なぜなら、remove() の呼び出しは集合 elem.childNodes をシフトするからです。 なので、要素は毎回インデックス 0 から開始します。しかし、 i は増加するので、いくつかの要素はスキップされるでしょう。
63
aaa だけのこる。 HTML がまちがっており、ブラウザの自動修正が働いている。 <table> タグの中は 仕様によると、テーブル固有のタグだけが許可されます。 したがって、ブラウザは <table> の 前に "aaa" を追加します。
64
再帰で実装する。 データの前提としては全てオブジェクトであり、プリミティブは関与しない function createTree(container, obj) { container.append(createTreeDom(obj)); } function createTreeDom(obj) { //このメソッドの終了条件は、キー情報のないオブジェクトであること。 if (!Object.keys(obj).length) return; // オブジェクトであればリストを作る let ul = document.createElement('ul'); for (let key in obj) { // リストアイテムを作り、キーをinnerHTMLに設定する let li = document.createElement('li'); li.innerHTML = key; // オブジェクトのvalueをターゲットに再帰の継続を行う その際、終了条件にひっかかっているならば、appendはしない let childrenUl = createTreeDom(obj[key]); if (childrenUl) { li.append(childrenUl); } ul.append(li); } return ul; } let container = document.getElementById('container'); createTree(container, data);
65
良問題なのでやれ
66
良問題やれ
67
どこかに HTML を部分を挿入する必要がある場合、insertAdjacentHTML がベストです。 解決策: one.insertAdjacentHTML('afterend', '<li>2</li><li>3</li>');
68
style プロパティは CSS カスケードなしで、その "style" 属性の値だけを操作します。 プロパティ elem.style は "style" 属性に書かれたものに対応するオブジェクトです。 elem.style.width="100px" の設定は、属性 style="width:100px" を持っているかのように機能します。 複数語のプロパティは、キャメルケースが使われます: background-color => elem.style.backgroundColor
69
classプロパティは、使えない(予約語によって) なのでclassNameプロパティを使う <body class="main page"> <script> alert(document.body.className); // main page </script> </body> classNameはクラス全体の文字列が設定される。 対して、 elem.classList はクラスを 追加/削除/トグル するためのメソッドを持つ特別なオブジェクトです。 例: <body class="main page"> <script> // クラスを追加します document.body.classList.add('article'); alert(document.body.className); // main page article </script> </body>
70
classList のメソッド: elem.classList.add/remove("class") – クラスの追加/削除をします。 elem.classList.toggle("class") – クラスが存在する場合は削除します。なければ追加します。 elem.classList.contains("class") – クラスをの有無をチェックし、 true/false を返します。 それに加え、classList は反復可能です
71
このための特別なメソッドもあります, elem.style.removeProperty('style property'). 次のようにしてプロパティの削除ができます。:
72
elem.style.cssTextで取得できる。 書き込みも可能! div.style.cssText=`color: red !important; background-color: yellow; width: 100px; text-align: center; `; alert(div.style.cssText); 属性を設定することで同じことができます。: div.setAttribute('style', 'color: red...').
73
getComputedStyle(element[, pseudo]) element 値を読み取る要素 pseudo 疑似要素(必要な場合に指定)。例えば ::before。 空文字列または引数なしは要素自身を意味します。 結果は、elem.style のようにスタイルプロパティを持つオブジェクトですが、ここではすべての CSS クラスに関してのものです。 返却値は、elem.style のようにスタイルプロパティを持つオブジェクトです CssStyleDecolationオブジェクト <head> <style> body { color: red; margin: 5px } </style> </head> <body> <script> let computedStyle = getComputedStyle(document.body); // 今やそこからマージンや色を読み取る事ができます alert( computedStyle.marginTop ); // 5px alert( computedStyle.color ); // rgb(255, 0, 0) </script> </body>
74
算出 スタイル値(computed style value)は、CSS カスケードの結果として、すべての CSS ルールと CSS 継承が適用された後の値です。 height:1em または font-size:125% のように見えます。 つまり、CSS適用されたスタイルのまま! 解決 スタイル値(resolved style value)は要素に最終的に適用される値です。 1em or 125% のような値は相対的なものです。ブラウザは計算された値を取り、height: 20px やfont-size: 16px のようにすべての単位を固定し絶対的にします。 ジオメトリ プロパティの場合、解析された値は width:50.5pxのような浮動小数点を持ちます。 つまり、CSS適用されたスタイルの相対値などを解決した値を表示! ずっと以前に、getComputedStyle は算出値を取得するために作られましたが、解決値がはるかに便利であることが分かり、標準が変更されました。 したがって、最近では getComputedStyle は実際にはプロパティの解決された値を返します。通常、ジオメトリ に対しては px です。
75
たとえば、一部のブラウザ(Chrome)では下記のドキュメントに"10px" と表示されていますが、他の一部のブラウザ(Firefox)では – そうではありません: <style> body { margin: 10px; } </style> <script> let style = getComputedStyle(document.body); alert(style.margin); // Firefox では空文字です </script> → getComputedStyle には完全なプロパティ名が必要です paddingやmarginではなく、 paddingLeft や marginTop や borderTopWidth のように、常に正確なプロパティの指定が必要です。 そうしないと、正しい結果が保証されません。
76
:visited CSS 疑似クラスを利用すると、リンクが訪問された状態に対して、色などを設定できる。 これはgetComputedStyleでは取得することができない なぜなら、ユーザがリンクを訪れたことがあるというブラウザの持つ情報を参照してしまうことができるためである。 つまりプライバシーの問題
77
スクロールバーが出ていると、 コンテンツの幅が相対的に狭くなってしまう。 したがって、スクロールバーがなければ、コンテンツの幅は 300px になりますが、スクロールバーの幅が 16px の場合(幅はデバイスやブラウザによって異なる場合があります)、 300-16 = 284px しか残っておらず、我々はそれを考慮する必要があります
78
offsetParent とは次のような、最も近い祖先です。: potision:static(初期値)以外の要素 もしくは <td>, <th>, <table>, もしくは <body> offsetLeft、offsetTopはオフセットペアレントの距離を示す。 なのでexampleのオフセットペアレントはmain を指す potision:absoluteは親要素(オフセットペアレント)に対して絶対配置という意味で、親要素を起点として座標指定した場所に要素を描画する。 なので、指定座標がそのままオフセットの値となり、 180 180が答えとなる。
79
実際以下のoffsetParentの定義に当てはまってはいるけども、 potision:static(初期値)以外の要素 もしくは <td>, <th>, <table>, もしくは <body> nullが返却される状況が存在する。 要素またはその親要素の display プロパティが none に設定されている。 →非表示の要素はオフセットペアレントがない、また要素の親要素が非表示の場合はnullとなる。 要素の position プロパティが fixed(固定位置指定)に設定されている(Firefox は <body> を返します)。 →画面の絶対配置はオフセットペアレントがない 要素が <body> または <html> 要素である。 →ボディとHTMLはオフセットペアレントがない
80
これらは要素の “外側からみたときの”(厳密にはオフセットペアレントからみたときの) 幅/高さを提供します。 もしくは、言い換えると、ボーダーを含むその要素の完全なサイズです。