| |
文法に関するメモ
ブラウザ制御に関するメモ
JavaScriptの文法に関するメモ
タイマーを使う
<html><body>
<script>
var id;
function timeoutCmd(){ alert("5秒経過しました。" + id); }
function startTimer(){ id = setTimeout("timeoutCmd()", 5000); }
</script>
<input type=button value="OK" onClick='startTimer()'>
</body></html>
|
タイマーをセットするには、setTimeout()関数を使います。
この関数はタイマーIDを返すので、途中でキャンセルするには、
clearTimeout(id)関数をコールします。
なお、何度も繰り返し同じ処理をタイマーで呼び出す場合は、
setTimeout()の代わりにsetInterval()という関数が使えます。
JavaScriptのwith構文の使い方
function linkSubmit(url) {
with(document.menuForm){
action = url;
method = "POST";
submit();
}
}
|
左0詰する
2桁の左0詰は次のようにします。
function lpad2(s){
return ('00'+s).slice(-2);
}
|
3桁の場合も同様です。
return ('000'+s).slice(-3);
|
文字列に含まれる部分文字列を置き換える、または削除する
文字列のreplaceメソッドを使います。
var s2 = s1.replace(",", "");
var s3 = s1.replace(/,/g, "");
|
この例は、いずれもs1に含まれるカンマを削除しているものです。
上のように普通の文字列で指定すると、変換対象の文字列が2個所以上あった場合、
最初に出会ったものだけを置き換え(削除)の対象にします。
下のようにPerlのような正規表現を使い、後ろにgオプションを使うと、
カンマが何個あっても全て置き換え(削除)の対象になります。
文字列の末尾から文字を検索する
ある文字列の末尾から特定文字が現れる位置を探すには、lastIndexOf()を使います。
この関数は見つかればその位置(先頭が0)、見つからなければ-1を返します。
var path = "C:/the/path/of/file.txt";
var n = path.lastIndexOf("/");
if(n != -1){
var dir = path.substring(0, n);
// ...
}
|
ユーザ定義関数(function)の引数に省略時値(デフォルト値)を設定できる?
PHPと異なり、JavaScriptでは、
引数は省略できますが、代わりの省略時値を定義する文法はありません。
では省略したら何が渡されるのかというと、undefinedとゆうものが渡されます。
これは「param == undefined」や「typeof(param) == "undefined"」で検出できますから、
関数冒頭でその場合の値を補う処理を書けば、省略時値を定義するのに類することはできます。
英数字のみ全角と半角を変換する
製品名など、英数字だけの表記の揺らぎを吸収したいという要望もあります。
こんな感じでどうでしょうか。
<script>
var gChangedOnce = false;
function zentohan(str) {
return str.replace(/[A-Za-z0-9]/g, function(s) {
return String.fromCharCode(s.charCodeAt(0) - 0xFEE0);
});
}
function hantozen(str) {
return str.replace(/[A-Za-z0-9]/g, function(s) {
return String.fromCharCode(s.charCodeAt(0) + 0xFEE0);
});
}
function fl_changed(textObj){
if(gChangedOnce){ return; } // 一度変換済なので再処理しない
if(textObj.value.length > 0){
textObj.value = hantozen(textObj.value.toUpperCase());
gChangedOnce = true;
}
}
function fl_dbl(textObj){
if(textObj.value.match(/[A-Za-z0-9]/)){
textObj.value = zentohan(textObj.value);
} else {
textObj.value = hantozen(textObj.value);
}
gChangedOnce = true;
}
</script>
<form>
品名<input type="text" name="hinmei" onChange="fl_changed(this)" onDblClick="fl_dbl(this)" autofocus="1">
<input type="button" value="検索" onClick="alert('入力値は[' + this.form.hinmei.value +']')">
</form>
|
これは次のような動作をします。
- 品名欄に半角英数字を入力して別の欄に移ると、全角に変換します。
その際に小文字は大文字に統一します。
- 一度変換した後は、利用者が再び修正した際にも再変換はしません。
- 品名欄をダブルクリックするたび、全角と半角を切り替えます。
JavaScriptのブラウザ制御に関するメモ
リンクで前のページに戻る
JavaScriptを使って、次のように書けます。
<a href="javascript:history.go(-1)">前のページに戻る</a>
|
実際に試してみてください。
入力内容を確認するダイアログを出す
function fl_confirmAndSubmit(){
a = document.form1.input1.value;
result = confirm(a + "でよろしいですか?");
if(result){
document.form1.submit();
} else{
alert("キャンセルしました。");
}
return false;
}
|
これはtype="button"のボタンのonClickイベントに設定する例です。
フォームのonSubmitイベントに設定する場合は、
function fl_confirmAndSubmit(){
a = document.form1.input1.value;
result = confirm(a + "でよろしいですか?");
if(! result){
alert("キャンセルしました。");
return false;
}
return true;
}
|
このように、Submitを続行する場合は真を、キャンセルする場合は偽を返します。
マウスの右クリック禁止
document.oncontextmenu = function () { return false; }
|
CTRL+Rによる更新禁止
document.onkeydown = function () {
var keyCode = parseInt(window.event.keyCode);
if(window.event.ctrlKey && keyCode == 82){ return false; }
return true;
}
|
同様の方法でCTRL+N(keyCode=78)、CTRL+U(keyCode=85)なども禁止できます。
なお、ひとつ前の右クリック禁止もそうですが、Chrome等の開発者ツールの操作と
JavaScriptの知識のある人なら誰も解除できるので、完璧な方法ではありません。
そういえば、CTRL+Rを禁止するならF5キーも禁止しないと意味がありませんね。
F5キーのkeyCodeは116です。
ブラウザがIEモードかどうかを判定する
var agent = window.navigator.userAgent.toLowerCase();
if(agent.indexOf('msie') != -1 || agent.indexOf('trident') != -1) {
// IEモードです
}
|
文書形式(MIMEタイプ)の中には、IEモードなら文書をブラウザ内に表示しますが、
Edge/Chromeではダウンロードしてしまう物があります。
そういう場合、Edge/Chromeでは新規ウィンドウを開いても無駄なので、そういった判別にこのルーチンが使えます。
JavaScriptから別のJSを動的に読み込む
var script = document.createElement("script");
script.src = "/test/ext_func.js";
document.body.appendChild(script);
function f_MainFunc(){
var url = f_ExternalFunc() + "/test.html";
return url;
}
|
上の例ではJavaScriptから別のJavaScriptファイル ext_func.js を読み込み、
そのファイルに定義されている f_ExternalFunc() 関数を呼び出しています。
これにより、元のHTML文書に手を加えずに、処理の一部を複数のJavaScript間で共通化できます。
要素からクラス名を取り出すには
document.getElementsByClassName()は、クラス名から該当する要素を抽出する処理ですが、
先に要素を別の方法で取得していて、それのクラス名を取得するには?
クラスは、要素の属性(attribute)のひとつなので、「element.getAttribute("class")」で取得できます。
ポップアップで開いたウィンドウから親ウィンドウを操作する
/* 元のウィンドウのURLを変更します。 */
if(opener.closed){
alert("(元のウィンドウが閉じられています。)");
} else {
opener.location.href = "/the/path/of/newpage.html";
}
|
下はもう少し実用的な例の完全なHTMLです。まず元のウィンドウ側
<html><body>
<script type="text/javascript">
function openSelectWindow(){
window.open("win2.html", "selwin",
"toolbar=no,location=no,directories=no,status=no,"+
"menubar=no,scrollbars=yes,resizable=yes,width=200,height=200");
}
</script>
<form name="form1">
果物コード
<input type="text" value="" maxlength="10" size="15" name="fruitCode">
<input type="button" value="..." onClick="openSelectWindow()"><br/>
<input type="submit" value="決定">
</form>
</body></html>
|
そして、オープンされるウィンドウ(win2.html)のHTML。プルダウンから項目を選んで「決定」を押すと、
そのコードが元のウィンドウの入力欄に補完されて、ウィンドウが閉じます。
<html><body>
<script type="text/javascript">
function selected(fruitCode){
if(window.opener.closed){
alert("元のウィンドウが既に閉じられています。");
} else {
window.opener.document.form1.fruitCode.value = fruitCode;
}
window.close();
}
</script>
<form>
果物の一覧
<select name="fruitCode" size="5">
<option value="ORN" selected="1">みかん</option>
<option value="APL">りんご</option><option value="MEL">メロン</option>
<option value="PEA">桃</option><option value="GRP">ぶどう</option>
</select>
<input type="button" value="決定" onClick="selected(this.form.fruitCode.value)">
<input type="button" value="キャンセル" onClick="window.close()">
</form>
</body></html>
|
ポップアップウィンドウを開く簡単リファレンス
window.open("newpage.html", "newWindowId",
"toolbar=no,status=no,location=no,directories=no,menubar=no,
scrollbars=yes,resizable=yes,width=300,height=300");
|
サイズなどを指定した新しいウィンドウを開きつつ、そのウィンドウにPOSTメソッドでフォームをSubmitするには
・サイズなどを指定した新しいウィンドウにGETメソッドでフォームをSubmitする
・サイズなどは指定せず新しいウィンドウにPOSTメソッドでフォームをSubmitする
は両方とも簡単ですが、この2つが混ざるとどーうなっちゃうの?
まさにすごい奴らが手を組んだ(帰れ)
正解は、「先にその名前のウィンドウをwindow.open()で開いてから、Submitする」。
例はこんな感じです。
<form name="JumpToDetailInfoForm" action="/the/path/of/DetailInfo.jsp"
method="POST" target="NewSmallWindow">
<input type="hidden" name="customerCode"/>
</form>
<a href="javascript:fl_showDetail('012345')">012345</a><br/>
<script type="text/javascript">
function fl_showDetail(customerCode){
var formObj = document.JumpToDetailInfoForm;
window.open("about:blank", formObj.target, "width=400,height=300,status=no,toolbar=no");
formObj.customerCode.value = customerCode;
formObj.submit();
}
</script>
|
TEXTAREAのカーソル位置に文字を追加する(IE限定)
JavaScriptには、TEXTAREAの現在カーソルがある位置を知る標準的な方法は用意されていませんが、
IE限定なら、以下のリンクにある裏技(すげー大技ですね)で、実現することができます。
How can I insert text at the caret(cursor) position of a text field/text area?
そのページに掲載されている通りのサンプルはこちらです。
入力欄からフォーカスが離れると入力内容を英大文字に自動変換する
小文字の場合は toLowerCase() を同様に使います。
<input type="text" name="text1" onChange="this.value=this.value.toUpperCase()"/>
|
入力欄の末尾の文字の後ろにカーソルを設定する
業務システムで機械的に入力されるオペレータの方に、
よくこういう要望をされることがあります。
var obj = document.form1.text1;
var range = obj.createTextRange();
range.move('character', obj.value.length);
range.select();
|
なお、このrange.moveの2番目の引数に任意の数字を指定すれば、n文字目にカーソルを設定する、
ということもできます。
入力欄の値を選択状態(反転表示)にする
1つでもキーを押したくない高齢のオペレータの方からは、こういう要望もあります。
また別の要望として、バーコードリーダで値を読ませる際に、
選択状態にしておけば値を消しつつ別の値を読ませることができるから便利ということもありました。
var obj = document.form1.text1;
obj.select();
obj.focus();
|
入力文字数が一定に達すると自動的に次の入力欄にフォーカスする
こんな感じになります。まず、入力欄自身の最大文字数つまりmaxlength属性の値は、
getAttribute('maxlength')で取り出せます。
それで現在の入力文字数が最大文字数に達したとき、引数で指定した入力欄にフォーカスを移動させるのは簡単です
(下のf_checkTabMoveTo関数)が、次の入力欄を明示的に指定せず、
DOMツリーで「隣り」(次)にいる要素を探して自動的にそれに移ることも可能です
(下のf_checkTabMove関数)。
文書の進行方向に向かって隣りにいる要素はnextSiblingで取り出せます(前にいる要素はpreviousSibling)が、
すぐ隣にいる要素がいつでもどのブラウザで読んでもinput要素であるとは限らないので、
do〜whileでinput要素に出会うまでループしてから、focus()で移動します。
なお、onChangeイベントはフォーカスが離れた際に発生するものなので、この目的には使えません。
onKeyUpイベントを使います。
<script language="JavaScript">
function f_checkTabMoveTo(textObj, nextTextObj){
if(textObj.value.length == textObj.getAttribute('maxlength')){
nextTextObj.focus();
}
}
function f_checkTabMove(textObj){
if(textObj.value.length == textObj.getAttribute('maxlength')){
var o = textObj;
do { o = o.nextSibling;
} while (o && ! o.tagName || o.tagName.toLowerCase() != "input");
if (o != null) { o.focus(); }
}
}
</script>
<form>
入力欄1(1文字)<input type="text" maxlength="1" size="3" name="ran1" tabindex="1"
onKeyUp="f_checkTabMoveTo(this, this.form.ran2)">
入力欄2(5文字)<input type="text" maxlength="5" size="8" name="ran2" tabindex="2"
onKeyUp="f_checkTabMove(this)">
入力欄3(8文字)<input type="text" maxlength="8" size="12" name="ran3" tabindex="3">
<input type="submit" value="ok">
</form>
|
ラジオボタン・グループの選択された値を得るには(1)
複数のinput type="radio"のラジオボタンに、同じ"name"をつけると、
それらは自動的に排他な選択動作をします。
つまり、他の1つがチェックされると、
今までチェックされていた項目は自動的にチェックoff状態になります。
が、複数のうちどれが選択されているのかを取得する処理は、
うっかりしているとはまります。
<script>
function check(formObj){
var i;
for(i = 0; i != formObj.favorite.length; i++){
if(formObj.favorite[i].checked) {
alert(formObj.favorite[i].value + "が選択されました。");
break;
}
}
}
</script>
<form id="form1">
<input type="radio" name="favorite" value="Apple" checked="1" />りんご
<input type="radio" name="favorite" value="Orange" />みかん
<input type="radio" name="favorite" value="Melon" />メロン
<input type="button" value="OK" onClick="check(this.form)" />
</form>
|
上のように、面倒ですが1項目ずつループで回してcheckedプロパティで確認するのが正解です。
これを
if(formObj.favorite.value == "Apple"){
// ...
}
|
のように書けると大変嬉しいところですが、実はこれが書けないのが落とし穴。
ラジオボタン・グループの選択された値を得るには(2)
一方で、ラジオボタンがフォームの中にある場合は、次のように値をダイレクトフリャに取得したり設定したりできます。
<script>
var f = document.getElementById("form1");
// 選択されたラジオボタンの値を取得する
var selected_value = f.elements["favorite"].value;
// 値によってラジオボタンを選択状態にする
f.elements["favorite"].value = selected_value;
</script>
|
ActiveXを使ってローカルファイルの存在を判定する
MSIE限定の方法ですが可能です。
Internet Explorer(IE)でActiveXを使う場合は、「インターネットオプション」で
「スクリプトを実行しても安全だとマークされていないActiveX コントロールの初期化とスクリプトの実行」
を「有効」か「ダイアログを表示する」に設定する必要があります。
<script language="JavaScript">
var path = 'D:\\the\\path\\of\\document.txt';
var fso = new ActiveXObject('Scripting.FileSystemObject');
if(fso.FileExists(path)){
document.write("ファイルは存在します。");
} else {
document.write("ファイルは存在しません。");
}
</script>
|
Excelファイルを読み、指定したセルの値をTEXTAREAに格納する
SheetJSを使えば可能です。
ブラウザのセキュリティ設定もプラグインも拡張機能も不要でこんなこともできる。
いい時代になったものじゃのう…(急に老人口調)
このSheetJSはNode.jsなどのサーバ側でも、ブラウザ上のクライアント側でもプログラム自体は同じ書き方ができますが、
クライアント側にはセキュリティ上の大きな制約があります。
下記の例のように、利用者がinput type="file"要素で明示的に選択したファイルしか処理対象にできません。
したがって例えば、利用者がWebページを開いた瞬間に、プログラムで予めパスを指定しておいた、
職場の共有ファイルサーバやSharePointサイト上のExcelファイルを読んで内容を表示する、といった使い方はできません。
それはブラウザ操作ではなく、夜間処理などでNode.js等のサーバー側のプログラムとして実行し、
内容をJSON等に変換しておく対応が必要になります。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>Excelファイル読み込み</title>
<!-- 上側はIEモードに対応するためのPolyfill -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/core-js/3.30.0/minified.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/xlsx/0.18.5/xlsx.full.min.js"></script>
</head>
<body>
<input type="file" id="fileInput" />
<textarea id="textArea" cols="60" rows="5"></textarea>
<script>
document.getElementById('fileInput').addEventListener('change', function(event) {
const file = event.target.files[0];
const reader = new FileReader();
reader.onload = function(e) {
const data = new Uint8Array(e.target.result);
const workbook = XLSX.read(data, { type: 'array' });
const sheetName = workbook.SheetNames[0];
const worksheet = workbook.Sheets[sheetName];
const cell = worksheet['C3'];
const cellValue = cell ? cell.v : '';
document.getElementById('textArea').value = cellValue;
};
reader.readAsArrayBuffer(file);
});
</script>
</body>
</html>
|

(first uploaded 2002/10/18 last updated 2025/01/04, URANO398)
|