スクリプトを外部ファイルに配置すると、次のような利点があります。
- HTMLとコードを分離
- HTML と JavaScript を読みやすく、保守しやすくする
- キャッシュされた JavaScript ファイルによりページの読み込みが高速化されます
複数のスクリプト ファイルを 1 つのページに追加するには、複数のスクリプト タグを使用します。
JavaScript はさまざまな方法でデータを「表示」できます。
window.alert()
書き込み警告ボックスを使用する- 次を使用して
document.write()
HTML 出力を記述します - 次を使用して
innerHTML
HTML 要素を記述します。 - を使用して
console.log()
ブラウザコンソールに書き込みます
内部HTML
HTML 要素にアクセスするために、JavaScript は document.getElementById(id)
メソッドを使用できます。
id
属性は HTML 要素を定義します。innerHTML 属性は HTML コンテンツを定義します。
<!DOCTYPE html>
<html>
<body>
<h1>我的第一张网页</h1>
<p>我的第一个段落</p>
<p id="demo"></p>
<script>
document.getElementById("demo").innerHTML = 5 + 6;
</script>
</body>
</html>
使用 document.write()
テスト目的では、 document.write()
次の方法を使用すると便利です: 4
<!DOCTYPE html>
<html>
<body>
<h1>我的第一张网页</h1>
<p>我的第一个段落</p>
<script>
document.write(5 + 6);
</script>
</body>
</html>
window.alert()を使用する
アラート ボックスを使用してデータを表示できます。
<!DOCTYPE html>
<html>
<body>
<h1>我的第一张网页</h1>
<p>我的第一个段落</p>
<script>
window.alert(5 + 6);
</script>
</body>
</html>
console.log() を使用する
ブラウザでは、 console.log()
メソッドを使用してデータを表示します。F12でブラウザコンソールを起動し、メニューの「コンソール」を選択してください。
<!DOCTYPE html>
<html>
<body>
<h1>我的第一张网页</h1>
<p>我的第一个段落</p>
<script>
console.log(5 + 6);
</script>
</body>
</html>
JavaScriptオブジェクトの学習
対応するオブジェクトを作成することによって作成されるオブジェクト インスタンス
var person = new Object();
person.name = "John";
person.age = 30;
person.job = "banker";
person.sayname = function(){
alert(this.name)
}
以下の方法でも対応可能です
var person2 = {
name: "John",
age: 30,
job: "banker",
sayname: function(){
alert(this.age)
}
}
プロパティのタイプ。ECMAScript には、データ プロパティとアクセサー プロパティという 2 つの対応するプロパティがあります。
データ属性
[設定可能]: 削除に対応する属性を削除することで属性を再定義できるかどうかを示します。プロパティのプロパティを変更できるかどうか、またはプロパティのアクセサーのプロパティを変更できるかどうか
[列挙可能]: for を通じて属性を返すことができることを示します。
[書き込み可能]: 属性の値を変更できるかどうかを示します。
[値]: この属性の値が含まれます。データの読み取りおよび書き込み時に、対応する値をこの位置に置くことができます。
var person2 = {};
Object.defineProperty(person2,"name",{
writable: false,
value: "John"
})
alert(person2.name);
person2.name = "John1";
alert(person2.name);
対応する name 属性が読み取り専用に設定されていることが判明したため、対応する変更のみを行うことができます
アクセサープロパティ
アクセサーのプロパティには、対応するデータ値が含まれていません。これらには、ゲッター関数とセッター関数のペアが含まれています (必須ではありません)。プロパティの値を読み取るときに、対応するゲッター関数が呼び出され、対応するプロパティ値が返されます。対応する属性値を設定すると、対応するセッターが呼び出され、新しい値が渡されます。
[設定可能]: 削除に対応する属性を削除することで属性を再定義できるかどうかを示します。プロパティのプロパティを変更できるかどうか、またはプロパティのアクセサーのプロパティを変更できるかどうか
[列挙可能]: for を通じて属性を返すことができることを示します。
[get]: プロパティの読み取り時に呼び出される関数
[set]: 属性が書き込まれるときに呼び出されます。
var book = {
_year: 2004,
edition: 1
}
Object.defineProperty( book,"year".{
get: function(){
return this._year;
},
set : function(newValue){
if( newValue > 2004){
this._year = newValue;
this.edition+=newValue-2004;
}
}
}
)
book.year = 2005;
alert(book.edition);
対応するプロパティを作成する
Object コンストラクターまたは対応するリテラル スカラーを使用して、対応する単一オブジェクトを作成できますが、これらのメソッドには明らかな欠点があり、同じインターフェイスを使用して多数のオブジェクトを作成すると、大量の重複が生成されます。
工場出荷時のパターン:
function CreateObject(name,age,job){
var o = new Object();
o.name = name;
o.age = age;
o.job = job;
o.sayname = function(){
alert(this.name);
}
return o;
}
短所: 対応するオブジェクト認識の問題は解決できなかった
コンストラクターパターン
function Person(name, age,job){
this.name = name;
this.age = age;
this.job = job;
this.sayname = function(){
alert(this.name);
}
}
var person = new Person("John", 30, "banker");
var person2 = new Person("John", 30, "software Engineer");
この例では、CreateObject の代わりに Person が使用されます。しかし
- 関数内で明示的なオブジェクトの作成はありません。
- 対応するプロパティとメソッドを直接割り当てる
- 対応する返品はありません
- 対応するコンストラクターの最初の文字を大文字にする必要があります。
対応するオブジェクトを使用するには、new を使用して対応するオブジェクトを作成する必要があります。
// 构造函数标识对象
alert(person.constructor == Person)
alert(person2.constructor == Person)
// 当检查是否为对象时可以使用
alert(person instanceof Object)
alert(person2 instanceof Object)
プロトタイプパターン
// 原型模式
function Person(){
}
Person.prototype.name = "John"
Person.prototype.age = 30
Person.prototype.job = "banker"
Person.prototype.sayname = function(){
alert(this.name)
}
var person1 = new Person()
person1.sayname()
var person2 = new Person()
person2.sayname()
alert(person1.constructor == person2.constructor)
まず、このコンストラクターにはパラメーターがありません。プロトタイプ メソッドを使用すると、コンストラクターにパラメーターを渡してプロパティの値を初期化することはできません。これは、Car1 と Car2 の color プロパティが両方とも「blue」に等しく、doors プロパティが両方とも 4 に等しく、mpg プロパティがどちらも 25 に等しい。これは、オブジェクトの作成後にプロパティのデフォルト値を変更する必要があることを意味し、非常に面倒です。
ハイブリッド コンストラクター/プロトタイプ アプローチ
function Car(sColor,iDoors,iMpg) {
this.color = sColor;
this.doors = iDoors;
this.mpg = iMpg;
this.drivers = new Array("Mike","John");
}
Car.prototype.showColor = function() {
alert(this.color);
};
var oCar1 = new Car("red",4,23);
var oCar2 = new Car("blue",3,25);
oCar1.drivers.push("Bill");
alert(oCar1.drivers); //输出 "Mike,John,Bill"
alert(oCar2.drivers); //输出 "Mike,John"
すべての非関数プロパティはコンストラクターで作成されます。つまり、コンストラクター引数を使用してプロパティにデフォルト値を再び割り当てることができます。showColor() 関数のインスタンスは 1 つだけ作成されるため、メモリが無駄になることはありません。
動的プロトタイプ法
function Car(sColor,iDoors,iMpg) {
this.color = sColor;
this.doors = iDoors;
this.mpg = iMpg;
this.drivers = new Array("Mike","John");
if (typeof this.showColor != "function") {
Car.prototype.showColor = function() {
alert(this.color);
};
Car._initialized = true;
}
}
継承する
継承メカニズムを説明する最も簡単な方法は、古典的な例である幾何学的図形を使用することです。実際、幾何学的形状は、楕円 (円形) と多角形(特定の数の辺を持つ)の 2 種類しかありません。円は、交点が 1 つだけある楕円の一種です。三角形、長方形、五角形はすべて、さまざまな数の辺を持つ多角形の一種です。正方形は、すべての辺の長さが等しい長方形の一種です。これは完全な継承関係を構成します。
この例では、Shape は Ellipse と Polygon の基本クラスです (すべてのクラスはそれを継承します)。楕円には属性 fociがあり、楕円が持つ焦点の数を示します。Circle は Ellipse を継承するため、Circle は Ellipse のサブクラスであり、Ellipse は Circle のスーパークラスです。同様に、Triangle、Rectangle、および Pentagon はすべて Polygon のサブクラスであり、Polygon はそれらのスーパークラスです。最後に、Square は Rectangle を継承します。
この継承関係は図で説明するのが最もよく、ここで UML (統一モデリング言語) が登場します。UML の主な用途の 1 つは、継承などの複雑なオブジェクトの関係を視覚的に表現することです。以下の図は、Shape とそのサブクラスの関係を説明する UML 図です。
継承メカニズムの実装
ECMAScript で継承メカニズムを実装するには、継承元の基本クラスから始めます。開発者が定義したすべてのクラスは、基本クラスとして使用できます。セキュリティ上の理由から、ネイティブ クラスとホスト クラスを基本クラスとして使用することはできません。これにより、悪意のある目的に使用される可能性のある、コンパイルされたブラウザ レベルのコードへのパブリック アクセスが防止されます。
基本クラスを選択すると、そのサブクラスを作成できます。基本クラスを使用するかどうかは完全にあなた次第です。場合によっては、直接使用できないが、サブクラスに共通の関数を提供するためにのみ使用される基本クラスを作成したい場合があります。この場合、基本クラスは抽象クラスとみなされます。
ECMAScript は他の言語ほど厳密に抽象クラスを定義しませんが、許可されていないクラスを作成することがあります。通常、このクラスを抽象クラスと呼びます。
作成されたサブクラスは、コンストラクターとメソッドの実装を含む、スーパークラスのすべてのプロパティとメソッドを継承します。すべてのプロパティとメソッドは public であるため、サブクラスはこれらのメソッドに直接アクセスできることに注意してください。サブクラスは、スーパークラスにない新しいプロパティやメソッドを追加したり、スーパークラスのプロパティやメソッドをオーバーライドしたりすることもできます。
継承の仕方
他の機能と同様、ECMAScript は複数の方法で継承を実装します。これは、JavaScript の継承メカニズムが明示的に規定されておらず、模倣によって実装されているためです。これは、すべての継承の詳細がインタープリターによって完全には処理されないことを意味します。開発者には、最適な継承方法を決定する権利があります。
ここでは、具体的な継承方法をいくつか紹介します。
オブジェクトの偽装
元の ECMAScript が考案されたとき、オブジェクトのマスカレードは決して意図されていませんでした。これは、開発者が関数の動作方法、特に関数のコンテキストで this キーワードを使用する方法を理解し始めた後に開発されました。
原理は次のとおりです。コンストラクターは this キーワードを使用して、すべてのプロパティとメソッド(つまり、クラス宣言のコンストラクター メソッド)に値を割り当てます。コンストラクターは単なる関数なので、ClassA のコンストラクターを ClassB のメソッドにして呼び出すことができます。次に、ClassB は ClassA のコンストラクターで定義されたプロパティとメソッドを受け取ります。たとえば、ClassA と ClassB を次のように定義します。
function ClassA(sColor) {
this.color = sColor;
this.sayColor = function () {
alert(this.color);
};
}
function ClassB(sColor) {
}
覚えていますか?キーワード this は、コンストラクターによって現在作成されているオブジェクトを参照します。ただし、このメソッドでは、this はそれが属するオブジェクトを指します。原則は、ClassA をコンストラクターとしてではなく、通常の関数として使用して継承メカニズムを確立することです。継承メカニズムは、次のようにコンストラクター ClassB を使用して実装できます。
function ClassB(sColor) {
this.newMethod = ClassA;
this.newMethod(sColor);
delete this.newMethod;
}
このコードでは、メソッド newMethod が ClassA に割り当てられています (関数名はそれへの単なるポインターであることに注意してください)。次にメソッドを呼び出し、ClassB コンストラクターのパラメーター sColor を渡します。コードの最後の行は ClassA への参照を削除し、後で呼び出すことができないようにします。
すべての新しいプロパティと新しいメソッドは、新しいメソッドのコード行が削除された後に定義する必要があります。そうしないと、スーパークラスの関連するプロパティとメソッドがオーバーライドされる可能性があります。
function ClassB(sColor, sName) {
this.newMethod = ClassA;
this.newMethod(sColor);
delete this.newMethod;
this.name = sName;
this.sayName = function () {
alert(this.name);
};
}
前述のコードが機能することを示すために、次の例を実行します。
var objA = new ClassA("blue");
var objB = new ClassB("red", "John");
objA.sayColor(); //输出 "blue"
objB.sayColor(); //输出 "red"
objB.sayName(); //输出 "John"
オブジェクトの偽装により多重継承が可能になります
興味深いことに、オブジェクトの偽装は多重継承をサポートできます。つまり、クラスは複数のスーパークラスから継承できます。UML で表される多重継承メカニズムを次の図に示します。
function ClassZ() {
this.newMethod = ClassX;
this.newMethod();
delete this.newMethod;
this.newMethod = ClassY;
this.newMethod();
delete this.newMethod;
}
ここには欠点があり、同じ名前のプロパティまたはメソッドを持つ 2 つのクラス ClassX と ClassY がある場合、ClassY の優先順位が高くなります。背後のクラスから継承しているためです。この小さな問題を除けば、オブジェクトの多重継承を偽装するのは簡単です。
この継承方法の人気により、ECMAScript の第 3 版では、Function オブジェクトに call() と apply() という 2 つのメソッドが追加されました。
all() メソッド
call() メソッドは、古典的なオブジェクト偽装メソッドに最も似ています。その最初のパラメータはこのオブジェクトとして使用されます。他のすべてのパラメーターは関数自体に直接渡されます。
function sayColor(sPrefix,sSuffix) {
alert(sPrefix + this.color + sSuffix);
};
var obj = new Object();
obj.color = "blue";
sayColor.call(obj, "The color is ", "a very nice color indeed.");
この例では、関数 SayColor() がオブジェクトの外部で定義されており、どのオブジェクトにも属していなくても、キーワード this を参照できます。オブジェクト obj の color プロパティは青に等しい。call() メソッドを呼び出すとき、最初のパラメータは obj で、sayColor() 関数のこのキーワードの値が obj に割り当てられることを示します。2 番目と 3 番目のパラメータは文字列です。これらは、sayColor() 関数のパラメータ sPrefix および sSuffix と一致し、結果として「色は青です。確かにとても素晴らしい色です。」というメッセージが表示されます。
このメソッドを継承メカニズムのオブジェクト偽装メソッドで使用するには、割り当ての最初の 3 行を置き換え、コードを呼び出し、削除するだけです。
function ClassB(sColor, sName) {
//this.newMethod = ClassA;
//this.newMethod(color);
//delete this.newMethod;
ClassA.call(this, sColor);
this.name = sName;
this.sayName = function () {
alert(this.name);
};
}
apply() メソッド
apply() メソッドは、this として使用されるオブジェクトと関数に渡されるパラメーターの配列の 2 つのパラメーターを取ります。例えば:
function sayColor(sPrefix,sSuffix) {
alert(sPrefix + this.color + sSuffix);
};
var obj = new Object();
obj.color = "blue";
sayColor.apply(obj, new Array("The color is ", "a very nice color indeed."));
この例は、apply() メソッドが呼び出される点を除いて、前の例と同じです。apply() メソッドを呼び出すとき、最初のパラメータは依然として obj であり、sayColor() 関数のこのキーワードの値が obj に割り当てられる必要があることを示します。2 番目のパラメーターは 2 つの文字列の配列で、sayColor() 関数のパラメーター sPrefix と sSuffix に一致します。最終的に生成されるメッセージは依然として「色は青です。本当に素晴らしい色です。」と表示されます。外。
このメソッドは、新しいメソッドの割り当て、呼び出し、削除を行うコードの最初の 3 行を置き換えるのにも使用されます。
function ClassB(sColor, sName) {
//this.newMethod = ClassA;
//this.newMethod(color);
//delete this.newMethod;
ClassA.apply(this, new Array(sColor));
this.name = sName;
this.sayName = function () {
alert(this.name);
};
}
同様に、最初のパラメータは依然として this であり、2 番目のパラメータは値 color が 1 つだけある配列です。ClassB の引数オブジェクト全体を 2 番目のパラメーターとして apply() メソッドに渡すことができます。
function ClassB(sColor, sName) {
//this.newMethod = ClassA;
//this.newMethod(color);
//delete this.newMethod;
ClassA.apply(this, arguments);
this.name = sName;
this.sayName = function () {
alert(this.name);
};
}
プロトタイプチェーン
この形式の継承は、もともと ECMAScript でプロトタイプ チェーンに使用されていました。前の章では、クラスを定義するプロトタイプの方法を紹介しました。プロトタイプ チェーンは、このアプローチを拡張して、興味深い方法で継承メカニズムを実装します。
function ClassA() {
}
ClassA.prototype.color = "blue";
ClassA.prototype.sayColor = function () {
alert(this.color);
};
function ClassB() {
}
ClassB.prototype = new ClassA();
function ClassB() {
}
ClassB.prototype = new ClassA();
ClassB.prototype.name = "";
ClassB.prototype.sayName = function () {
alert(this.name);
};
var objA = new ClassA();
var objB = new ClassB();
objA.color = "blue";
objB.color = "red";
objB.name = "John";
objA.sayColor();
objB.sayColor();
objB.sayName();
また、instanceof 演算子はプロトタイプ チェーン内で独自に動作します。ClassB のすべてのインスタンスについて、instanceof は ClassA と ClassB の両方に true を返します。例えば:
var objB = new ClassB();
alert(objB instanceof ClassA); //输出 "true"
alert(objB instanceof ClassB); //输出 "true"
ハイブリッド
このスタイルの継承では、プロトタイプではなくコンストラクターを使用してクラスを定義します。オブジェクトの偽装に関する主な問題は、コンストラクター メソッドを使用しなければならないことですが、これは最良の選択ではありません。ただし、プロトタイプ チェーンを使用する場合は、パラメーターを指定したコンストラクターを使用できません。開発者はどのように選択するのでしょうか? 答えは簡単です。両方を使用してください。
前の章では、クラスを作成する最良の方法は、コンストラクターでプロパティを定義し、プロトタイプでメソッドを定義することであると説明しました。このメソッドは継承メカニズムにも適用でき、オブジェクトを使用してコンストラクターのプロパティを継承するふりをし、プロトタイプ チェーンを使用してプロトタイプ オブジェクトのメソッドを継承します。前の例を両方の方法で書き直すと、コードは次のようになります。
function ClassA(sColor) {
this.color = sColor;
}
ClassA.prototype.sayColor = function () {
alert(this.color);
};
function ClassB(sColor, sName) {
ClassA.call(this, sColor);
this.name = sName;
}
ClassB.prototype = new ClassA();
ClassB.prototype.sayName = function () {
alert(this.name);
};
この例では、継承メカニズムは青色で強調表示された 2 行のコードによって実装されています。最初の強調表示されたコード行の ClassB コンストラクターでは、オブジェクトが ClassA クラスの sColor プロパティを継承するように偽装されています。2 番目の強調表示されたコード行では、クラス ClassA のメソッドがプロトタイプ チェーンを使用して継承されます。このハイブリッドはプロトタイプ チェーンを使用するため、instanceof 演算子は引き続き正しく動作します。
次の例では、このコードをテストします。
var objA = new ClassA("blue");
var objB = new ClassB("red", "John");
objA.sayColor(); //输出 "blue"
objB.sayColor(); //输出 "red"
objB.sayName(); //输出 "John"
JavaScript HTML DOM
JavaScript は HTML DOM を通じて、HTML ドキュメントのすべての要素にアクセスし、変更することができます。
HTML DOM (ドキュメント オブジェクト モデル)
Web ページが読み込まれると、ブラウザはページのドキュメント オブジェクト モデル (ドキュメント オブジェクト モデル)を作成します。
HTML DOMモデルは、オブジェクトのツリー として構造化されています。
このオブジェクト モデルを通じて、JavaScript は動的な HTML を作成するためのすべての機能を取得します。
- JavaScript はページ内のすべての HTML 要素を変更できます
- JavaScript はページ内のすべての HTML 属性を変更できます
- JavaScript はページ内のすべての CSS スタイルを変更できます
- JavaScript は既存の HTML 要素と属性を削除できる
- JavaScript は新しい HTML 要素と属性を追加できます
- JavaScript はページ内のすべての既存の HTML イベントに反応できます
- JavaScript はページ内に新しい HTML イベントを作成できます
HTML DOM プロパティは、設定または変更できる HTML 要素の値です。
HTML DOM には、JavaScript (および他のプログラミング言語も) を通じてアクセスできます。
DOM では、すべての HTML 要素がオブジェクトとして定義されます。
プログラミング インターフェイスは、各オブジェクトのプロパティとメソッドです。
属性は、取得または設定できる値です(HTML 要素のコンテンツの変更など)。
メソッドは、実行できるアクション(HTML 要素の追加または削除など) です。
<!DOCTYPE html>
<html>
<body>
<h2>我的第一张网页</h2>
<p id="demo"></p>
<script>
document.getElementById("demo").innerHTML = "Hello World!";
</script>
</body>
</html>
getElementById 方法
HTML 要素にアクセスする最も一般的な方法は、要素の ID を使用することです。
上記の例では、getElementById
メソッドは id="demo" を使用して要素を検索します。
innerHTML 属性
要素のコンテンツを取得する最も簡単な方法は、 innerHTML
属性を使用することです。
innerHTML
属性を使用して、HTML 要素のコンテンツを取得または置換できます。
innerHTML
<html>
属性を使用して、 やなど の HTML 要素を取得または変更できます <body>
。
HTML DOM ドキュメントオブジェクト
ドキュメント オブジェクトは Web ページを表します。HTML ページ内の任意の要素にアクセスする場合は、常にドキュメント オブジェクトにアクセスすることから始めます。
ここでは、ドキュメント オブジェクトを使用して HTML にアクセスして操作する方法の例をいくつか示します。
HTML要素を検索する
方法 | 説明する |
---|---|
document.getElementById( id ) | 要素 ID で要素を検索する |
document.getElementsByTagName(名前) | タグ名で要素を検索する |
document.getElementsByClassName( name ) | クラス名で要素を検索する |
HTML要素を変更する
方法 | 説明する |
---|---|
element.innerHTML = 新しい HTML コンテンツ | 要素の内部 HTML を変更する |
element.attribute = 新しい値 | HTML要素の属性値を変更する |
element.setAttribute(属性, 値) | HTML要素の属性値を変更する |
element.style.property = 新しいスタイル | HTML要素のスタイルを変更する |
要素の追加と削除
方法 | 説明する |
---|---|
document.createElement(要素) | HTML要素を作成する |
document.removeChild(要素) | HTML要素を削除する |
document.appendChild(要素) | HTML要素を追加する |
document.replaceChild(要素) | HTML要素を置換する |
document.write(テキスト) | HTML出力ストリームに書き込みます |
イベントハンドラを追加する
方法 | 説明する |
---|---|
document.getElementById(id).onclick = function(){ コード} | onclick イベントにイベント ハンドラーを追加する |
HTML オブジェクトを検索する
最初の HTML DOM レベル 1 (1998 年) では、11 の HTML オブジェクト、オブジェクト コレクション、および属性が定義されています。これらは HTML5 でも動作します。
その後、HTML DOM レベル 3 では、さらに多くのオブジェクト、コレクション、プロパティが追加されました。
属性 | 説明する | ドム |
---|---|---|
ドキュメント.アンカー | name 属性を持つすべての <a> 要素を返します。 | 1 |
ドキュメント.アプレット | すべての <applet> 要素を返します (HTML5 は非推奨) | 1 |
document.baseURI | ドキュメントの絶対ベース URI を返します。 | 3 |
文書.本文 | <body> 要素を返します。 | 1 |
ドキュメント.クッキー | ドキュメントクッキーを返す | 1 |
ドキュメント.doctype | ドキュメントのDoctypeを返します。 | 3 |
document.documentElement | <html> 要素を返す | 3 |
document.documentMode | ブラウザで使用されているモードを返します。 | 3 |
document.documentURI | ドキュメントのURIを返します。 | 3 |
ドキュメント.ドメイン | ドキュメントサーバーのドメイン名を返します。 | 1 |
document.domConfig | 放棄された。DOM 設定を返す | 3 |
document.embeds | すべての <embed> 要素を返します。 | 3 |
ドキュメント.フォーム | すべての <form> 要素を返します。 | 1 |
document.head | <head> 要素を返します。 | 3 |
ドキュメント.イメージ | すべての <img> 要素を返します | 1 |
ドキュメント.実装 | DOM 実装を返します。 | 3 |
document.inputEncoding | ドキュメントのエンコーディング (文字セット) を返します。 | 3 |
document.lastModified | ドキュメントが更新された日時を返します。 | 3 |
ドキュメント.リンク | href 属性を持つすべての <area> 要素と <a> 要素を返します。 | 1 |
document.readyState | ドキュメントの(ロード)ステータスを返します。 | 3 |
ドキュメント.リファラー | 参照 (リンクされたドキュメント) の URI を返します。 | 1 |
ドキュメント.スクリプト | すべての <script> 要素を返します。 | 3 |
document.strictErrorChecking | エラーチェックが強制されるかどうかを返します。 | 3 |
ドキュメントのタイトル | <title> 要素を返します。 | 1 |
ドキュメント.URL | ドキュメントの完全な URL を返します | 1 |
HTML要素を検索する
通常、JavaScript では HTML 要素を操作する必要があります。
これを行うには、まずこれらの要素を見つける必要があります。このタスクを実行するには、いくつかの方法があります。
- ID で HTML 要素を検索する
- タグ名で HTML 要素を検索する
- クラス名で HTML 要素を検索する
- CSSセレクターによるHTML要素の検索
- HTML オブジェクトのコレクションから HTML 要素を検索する
ID で HTML 要素を検索する
DOM 内で HTML 要素を検索する最も簡単な方法は、要素の ID を使用することです。
この例では、id="intro" を持つ要素を検索します。
<!DOCTYPE html>
<html>
<body>
<h1>通过 id 查找 HTML 元素</h1>
<p id="intro">Hello World!</p>
<p>本例演示 <b>getElementsById</b> 方法。</p>
<p id="demo"></p>
<script>
var myElement = document.getElementById("intro");
document.getElementById("demo").innerHTML =
"来自 intro 段落的文本是:" + myElement.innerHTML;
</script>
</body>
</html>
タグ名で HTML 要素を検索する
この例では、すべての <p>
要素を検索します。
<!DOCTYPE html>
<html>
<body>
<h1>通过标签名查找 HTML 元素</h1>
<p>Hello World!</p>
<p>本例演示 <b>getElementsByTagName</b> 方法。</p>
<p id="demo"></p>
<script>
var x = document.getElementsByTagName("p");
document.getElementById("demo").innerHTML =
'第一段中的文本 (index 0) 是:' + x[0].innerHTML;
</script>
</body>
</html>
クラス名で HTML 要素を検索する
同じクラス名を持つすべての HTML 要素を検索する必要がある場合に使用します getElementsByClassName()
。
この例では、class="intro" を持つすべての要素のリストを返します。
<!DOCTYPE html>
<html>
<body>
<h1>通过类名查找 HTML 元素</h1>
<p>Hello World!</p>
<p class="intro">DOM 很有用。</p>
<p class="intro">本例演示 <b>getElementsByClassName</b> 方法。</p>
<p id="demo"></p>
<script>
var x = document.getElementsByClassName("intro");
document.getElementById("demo").innerHTML =
'class ="intro" 的第一段(索引 0):' + x[0].innerHTML;
</script>
</body>
</html>
CSSセレクターによるHTML要素の検索
如果您需要查找匹配指定 CSS 选择器(id、类名、类型、属性、属性值等等)的所有 HTML 元素,请使用 querySelectorAll()
方法。
<!DOCTYPE html>
<html>
<body>
<h1>按查询选择器查找 HTML 元素</h1>
<p>Hello World!</p>
<p class="intro">DOM 很有用。</p>
<p class="intro">本例演示 <b>querySelectorAll</b> 方法。</p>
<p id="demo"></p>
<script>
var x = document.querySelectorAll("p.intro");
document.getElementById("demo").innerHTML =
'class ="intro" 的第一段(索引 0):' + x[0].innerHTML;
</script>
</body>
</html>
通过 HTML 对象选择器查找 HTML 对象
本例查找 id="frm1" 的 form 元素,在 forms 集合中,然后显示所有元素值:
<!DOCTYPE html>
<html>
<body>
<h1>使用 document.forms 查找 HTML 元素</h1>
<form id="frm1" action="/demo/demo_form.asp">
First name: <input type="text" name="fname" value="Bill"><br>
Last name: <input type="text" name="lname" value="Gates"><br><br>
<input type="submit" value="提交">
</form>
<p>单击“试一试”按钮,显示表单中每个元素的值。</p>
<button onclick="myFunction()">试一试</button>
<p id="demo"></p>
<script>
function myFunction() {
var x = document.forms["frm1"];
var text = "";
var i;
for (i = 0; i < x.length ;i++) {
text += x.elements[i].value + "<br>";
}
document.getElementById("demo").innerHTML = text;
}
</script>
</body>
</html>
JavaScript HTML DOM - 改变 HTML
改变 HTML 输出流
JavaScript 能够创建动态 HTML 内容:
document.write()
可用于直接写入 HTML 输出流:
<!DOCTYPE html>
<html>
<body>
<script>
document.write(Date());
</script>
</body>
</html>
改变 HTML 内容
修改 HTML 文档内容最简单的方法是,使用 innerHTML
属性。
如需修改 HTML 元素的内容,请使用此语法:
<!DOCTYPE html>
<html>
<body>
<p id="p10">
"hello world!";
</p>
<script>
document.getElementById("p10").innerHTML ="hello kitty!";
</script>
</body>
</html>
改变属性的值
如需修改 HTML 属性的值,请使用如下语法:
document.getElementById(id).attribute = new value
<!DOCTYPE html>
<html>
<body>
<img id="demo1" src="/home/ss/learn/node_learn/2023-08-05 12-41-26 的屏幕截图.png">
</body>
<script>
document.getElementById("demo1").src = "/home/ss/learn/node_learn/2023-08-05 12-43-54 的屏幕截图.png";
</script>
</html>
JavaScript 表单
JavaScript 表单验证
HTML 表单验证可以通过 JavaScript 完成。
如果表单域 (fname) 为空,该函数会提示一条消息,并返回 false,以防止表单被提交:
<!DOCTYPE html>
<html>
<head>
<script>
function validateForm() {
let x = document.forms["myForm"]["fname"].value;
if (x == "") {
alert("Name must be filled out");
return false;
}
}
</script>
</head>
<body>
<h1>JavaScript 验证</h1>
<form name="myForm" action="/demo/html/action_page.php" onsubmit="return validateForm()" method="post">
Name: <input type="text" name="fname">
<input type="submit" value="Submit">
</form>
</body>
</html>
JavaScript 可以验证数字输入
<!DOCTYPE html>
<html>
<body>
<h1>JavaScript 验证</h1>
<form action="/demo/html/action_page.php" method="post">
<input type="text" name="fname" required>
<input type="submit" value="提交">
</form>
<p>如果您点击提交,而不填写文本字段,浏览器将显示错误消息。</p>
</body>
</html>
JavaScript HTML DOM - 改变 CSS
<html>
<body>
<p id="p2">Hello World!</p>
<script>
document.getElementById("p2").style.color = "blue";
</script>
<p>上面的段落已被脚本改变。</p>
</body>
</html>
使用事件
HTML DOM 允许您在事件发生时执行代码。
当“某些事情”在 HTML 元素上发生时,浏览器会生成事件:
- 点击某个元素时
- 页面加载时
- 输入字段被更改时
您将在本教程的下一章学到更多有关事件的知识。
本例会在用户点击按钮时,更改 id="id1" 的 HTML 元素的样式:
<!DOCTYPE html>
<html>
<body>
<h1 id="id1">我的标题</h1>
<button type="button"
onclick="document.getElementById('id1').style.color = 'red'">
单击我!</button>
</body>
</html>
JavaScript HTML DOM 动画
为了演示如何通过 JavaScript 来创建 HTML 动画,我们将使用一张简单的网页
<!DOCTYPE html>
<html>
<body>
<h1>我的第一部 JavaScript 动画</h1>
<div id="animation">我的动画在这里。</div>
</body>
</html>
为元素添加样式
应该通过 style = "position: relative
" 创建容器元素。
应该通过 style = "position: absolute
" 创建动画元素。
<!Doctype html>
<html>
<style>
#container {
width: 400px;
height: 400px;
position: relative;
background: yellow;
}
#animate {
width: 50px;
height: 50px;
position: absolute;
background: red;
}
</style>
<body>
<h1>我的第一个 JavaScript 动画</h1>
<div id="container">
<div id="animate"></div>
</div>
</body>
</html>
动画代码
JavaScript 动画是通过对元素样式进行渐进式变化编程完成的。
这种变化通过一个计数器来调用。当计数器间隔很小时,动画看上去就是连贯的。
基础代码是:
<!DOCTYPE html>
<html>
<style>
#container {
width: 400px;
height: 400px;
position: relative;
background: yellow;
}
#animate {
width: 50px;
height: 50px;
position: absolute;
background-color: red;
}
</style>
<body>
<p><button onclick="myMove()">单击我</button></p>
<div id ="container">
<div id ="animate"></div>
</div>
<script>
function myMove() {
var elem = document.getElementById("animate");
var pos = 0;
var id = setInterval(frame, 5);
function frame() {
if (pos == 350) {
clearInterval(id);
} else {
pos++;
elem.style.top = pos + "px";
elem.style.left = pos + "px";
}
}
}
</script>
</body>
</html>
JavaScript HTML DOM 事件
对事件作出反应
JavaScript 能够在事件发生时执行,比如当用户点击某个 HTML 元素时。
为了在用户点击元素时执行代码,请向 HTML 事件属性添加 JavaScript 代码:
HTML 事件的例子:
- 当用户点击鼠标时
- 当网页加载后
- 当图像加载后
- 当鼠标移至元素上时
- 当输入字段被改变时
- 当 HTML 表单被提交时
- 当用户敲击按键时
<!DOCTYPE html>
<html>
<body>
<h1 onclick="this.innerHTML='谢谢!'">请点击此文本!</h1>
</body>
</html>
<!DOCTYPE html>
<html>
<body>
<h1 onclick="changeText(this)">点击此文本!</h1>
<script>
function changeText(id) {
id.innerHTML = "Hello:)";
}
</script>
</body>
</html>
<!DOCTYPE html>
<html>
<body>
<p>请点击“试一试”按钮,以执行 displayDate() 函数。</p>
<button id="myBtn">试一试</button>
<p id="demo"></p>
<script>
document.getElementById("myBtn").onclick = displayDate;
function displayDate() {
document.getElementById("demo").innerHTML = Date();
}
</script>
</body>
</html>
onload 和 onunload 事件
当用户进入后及离开页面时,会触发 onload
和 onunload
事件。
onload
事件可用于检测访问者的浏览器类型和浏览器版本,然后基于该信息加载网页的恰当版本。
onload
和 onunload
事件可用于处理 cookie。
<!DOCTYPE html>
<html>
<body onload="checkCookies()">
<p id="demo"></p>
<script>
function checkCookies() {
var text = "";
if (navigator.cookieEnabled == true) {
text = "Cookie 已启用";
} else {
text = "Cookie 未启用";
}
document.getElementById("demo").innerHTML = text;
}
</script>
</body>
</html>
onchange 事件
onchange
事件经常与输入字段验证结合使用。
下面是一个如何使用 onchange
的例子。当用户改变输入字段内容时,会调用 upperCase() 函数。
<!DOCTYPE html>
<html>
<head>
<script>
function myFunction() {
var x = document.getElementById("fname");
x.value = x.value.toUpperCase();
}
</script>
</head>
<body>
请输入您的名字:<input type="text" id="fname" onchange="myFunction()">
<p>离开输入字段时,会触发一个函数,将输入文本转换为大写。</p>
</body>
</html>
onmouseover 和 onmouseout 事件
onmouseover
和 onmouseout
事件可用于当用户将鼠标移至 HTML 元素上或移出时触发某个函数:
<!DOCTYPE html>
<html>
<body>
<div onmouseover="mOver(this)" onmouseout="mOut(this)"
style="background-color:#D94A38;width:120px;height:20px;padding:40px;">
请把鼠标移上来</div>
<script>
function mOver(obj) {
obj.innerHTML = "谢谢您"
}
function mOut(obj) {
obj.innerHTML = "请把鼠标移上来"
}
</script>
</body>
</html>
onmousedown, onmouseup 以及 onclick 事件
onmousedown
, onmouseup
以及 onclick
事件构成了完整的鼠标点击事件。先当鼠标按钮被点击时,onmousedown
事件被触发;然后当鼠标按钮被释放时,onmouseup
事件被触发;最后,当鼠标点击完成后,onclick
事件被触发。
<!DOCTYPE html>
<html>
<body>
<div onmousedown="mDown(this)" onmouseup="mUp(this)"
style="background-color:#D94A38;width:90px;height:20px;padding:40px;">
点击鼠标</div>
<script>
function mDown(obj) {
obj.style.backgroundColor = "#1ec5e5";
obj.innerHTML = "松开鼠标";
}
function mUp(obj) {
obj.style.backgroundColor="#D94A38";
obj.innerHTML="谢谢您";
}
</script>
</body>
</html>
JavaScript HTML DOM 事件监听程序
<!DOCTYPE html>
<html>
<body>
<h2>JavaScript addEventListener()</h2>
<p>此示例使用 addEventListener() 方法将 click 事件附加到按钮。</p>
<button id="myBtn">试一试</button>
<p id="demo"></p>
<script>
document.getElementById("myBtn").addEventListener("click", displayDate);
function displayDate() {
document.getElementById("demo").innerHTML = Date();
}
</script>
</body>
</html>
element.addEventListener(event, function, useCapture);
第一个参数是事件的类型(比如 "click" 或 "mousedown")。
第二个参数是当事件发生时我们需要调用的函数。
第三个参数是布尔值,指定使用事件冒泡还是事件捕获。此参数是可选的。
注意:请勿对事件使用 "on" 前缀;请使用 "click" 代替 "onclick"。
向相同元素添加多个事件处理程序
<!DOCTYPE html>
<html>
<body>
<h1>JavaScript addEventListener()</h1>
<p>此示例使用 addEventListener() 方法将两个 click 事件添加到同一按钮。</p>
<button id="myBtn">试一试</button>
<script>
var x = document.getElementById("myBtn");
x.addEventListener("click", myFunction);
x.addEventListener("click", someOtherFunction);
function myFunction() {
alert ("Hello World!");
}
function someOtherFunction() {
alert ("此函数也被执行了!");
}
</script>
</body>
</html>
向 Window 对象添加事件处理程序
addEventListener()
允许您将事件监听器添加到任何 HTML DOM 对象上,比如 HTML 元素、HTML 对象、window 对象或其他支持事件的对象,比如 xmlHttpRequest 对象。
<!DOCTYPE html>
<html>
<body>
<h1>JavaScript addEventListener()</h1>
<p>此例在 window 对象上使用 addEventListener() 方法。</p>
<p>尝试调整此浏览器窗口的大小以触发“resize”事件处理程序。</p>
<p id="demo"></p>
<script>
window.addEventListener("resize", function(){
document.getElementById("demo").innerHTML = Math.random();
});
</script>
</body>
</html>
事件冒泡还是事件捕获?
在 HTML DOM 中有两种事件传播的方法:冒泡和捕获。
事件传播是一种定义当发生事件时元素次序的方法。假如 <div> 元素内有一个 <p>,然后用户点击了这个 <p> 元素,应该首先处理哪个元素“click”事件?
在冒泡中,最内侧元素的事件会首先被处理,然后是更外侧的:首先处理 <p> 元素的点击事件,然后是 <div> 元素的点击事件。
在捕获中,最外侧元素的事件会首先被处理,然后是更内侧的:首先处理 <div> 元素的点击事件,然后是 <p> 元素的点击事件。
在 addEventListener() 方法中,你能够通过使用“useCapture”参数来规定传播类型:
removeEventListener() 方法
removeEventListener()
方法会删除已通过 addEventListener()
方法附加的事件处理程序:
<!DOCTYPE html>
<html>
<head>
<style>
#myDIV {
background-color: coral;
border: 1px solid;
padding: 50px;
color: white;
font-size: 20px;
}
</style>
</head>
<body>
<h1>JavaScript removeEventListener()</h1>
<div id="myDIV">
<p>这个 div 元素有一个 onmousemove 事件处理程序,每次在这个橙色字段中移动鼠标时都会显示一个随机数。</p>
<p>单击按钮以删除 div 的事件处理程序。</p>
<button onclick="removeHandler()" id="myBtn">删除</button>
</div>
<p id="demo"></p>
<script>
document.getElementById("myDIV").addEventListener("mousemove", myFunction);
function myFunction() {
document.getElementById("demo").innerHTML = Math.random();
}
function removeHandler() {
document.getElementById("myDIV").removeEventListener("mousemove", myFunction);
}
</script>
</body>
</html>
JavaScript HTML DOM 导航
DOM 节点
根据 W3C HTML DOM 标准,HTML 文档中的所有事物都是节点:
- 整个文档是文档节点
- 每个 HTML 元素是元素节点
- HTML 元素内的文本是文本节点
- 每个 HTML 属性是属性节点
- 所有注释是注释节点
节点关系
节点树中的节点彼此之间有一定的等级关系。
- 术语(父、子和同胞,parent、child 以及 sibling)用于描述这些关系。
- 在节点树中,顶端节点被称为根(根节点)。
- 每个节点都有父节点,除了根(根节点没有父节点)。
- 节点能够拥有一定数量的子
- 同胞(兄弟或姐妹)指的是拥有相同父的节点。
<html>
<head>
<title>DOM 教程</title>
</head>
<body>
<h1>DOM 第一课</h1>
<p>Hello world!</p>
</body>
</html>
从以上的 HTML 中您能读到以下信息:
- <html> 是根节点
- <html> 没有父
- <html> 是 <head> 和 <body> 的父
- <head> 是 <html> 的第一个子
- <body> 是 <html> 的最后一个子
子节点和节点值
DOM 处理中的一种常见错误是认为元素节点中包含文本。
<!DOCTYPE html>
<html>
<body>
<h1 id="id01">我的第一张网页</h1>
<p id="id02"></p>
<script>
document.getElementById("id02").innerHTML = document.getElementById("id01").innerHTML;
</script>
</body>
</html>
<html>
<body>
<h1 id="id01">我的第一张页面</h1>
<p id="id02">Hello!</p>
<script>
document.getElementById("id02").innerHTML = document.getElementById("id01").firstChild.nodeValue;
</script>
</body>
</html>
<html>
<body>
<h1 id="id01">我的第一张页面</h1>
<p id="id02">Hello!</p>
<script>
document.getElementById("id02").innerHTML = document.getElementById("id01").childNodes[0].nodeValue;
</script>
</body>
</html>
<html>
<body>
<p>Hello World!</p>
<div>
<p>DOM 很有用!</p>
<p>本例演示 <b>document.body</b> 属性。</p>
</div>
<script>
alert(document.body.innerHTML);
</script>
</body>
</html>
HTML DOM 元素(节点)
添加和删除节点(HTML 元素)
创建新 HTML 元素(节点)
如需向 HTML DOM 添加新元素,您必须首先创建这个元素(元素节点),然后将其追加到已有元素。
<!DOCTYPE html>
<html>
<body>
<div id="div1">
<p id="p1">这是一段文字。</p>
<p id="p2">这是另一段文字。</p>
</div>
<script>
var para = document.createElement("p");
var node = document.createTextNode("这是新的文本。");
para.appendChild(node);
var element = document.getElementById("div1");
element.appendChild(para);
</script>
</body>
</html>
删除已有 HTML 元素
HTML 要素を削除するには、 remove()
次のメソッドを使用します。
<!DOCTYPE html>
<html>
<body>
<h1>JavaScript HTML DOM</h1>
<p>删除 HTML 元素:</p>
<div>
<p id="p1">This is a paragraph.</p>
<p id="p2">This is another paragraph.</p>
</div>
<button onclick="myFunction()">删除元素</button>
<script>
function myFunction() {
document.getElementById("p1").remove();
}
</script>
</body>
</html>
<!DOCTYPE html>
<html>
<body>
<div id="div1">
<p id="p1">这是一段文字。</p>
<p id="p2">这是另一段文字。</p>
</div>
<script>
var parent = document.getElementById("div1");
var child = document.getElementById("p1");
parent.removeChild(child);
</script>
</body>
</html>
HTML要素を置換する
要素を置換するには、 replaceChild()
次のメソッドを使用します。
<!DOCTYPE html>
<html>
<body>
<div id="div1">
<p id="p1">这是一段文字。</p>
<p id="p2">这是另一段文字。</p>
</div>
<script>
var parent = document.getElementById("div1");
var child = document.getElementById("p1");
var para = document.createElement("p");
var node = document.createTextNode("这是新的文本。");
para.appendChild(node);
parent.replaceChild(para,child);
</script>
</body>
</html>
HTML DOM ノードのリスト
NodeList オブジェクトは、ドキュメントから抽出されたノードのリスト (コレクション) です。
NodeList オブジェクトは、HTMLCollection オブジェクトとほぼ同じです。
一部の (古い) ブラウザは、メソッドを使用する場合 getElementsByClassName()
、HTMLCollection の代わりに NodeList オブジェクトを返します。
すべてのブラウザは childNodes
プロパティの NodeList オブジェクトを返します。
ほとんどのブラウザは、 querySelectorAll()
メソッドの NodeList オブジェクトを返します。
次のコードは、ドキュメント内のすべての <p> ノードを選択します。
<!DOCTYPE html>
<html>
<body>
<h1>JavaScript HTML DOM</h1>
<p>Hello World!</p>
<p>Hello China!</p>
<p id="demo"></p>
<script>
var myNodelist = document.querySelectorAll("p");
document.getElementById("demo").innerHTML =
"第二段的 innerHTML 是:" +
myNodelist[1].innerHTML;
</script>
</body>
</html>
HTML DOM ノードリストの長さ
length
このプロパティは、ノード リスト内のノードの数を定義します。
<!DOCTYPE html>
<html>
<body>
<h1>JavaScript HTML DOM</h1>
<p>Hellow World!</p>
<p>Hello China!</p>
<p id="demo"></p>
<script>
var myNodelist = document.querySelectorAll("p");
document.getElementById("demo").innerHTML =
"此文档包含 " + myNodelist.length + " 段文字。";
</script>
</body>
</html>