各ボタンの機能と、対応するイベントハンドラ
getElementByIdとclassNameによる要素の検索と選択
テーブルの最初の行(136~141行目)では、目的の要素のidをテキストフィールド(137~138行目)に入力し、[Get By id]ボタン(139~140行目)をクリックすると、その要素を見つけて選択できます。図10.2(b)および図10.2(g)がその例です。ボタンのonclick属性では、イベントハンドラとしてbyId関数を指定しています。
byId関数の定義は31~38行目にあります。33行目では、getElementByIdを使って、テキストフィールドに入力された内容をid変数に代入しています。34行目では、getElementByIdを再度使って、id変数の値と一致するid属性を持つ要素を探し、target変数に代入しています。指定したid属性を持つ要素が見つかった場合、getElementByIdはその要素を表すオブジェクトを返します。要素が見つからなかった場合、getElementByIdはnullを返します。36行目では、targetがオブジェクトかどうかをチェックしています。オブジェクトをブール式として評価するとtrueとなり、nullはfalseとなります。targetがtrueとして評価された場合、37行目でswitchTo関数を呼び出し、targetを引数に渡しています。
switchTo関数の定義は106~112行目にあります。これは、ページ内の別の要素に選択を切り替えて強調表示するための関数で、このプログラムのあちこちで使用しています。現在選択中の要素は、22行目で定義したhighlightedというスタイルクラスを使用して、黄色の背景で表示します。108行目では、現在のノードのclassNameプロパティを空文字列に設定しています。classNameプロパティでは、XHTML要素のclass属性を変更できます。ここでは、新たに選択したクラスを強調表示する前に、currentNodeのclass属性に指定したhighlightedクラスをクリアする目的で使用しています。
109行目では、currentNode変数にnewNodeオブジェクト(パラメータでこの関数に渡されたオブジェクト)を代入しています。110行目では、新たなcurrentNodeのclassNameプロパティを使って、highlightedスタイルクラスを設定しています。
最後の111行目では、idプロパティを使って、現在選択中のノードのidをテキストフィールドのvalueプロパティに代入しています。classNameプロパティで要素のクラスにアクセスできるのと同様に、idプロパティでは要素のid属性にアクセスできます。この111行目の処理は、byId関数からswitchTo関数を呼び出した場合だけを考えると必要ありません。しかし、この後見ていくように、switchTo関数は他の関数からも呼び出しますので、この行の処理があることで、テキストフィールドの値が現在選択中のノードのidを正しく反映できることになります。こうして、新たな要素を見つけ、古い要素の強調表示を解除し、currentNode変数を更新し、新しい要素を強調表示するという一連の処理を経て、ユーザーが入力したidに基づいて新しいノードを選択する処理が完了します。
insertBeforeとappendChildによる要素の作成と挿入
テーブルの2行目と3行目では、新しい要素を作成して、選択中のノードの前のノードまたは子ノードとして挿入できます。テーブルの2行目(コードの141~145行目)にはテキストフィールドと[InsertBefore]ボタンがあります。テキストを入力してボタンをクリックすると、入力した内容が新しいp要素として現在選択中の要素の前に挿入されます。図10.2(c)はその例です。ボタンの指定は143~144行目にあり、そこから呼び出すinsert関数の定義は42~48行目にあります。
44~45行目ではcreateNewNode関数を呼び出し、idがinsのテキストフィールドの値を引数として渡しています。createNewNode関数は、パラメータで受け取ったテキストを格納した段落ノードを作成する関数で、定義は94~103行目にあります。96行目では、documentオブジェクトのcreateElementメソッドを使ってp要素を作成しています。createElementメソッドは、新しいDOMノードを作成するメソッドで、タグ名を引数に取ります。createElementは要素を作成するのみで、ページへの挿入は行いません。
97行目では、新しい要素で使用する一意のidとして、"new"という文字列の後にidcount変数の値を付加した文字列を作成しています。98行目ではidcountをインクリメントしています。99行目では、作成したidを新しい要素に適用しています。100行目では、要素のidを角かっこで囲み、text変数(段落の内容としてパラメータで受け取ったテキスト)の先頭に付加しています。
101行目では、新しいメソッドを2つ使用しています。1つはdocumentのcreateTextNodeメソッドで、テキストのみを含むノードを作成するメソッドです。文字列を引数に渡すと、その内容を格納したテキストノードを作成してくれます。101行目では、text変数を使ってテキストノードを新規作成しています。さらに同じ行の中で、そのノードをappendChildメソッドの引数として渡しています。このメソッドは、上で作成した段落ノードに対して呼び出しています。appendChildメソッドは、親となるノードに対して呼び出すメソッドで、引数で渡したノードが子ノードとして挿入されます。既に子ノードがある場合は、その末尾に挿入されます。
こうしてp要素を作成したら、102行目でノードを戻り値として返し、呼び出し元のinsert関数に処理が戻ります。44~45行目では、その戻り値をnewNode変数に代入しています。46行目では、こうして新規作成したノードを現在選択中のノードの前に挿入しています。DOMノードのparentNodeプロパティは、親ノードを返すプロパティです。46行目では、currentNodeのparentNodeプロパティを使って親を取得しています。
46行目では、その親に対してinsertBeforeメソッドを呼び出し、newNodeとcurrentNodeを引数として渡しています。これにより、currentNodeの直前の子としてnewNodeが挿入されます。insertBeforeメソッドの一般的な構文は次のとおりです。
parent.insertBefore( newChild, existingChild );
このように、親ノードに対して呼び出すメソッドで、新しい子ノードと既存の子ノードを引数として渡します。newChildとして指定した子が、existingChildとして指定した子の直前に挿入されるという形です。47行目では、既に説明したswitchTo関数を使って、新しく挿入したノードがcurrentNodeとなるよう更新し、XHTMLページ内でこのノードを強調表示します。
テーブルの3行目(コードの145~149行目)では、現在選択中の要素の子として新しい段落ノードを追加できます。図10.2(d)はその例です。この機能も、処理の流れはinsertBeforeと同様です。appendNode関数の53~54行目でノードを新規作成し、55行目で現在選択中のノードの子として挿入したうえで、56行目でswitchToを使ってcurrentNodeの更新と新しいノードの強調表示を行います。
replaceChildとremoveChildによる要素の置換と削除
テーブルの4行目と5行目(コードの149~156行目)では、現在選択中の要素を新しいp要素に置き換える処理と、現在選択中の要素を削除する処理を実行できます。150~152行目にあるテキストフィールドとボタンは、現在選択中の要素を、新しいテキストの段落ノードに置換するもので、図10.2(e)がその例です。
151~152行目のボタンではreplaceCurrent関数を呼び出し、その定義は60~66行目にあります。62~63行目では、該当するテキストフィールドの入力内容を使ってcreateNewNodeを呼び出しています。この処理はinsertおよびappendNodeと同様です。64行目では、currentNodeの親を取得したうえで、そのreplaceChildメソッドを呼び出しています。replaceChildメソッドの一般的な構文は次のとおりです。
parent.replaceChild( newChild, oldChild );
replaceChildメソッドは、parentの子の中からoldChildを見つけ、newChildに置換します。
図10.2(h)に示す[Remove Current]機能は、現在選択中の要素を完全に削除し、その親を選択状態にする機能です。新しい要素は作成しないため、テキストフィールドは必要ありません。154~155行目のボタンでremove関数を呼び出し、その定義は69~79行目にあります。選択中のノードの親がbody要素の場合は、72行目でエラーを表示しています。このプログラムでは、body要素全体を選択状態にできないようにしているためです。親がbody要素でない場合は、現在選択中の要素を75~77行目で削除しています。75行目では、現在のcurrentNodeをoldNode変数に待避しています。currentNodeの値を変えた後も、削除対象のノードを参照できるようにするためです。76行目では、switchToを呼び出して、親ノードを選択状態にしています。
77行目では、removeChildメソッドを使って、oldNode(新しいcurrentNodeの子)をXHTMLドキュメント内の現在の場所から削除しています。このメソッドの一般的な構文は次のとおりです。
parent.removeChild( child );
このメソッドは、parentの子ノードの中からchildを見つけ出して削除します。
最後のボタン(157~158行目)は、現在選択中の要素の親要素を選択状態にして強調表示する機能を持ちます。このボタンで呼び出すのはparent関数で、その定義は82~90行目にあります。関数内の処理は単純で、親ノードを取得し(84行目)、body要素でないことを確認したうえで(86行目)、switchToを呼び出して選択状態にしています(87行目)。89行目では、親ノードがbody要素の場合にエラーを表示しています。図10.2(f)がこの機能の例です。
このセクションでは、DOMツリーの操作と処理を行うための基本的な方法について見てきました。次はコレクションの概念を紹介します。コレクションを使うと、ページ内の複数の要素にアクセスできます。
