■コピー&ペーストでJavaScriptのプログラムを貼付けると動かなくなるのはなぜ? Webサイト上には、たくさんのJavaScriptのサンプルや利用できるライブラリなどが公開されています。「あ、これ使いたいな」と思ってコピー&ペーストで持ってきて貼付けて使う人は多いと思います。貼付けるJavaScriptが1つの場合には、ちゃんと動いたのに、あれもこれもと2つ以上貼付けていくと動作がおかしくなったりエラーが発生することがあります。 ここでは、トラブルの原因とエラーの解決への方法を載せておきますので参考にしてください。 ■動かなくなる原因 JavaScriptプログラムを複数貼付けたりすると不具合が発生することがありますが、主に以下の原因によるものです。 (1)変数名の不具合 (2)関数名の重複 (3)タグID、名前の不具合 (4)スタイルシートの不具合 (5)HTMLの不具合 (6)ブラウザとOS依存による不具合 (7)その他 それでは順番に見ていきましょう。 【1】変数名の不具合 JavaScriptの変数には「ローカル変数」と「グローバル変数」の2種類があります。複数のJavaScriptプログラムを利用すると動作がおかしくなったりするのは「グローバル変数」の重複によるものです。例えば function prog1(){ n = 0; // 各種処理 } というJavaScriptプログラムを貼付け、さらに以下のJavaScriptプログラムも貼付けたとします。 function prog2(){ n = 100; // 各種処理 } よくみると、どちらのJavaScriptプログラムでも変数nが使われています。この変数nは先頭にvarがついていないので「グローバル変数」になります。グローバル変数は関数の外でも値を保持しているので、prog1で処理を行った後にprog2でnの値を変更してしまうとprog1での変数nの値が消えてしまい誤動作の原因になります。変数が関数内でしか使われていないのであれば以下のように先頭にvarをつけることで解決することができます。 function prog1(){ var n = 0; // 各種処理 } function prog2(){ var n = 100; // 各種処理 } 変数名の不具合のほとんどは、このようにすると解決することができますが、両方で同じ名前のグローバル変数が使われている場合には、どちらかのグローバル変数名を変更する必要があります。エディタなどの検索置換機能で処理すれば良いでしょう。 変数名の不具合は、これ以外にもあります。これは自分で作成している場合におこってしまうトラブルの1つです。以下のサンプルを見てください。 function prog1(){ n = 0; // 各種処理 } function prog2(n){ n = n * 2; // 各種処理 } prog1ではグローバル変数nが使われており、prog2では関数の引数として使われています。この場合、関数の引数はローカル変数として扱われるためprog2関数内でグローバル変数として処理してしまうという勘違いが発生します。グローバル変数として扱っているのであれば引数にグローバル変数名を使ってはいけません。上記のサンプルは以下のようにする必要があります。 function prog1(){ n = 0; // 各種処理 } function prog2(){ n = n * 2; // 各種処理 } 【2】関数名の重複 JavaScriptでは同じ関数名が定義されていると一番最後に定義したものが有効になります。つまり貼付けたJavaScriptプログラムに、たまたま同じ名前の関数名が存在すると後から定義されたものが有効になるためプログラムの動作がおかしくなってしまうわけです。これを防ぐには同じ名前の関数があるかどうかエディタなどで検索して処理します。 利用するJavaScriptプログラムが外部ファイルである場合には上記のエディタで検索するのは難しくなります。このような場合はtypeof()という命令を利用して関数が定義されているかどうか調べることができます。 function abc(){ alert("abc"); } alert(typeof(abc)); alert(typeof(def)); 関数が定義されている場合にはfunctionという文字を返します。定義されていない場合にはundefinedになります。このようにして調べると関数が重複しているかどうか判別できます。 また、関数名の重複以外にも注意しないといけないのは関数名と変数名の重複です。JavaScriptでは以下のように関数を定義した後に関数名に値を代入することができてしまいます。 function abc(){ alert("abc"); } alert(typeof(abc)); abc=123; alert(abc); 実行すると123がアラートダイアログに表示されます。つまり定義した関数が消えてしまうことになりエラーが発生することになります。関数名が重複しているか、変数名が重複しているかどうか調べるのも重要です。 【3】タグID、名前の不具合 DynamicHTML、DOMを利用したプログラムの場合にタグのIDと名前が問題になることがあります。まず、タグのIDがついていないとエラーになってしまうものがあります。この場合、プログラムで使われているタグIDに合わせてHTMLのタグIDも定義する必要があります。タグの種類も合わせる必要があります。多くの場合、DIV, SPAN, IMGなので、ここを重点的にチェックすると良いでしょう。 タグIDはページ内で同じ名前のものがあると不具合が発生します。タグのIDはページ内で唯一、そのタグでしか指定されていないことを確認してください。以下のようなものは駄目です。 <div id="AB"></div> <div id="AB"></div> ←同じ名前のIDになっている! タグID以外にタグのnameも重要です。意外と多いのが「日本語で名前を付けた」もので、日本語を使ってしまうとブラウザによっては動きません。(というかほとんどのブラウザでは動かない) 日本語をやめて英数字の組み合わせにする必要があります。 <input type="text" name="年齢"> ←nameが日本語になっている! 名前に関してはIDと違い重複しても良い場合と悪い場合があります。IMGタグでの名前の重複は駄目ですが、フォームのラジオボタンはラジオボタングループとして定義、利用されるため同じ名前になっても問題ありません。 <img src="xxx.gif" name="IMG1"> <img src="xxx.gif" name="IMG1"> ←nameが重複している! <input type="radio" name="grp1"> <input type="radio" name="grp1"> <input type="radio" name="grp1"> (これらのラジオボタンの場合は重複していても問題ない) 【4】スタイルシートの不具合 スタイルシートで定義されているIDとタグのIDが不一致または重複して定義されていると不具合が発生します。スタイルシートが別ファイルで指定されている場合は要注意です。ページレイアウトとJavaScriptプログラムでのタグのIDが不一致である場合には期待どおり動きません。このような場合はJavaScriptプログラムをスタイルシートに合わせるか、スタイルシートとHTMLタグのIDなどを合わせるかする必要があります。場合によっては、全体を作り直すかあきらめることも考慮すべきです。 単純なものなのにスタイルシートが定義されていないために不具合が発生することがあります。例えば画像を動かす場合に <img src="xxx.gif" name="ABC"> とHTMLで指定されていてスタイルシートが定義されていない場合、JavaScriptプログラムには問題がなくエラーも発生しませんが、肝心の画像は動きません。これは以下のようにスタイルシートを指定する必要があります。 <img src="xxx.gif" name="ABC" style="position:absolute;top:0px;left:0px;"> topとleftは最初に表示される位置を指定しておきます。見せたくない場合には-500などのマイナス座標を指定します。また、座標系でabsolute以外の指定では期待通り動かないことがあります。HTMLタグ内で指定するのが分からない場合にはJavaScriptプログラムで座標系をabsoluteにしてしまう方法もあります。この場合は以下のようになります。 オブジェクト名.style.positoon = "absolute"; スタイルシートをタグ内でなく別ファイルや<head>内で定義している場合にも、期待通り動作しないことがあります。主な原因としてはtopとleftが指定されていないために発生します。この2つは必ず定義するようにしてください。 座標系と位置を指定してもwidth, heightを指定しないとフィルタ機能を利用したプログラムの場合、期待通りに動作しないことがあります。フィルタ機能を利用している場合には座標系と位置、幅の3つを指定してください。また、Windows 2000の場合にはフィルタ機能で障害(半透明合成、α合成)が発生することがあります。サービスパックを入れるか、OSを再度インストールするとなおります。 【5】HTMLの不具合 JavaScriptプログラムでフォームや画像などで「参照番号」を利用している場合にはHTMLタグの出現順番が問題でエラーになることがあります。この場合にはHTMLタグの出現順番を変更するかJavaScriptプログラムで参照番号を指定している部分を変更する必要があります。 JavaScriptプログラムで参照番号を指定する場合は以下のようになります。 document.forms[参照番号].elements[参照番号] document.forms[参照番号][参照番号] document.images[参照番号] 他にもありますが、参照番号を使って処理するものの多くが画像とフォームなので上記の書式を見つけ出して参照番号部分を書き換えます。参照番号ですがHTMLタグで最初に出てきたものが0番になります。例えば以下のようなHTMLがあるとしましょう。 <html> <head> <title>Sample</title> </head> <body> <img src="xxx.gif"> <img src="yyy.gif"> <hr> <img src="zzz.gif"> </body> </html> ここで<img>タグのxxx.gifはdocument.imagesでの指定では0番になります。これはimgタグでは一番最初に出現しているからです。yyy.gifは1番になり、zzz.gifでは2番になります。imgタグの間に他のタグが入っても関係ありません。JavaScriptでxxx.gifのimgタグの指定は以下のようになります。 document.images[0] うまく動かない場合には、このような部分を見つけ出して数字部分を変更します。変更する場合には document.images[5] のように単純に数字部分を直すよりも以下のように一度グローバル変数を定義して指定するのがベストです。この方が間違ったときに修正が簡単になるためです。 gKF_imgNo = 5; // この間にいろいろプログラムが入る document.images[gKF_imgNo + 0] グローバル変数ですが、なるべく変数名の衝突(重複)をさけるため先頭に小文字のgをつけた後に自分のイニシャルやアカウント名などをつけてアンダーバーで区切ってから何に利用している変数なのかを指定します。 参照番号以外ではタグが存在したいためにエラーになったり、プログラムが想定している「タグの入れ子(ネスト)」になっていないために不具合が発生することがあります。例えば <div id="a1"> </div> <div id="a2"> </div> でなく以下のように入れ子を想定している場合があります。 <div id="a1"> <div id="a2"> </div> </div> プログラムが、どのようなHTMLタグを想定しているかを調べてから使うのが良いでしょう。 【6】ブラウザとOS依存による不具合 JavaScript最大の難関とも言えます。対応OSとブラウザと動作するバージョンが明記されていない場合は疑ってかかるべきです。Webサイトにある多くのJavaScriptプログラムは以下の4つに分けることができます。 (1)Windows版のInternet Explorer 4以降用のもの (2)Document Obejct Model (DOM)に従っているもの (3)ECMA Script標準のもの (4)その他 ほとんどが(1)になります。裏を返すとWindows版Internet Explorer以外のブラウザでは障害が発生することになります。例えばWindows版Internet Explorer 5で作成されたプログラムをMac版のInternet Explorer 5で動作させようとしても動かないことがあります。名前もバージョンも同じなのにOSが違うので動かないのです。実際は名前は同じですが別のものなので動かないと言えます。この場合には、素直にあきらめるかMacintoshを購入しチェックするか、持っている人に頼んで調べてもらうしかありません。Macintoshの場合にも同様のことが言えます。Mac版Internet Explorer 5で動作するプログラムがWindows版のInternet Explorer 5で動作するわけではないためです。Mac版の場合にはマイクロソフト社が発売しているVirtual PCを購入することで様々なWindows環境およびUNIX環境での動作を同時にチェックすることができます。 (2)のDOMに従っているプログラムの場合は、DOMが利用できる多くのブラウザで動作します。Windows版Internet Explorer 5以降、Macintosh版Internet Explorer 5、Netscape 6以降、Safari、Opera 7以降などです。ただし、Windows版のみの命令を使用してしまっている場合には他のブラウザでは動作しないのでプログラムを書き直す必要があります。 (3)これはECMA Script標準なのでNetscape 4以前など、かなり古いブラウザをのぞいて、ほぼ問題なく動作します。しかし、Webサイトにはほとんどありません。というのもブラウザ固有の機能やDOMなどが利用できないためです。その代わり、ブラウザ以外でもFlashやAcrobat (PDF)、PhotoshopやIllustratorなどのアプリケーションで利用することができます。 (4)その他というのは、Netscape 4や3など、かなり古い時代に作成されたものです。これに関してはフォームやロールオーバーなど一部をのぞいて動作しない場合が多くあります。注意して使うべきです。ただ、昔の場合は複雑なものではないため、そのまま動いてしまったりタグの名前を修正する程度で動作することがあります。 ブラウザ依存は避けがたいもので結局は、いろいろな環境で動作テストをするしかありません。また、Windows版のInternet Explorer 6のようにDOCTYPE宣言で動作がかわってしまうものもあります。JavaScriptでブラウザ判別処理を行っていてもOperaやSafariなどのようにInternet Explorerだよ、というフリをしたりNetscapeのフリをしたりする(詐称する、偽る)ブラウザもありますから、この点に関してもブラウザを振り分けて処理するものであっても注意が必要です。 【7】その他 自分のブラウザの環境設定によって正しく動作しない場合もあります。例えばクッキーへの書き込みを禁止していたりするとクッキー関連のプログラムは正しく動作しません。また、Safariなどで独自のスタイルシートなどを定義したりして広告ブロックしているような場合も、期待通りに動作しなくなることがあります。 これ以外でもノートンインターネットセキュリティなどでの広告ブロックを利用するとサーバーからのデータに勝手にJavaScriptプログラムが埋め込まれてしまい期待通りに動作しないことがあります。 自分のローカル環境では動作したのにサーバー上にアップロードしてから確認すると動かない場合もあります。特に広告を自動挿入するプロバイダの場合には要注意です。画像の参照などが崩れてしまったりして動作がおかしくなることがあります。 JavaScriptプログラムが動かなくなる原因は様々です。汎用性を持ったライブラリであっても注意する部分はたくさんあります。DreamweaverやHome Page Builder、Adobe GoLiveなどアプリケーション側で用意されているもので実現できるのであれば、それらを利用する方が速度は犠牲になりますが、ある意味安心ではないかと思います。逆に自分で勉強して習得してしまえば、自作した方が早いこともありますし、作成ソフトと使い分けることもできます。困ったらJavaScript掲示板などを利用して見るのも手でしょう。 2004 Copyright 古籏一浩/[email protected] |