その昔、WEBマーケティング会社でブラウザ対応のSaasツールを大量生成して、マーケティング業界でブイブイ言わせていた時代に、今では"EFO"(EntryFormOptimization)という今では当たり前になっているB2Bツールを世界で初めて作ったのがこの会社(僕)ですが、その時のHTMLのバージョンは4で、IEのバージョンは6でした。
IEの最も寿命の長かったバージョンだったために、基本的にはWEBサービスはIE6を基準に作っていた時代です。
※当時はまだGoogleChromeブラウザも無かった時代です・・・
色々な企業の入力フォームをこの会社のEFOツールのjavascriptタグを1行挿入すれだけで、事前に設定されたEFO機能が発動するというサービスだったのですが、当時はW3Cに準拠していない企業ホームページも多く、「同一ID使用問題」やら、「閉じタグの無いHTML構成」やら、「同一name値問題」などなど、数多くの経験をさせてもらい、こうしたトラブル対応に対する免疫がついたと言ってもいいでしょう。
その中に「name=name問題」というのがあって、当時まだjavascriptに明るくなかった僕としては、非常に長期間この問題に悩まされていたのですが、最近では非常にあっさりと解決できたので、そうした問題点と解決方法などを、備忘録として残しておきたいと思います。
同一ID使用問題
WEBページを表示するHTMLの中では、タグに色々な属性を付けて管理したり、cssでコントロールすることが可能ですが、class属性やID属性などの基本属性でよく使う人も多いでしょう。
この時に、ID属性は、表示するページ内で1箇所しか使えないというHTMLの当初から存在するルールがあるのですが、一流の大手企業ホームページでも、こうしたルールを破っているサイトも、実は数多くあります。
※ページ変更のタイミングで修正されているものもありますが、CMS自体でその仕様になっていて、致し方なく使っている企業もあるようですよ。
w3cのID属性についての説明ページ
https://w3g.jp/xhtml/dic/id
ID属性は、ユニークで且つ固定の値である必要に対して、class属性は、重複してもいい上、1つの属性に複数のclass名を半角スペース区切りで登録することが可能で、class名で対応したほうが、不意なトラブルが避けられるとして、今どきのデザイナーはIDは使わずにclass名のみで構成するのが流行りのようです。
ただ、何故ID属性がページ内で重複してしまうのかというと、企業ならではの理由があり、表示するページの基本構成はCMSで作られて、それぞれの表示部分に対して、企業内の担当者がついていたり、それに付随するガジェットやライブラリなどを導入している時に、それぞれが各々にHTMLを構築することが可能になります。
この時に、ベンダープレフィックスルールなどを定めておかない場合は、簡易なID名称にしてしまうと、かんたんに重複IDが生まれてしまうという事になります。
大きな会社ほど重複IDが多いのもなんとなくうなずけますが、こうしてホームページの内容をみてその企業のルール化の乏しさなど、プロファイリングすることも可能という事を覚えました。
閉じタグの無いHTML構造問題
これも比較的ある内容ですが、HTMLには、閉じタグが必要なタグと必要のないタグがあります。
HTMLに触りなれている人であれば、さほど違和感を感じないのですが、初心者などにとっては、閉じる必要のあるなしは、非常にめんどくさい仕様のようです。
XMLが生まれた経緯も、HTMLのこうした少し乱暴な仕様が影響しているとかしていないとか・・・
IDEなどを使ってコーディングをしている場合は、閉じタグを付け忘れるという問題は限りなく少ないのですが、テキストエディタや、CMSの入力フォームだけでコーディングしていると、一流のプログラマーであっても、閉じ忘れがある場合があります。
ちなみに、HTMLでタグを閉じ忘れると、場所によっては、ページ全体が大幅に崩れたり、下方に設置されているscriptタグなどが正常に読み込まれずに、大きな生涯に繋がる可能性も大きいです。
改めて、起動チェックなどの工程を設けて、こうしたミス対応をしているかどうかも企業ルールのクオリティが問われるところですね。
name=name問題
これは、お問い合わせやECサイトの購入ページなどで度々見かける記述ですが、個人情報入力をするinputタグのname値に、「名前」の箇所を「name="name"」という属性をセットしているページがたまにあります。
他にも、formタグのname値に"<form name='form'>"と設置しているケースなども同じなのですが、DOM構造の階層呼び出しの際に大きな影響が出てきます。
一般的にEFOでそれぞれの入力フォームにアクセスして書かれている文字列のチェックを行う際には、以下のように行います。
var fm = document.forms[0];
if(fm.input_1.value == ""){
alert("error");
}
input_1というname属性を持った入力フォームがブランクの場合にアラートを出すというだけの内容ですが、formは、ページ内に存在する順番、inputへのアクセスはname値を階層アクセスするというのが、javascriptのセオリーになっています。
これは、formタグがページ内に1つしか存在しない場合であれば、何も問題ないのですが、検索フォームなどが存在するだけで、formタグが複数になり、順番がずれ込んでしまう恐れがあるため、formもname値を元に確定アクセスしなければいけなくなります。
その場合は、以下のような記述でアクセスできるのですが・・・
document.forms."formタグのname値".name
これでformタグのname値を取得することができます。
次に、inputタグのname値を取る場合は以下のようになります。
document.forms."formタグのname値"."inputタグのname値".name
ここで、inputタグのname値に"name"と登録されている場合は、どうなるでしょうか?
# formタグのname値
document.forms."formタグのname値".name
# inputタグへのアクセス
document.forms."formタグのname値".name
# inputタグのname値
document.forms."formタグのname値".name.name
分かりますかね?「formタグのname値」と「inputタグへのアクセス」が全く同じ記述になってしまいます。
この場合、inputタグへのアクセスが優先されて、結果formタグのname値が取得できない状態になってしまいます。
console.log(document.forms.form[0].getAttribute("name"));
この場合は、上記の情報で、name値を強制的に取得することが可能なのですが、できればname属性に"name"という値は使わないほうがいいという予約後のような扱いにしないといけないですね。
HTMLにおけるjavascriptは、こうしたDOM構造のアクセスと内部配列、属性などが多数存在するので、その特性をよく把握しておく必要があるという事ですね。
0 件のコメント:
コメントを投稿