適用 (対象)
HTML 及び XHTML の中で利用される ECMAScript
これは達成基準 1.3.1: 情報及び関係性に関する達成方法である。(書かれていない達成方法を満たす慣習的な達成方法)
解説
この達成方法の目的は、document.write 又は object.innerHTML の代わりに Document Object Model (DOM) の機能を用いて、ページ中にコンテンツを追加することである。document.write() メソッドは XHTML で正しい MIME タイプ (application/xhtml+xml) が指定されているときに動作せず、innerHTML プロパティは DOM の仕様ではないため利用すべきでない。もし DOM の機能を利用してコンテンツを追加すれば、ユーザエージェントは DOM にアクセスしてコンテンツを取り込むことができる。createElement() 関数を使って DOM の中に要素を作成することもできる。createTextNode() は要素に関連付けられたテキストを作成するのに用いられる。appendChild()、removeChild()、insertBefore() 及び replaceChild() 関数は、要素やノードを追加したり削除したりするのに用いられる。その他の DOM 関数は、作成された要素に属性を与えるときに使用される。
フォーカス可能な要素を文書に追加するとき、tabindex 属性を用いて明示的なタブ順序を指定してはならない。なぜなら、文書の中央にフォーカス可能な要素を追加するときに問題が発生するからである。tabindex 属性を明示的に設定しないことで、デフォルトのタブ順序が新しい要素に割り当てられるようにする。
HTML §8.4.3 document.write() の Warning でも述べられているように、たとえ HTML (MIME タイプ text/html) であっても document.write()
の使用は勧められていない。
innerHTML
は 2018 年現在、DOM Parsing and Serialization 仕様で定義されている。
WAIC では SCR21 に関するアクセシビリティ・サポーテッド(AS)情報を提供している。2014 年 6 月版のアクセシビリティ・サポーテッド(AS)情報: SCR21 では、「達成可能」と評価されている。WAIC はこの達成方法が検証した環境で広く動作すると判断している。
事例
事例 1
この例では、クライアントサイドスクリプトの使用法として、フォームの検証方法を紹介している。もしエラーがみつかれば、適切なエラーメッセージが表示される。この例では DOM 関数を使用し、タイトル、エラーに関する短い説明、及びエラー一覧の順序付リストを含むエラー通知を追加している。タイトルの内容はリンクとして書かれているので、focus メソッドを使って利用者の注意をエラーに向けることができる。個別のリスト項目もまた、リンクとして書かれているので、そのリンク先に移動したときにエラーのあるフォームのフィールドにフォーカスできるように書かれている。
この例では、簡単にするために二つのテキストフィールドだけを検証しているが、一般的なフォームハンドラにするために容易に拡張することができる。クライアントサイドの検証は、それを唯一の検証とすべきではなく、サーバーサイドの検証でも確認するべきである。クライアントサイドでの検証の利点は、利用者にすぐにフィードバックを提供することで、サーバーからエラーが帰ってくるまでの間、彼らを待たせることがないこと、及びサーバーへの余計なトラフィックを軽減できることである。
次の例はフォームにイベントハンドラを追加するスクリプトである。もしスクリプトが有効であれば、サーバーにフォームが送信される前に validateNumbers() 関数がクライアントサイドの検証のために呼び出される。もしスクリプトが有効でなければ、フォームはすぐにサーバー側に送信されるので、検証機能はサーバーにも実装されるべきである。
window.onload = initialise; function initialise() { // Ensure we're working with a relatively standards compliant user agent if (!document.getElementById || !document.createElement || !document.createTextNode) return; // Add an event handler for the number form var objForm = document.getElementById('numberform'); objForm.onsubmit= function(){return validateNumbers(this);}; }
次の例は validation の機能である。エラーメッセージの要素を作成するために createElement()、createTextNode()、及び appendChild() DOM 関数を使用しているところに注目して欲しい。
function validateNumbers(objForm) { // Test whether fields are valid var bFirst = isNumber(document.getElementById('num1').value); var bSecond = isNumber(document.getElementById('num2').value); // If not valid, display errors if (!bFirst || !bSecond) { var objExisting = document.getElementById('validationerrors'); var objNew = document.createElement('div'); var objTitle = document.createElement('h2'); var objParagraph = document.createElement('p'); var objList = document.createElement('ol'); var objAnchor = document.createElement('a'); var strID = 'firsterror'; var strError; // The heading element will contain a link so that screen readers // can use it to place focus - the destination for the link is // the first error contained in a list objAnchor.appendChild(document.createTextNode('Errors in Submission')); objAnchor.setAttribute('href', '#firsterror'); objTitle.appendChild(objAnchor); objParagraph.appendChild(document.createTextNode('Please review the following')); objNew.setAttribute('id', 'validationerrors'); objNew.appendChild(objTitle); objNew.appendChild(objParagraph); // Add each error found to the list of errors if (!bFirst) { strError = 'Please provide a numeric value for the first number'; objList.appendChild(addError(strError, '#num1', objForm, strID)); strID = ''; } if (!bSecond) { strError = 'Please provide a numeric value for the second number'; objList.appendChild(addError(strError, '#num2', objForm, strID)); strID = ''; } // Add the list to the error information objNew.appendChild(objList); // If there were existing errors, replace them with the new lot, // otherwise add the new errors to the start of the form if (objExisting) objExisting.parentNode.replaceChild(objNew, objExisting); else { var objPosition = objForm.firstChild; objForm.insertBefore(objNew, objPosition); } // Place focus on the anchor in the heading to alert // screen readers that the submission is in error objAnchor.focus(); // Do not submit the form objForm.submitAllowed = false; return false; } return true; } // Function to validate a number function isNumber(strValue) { return (!isNaN(strValue) && strValue.replace(/^\s+|\s+$/, '') !== ''); }
以下は、エラーメッセージを作成して、関連するフォームのフィールドにフォーカスさせるための補助関数である。
// Function to create a list item containing a link describing the error // that points to the appropriate form field function addError(strError, strFragment, objForm, strID) { var objAnchor = document.createElement('a'); var objListItem = document.createElement('li'); objAnchor.appendChild(document.createTextNode(strError)); objAnchor.setAttribute('href', strFragment); objAnchor.onclick = function(event){return focusFormField(this, event, objForm);}; objAnchor.onkeypress = function(event){return focusFormField(this, event, objForm);}; // If strID has a value, this is the first error in the list if (strID.length > 0) objAnchor.setAttribute('id', strID); objListItem.appendChild(objAnchor); return objListItem; } // Function to place focus to the form field in error function focusFormField(objAnchor, objEvent, objForm) { // Allow keyboard navigation over links if (objEvent && objEvent.type == 'keypress') if (objEvent.keyCode != 13 && objEvent.keyCode != 32) return true; // set focus to the form control var strFormField = objAnchor.href.match(/[^#]\w*$/); objForm[strFormField].focus(); return false; }
以下は事例のフォーム用 HTML である。
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "https://www.w3.org/TR/html4/strict.dtd"> <html> <head> <title>ECMAScript Form Validation</title> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <script type="text/javascript" src="validate.js"></script> </head> <body> <h1>Form Validation</h1> <form id="numberform" method="post" action="form.php"> <fieldset> <legend>Numeric Fields</legend> <p> <label for="num1">Enter first number</label> <input type="text" size="20" name="num1" id="num1"> </p> <p> <label for="num2">Enter second number</label> <input type="text" size="20" name="num2" id="num2"> </p> </fieldset> <p> <input type="submit" name="submit" value="Submit Form"> </p> </form> </body> </html>
この例はクライアントサイドスクリプトに限定しているため、サーバーサイドの検証によって補完されるべきである。例では、クライアントサイドスクリプトが利用できるときのエラーメッセージの作成に限定される。
このコードの実装サンプル: フォームの検証
参考リソース
この参考リソースは、あくまでも情報提供のみが目的であり、推薦などを意味するものではない。
- HTML 4.01 The Document Object Model, More methods from Webreference.com
- Accessible Forms using WCAG 2.0
検証
手順
動的に新しいコンテンツを作成するページに対して:
- ソースコードを検証して、新しいコンテンツが document.write()、innerHTML、outerHTML、innerText 又は outerText を用いて作成されていないことを確認する。
解説の訳注で示した document.write()
及び innerHTML
に加えて、outerHTML
は 2021 年現在 DOM Parsing and Serialization 仕様で定義されている。また、innerText
及び outerText
は HTML§3.2.7 The innerText and outerText properties で定義されている。
期待される結果
- 1. の結果が真である。