JavaScriptの数値計算誤差で悩む(図形の内外判定) [HTML/CSS/JavaScript]
地図上の任意の点があるある特定の範囲内かを判定するスクリプトを、「点の多角形に対する内外判定」をそのまま使用させて戴き、JavaScriptで実装しました。しかし特定の形状時のみ判定結果が間違う結果となることが判明。色々考えたが原因が不明、困ってしまって初心に戻り同じ計算をExcel表にて実施し、順番にJavaScriptとExcelの結果を比較することで、漸く原因が判明しました。"考えるより手を動かせ!"ですね。
【原因】
このif文の結果がExcelの結果と異なるために誤判定となることが判明
if(point.x < (polygon.v[i].x + (vt * (polygon.v[i+1].x - polygon.v[i].x)))){
右辺のvt * (polygon.v[i+1].x - polygon.v[i].x))が十分小さいと、計算誤差により情報落ちが発生してvt * (polygon.v[i+1].x - polygon.v[i].x))分が無くなってしまいif判定が逆転し内外判定に誤りが生じることが判明。
【対策】
数値計算JavaScriptライブラリの利用も考えたたが、とりあえず以下の方法にて対処しました。
if(point.x - polygon.v[i].x) < (vt * (polygon.v[i+1].x - polygon.v[i].x))){
そういえば、その昔数値計算の誤差で習ったような記憶が。。
【原因】
このif文の結果がExcelの結果と異なるために誤判定となることが判明
if(point.x < (polygon.v[i].x + (vt * (polygon.v[i+1].x - polygon.v[i].x)))){
右辺のvt * (polygon.v[i+1].x - polygon.v[i].x))が十分小さいと、計算誤差により情報落ちが発生してvt * (polygon.v[i+1].x - polygon.v[i].x))分が無くなってしまいif判定が逆転し内外判定に誤りが生じることが判明。
【対策】
数値計算JavaScriptライブラリの利用も考えたたが、とりあえず以下の方法にて対処しました。
if(point.x - polygon.v[i].x) < (vt * (polygon.v[i+1].x - polygon.v[i].x))){
そういえば、その昔数値計算の誤差で習ったような記憶が。。
Jqueryでtooltip(吹き出し)実装 [HTML/CSS/JavaScript]
WEB DBシステムのユーザビィティ向上のためこちらを参照にしてJqueryでtooltipを実装したときのメモ。
サンプル
1 | メニュー1 |
2 | メニュー2 |
3 | メニュー3 |
4 | メニュー4 |
//css部 .relative td { position:relative; } .hvr:hover { background: #deb3ba; width: 10em; } .dsp_tooltips { position: absolute; top: +1.5em; left: 0.3em; z-index: 9999; width:12em; padding: 0.3em 0.5em; color: #000000; background: #deb3ba; border-radius: 0.1em; } .dsp_tooltips:after { width: 100%; content: ""; display: block; position: absolute; left: 0.5em; top: -8px; border-top:8px solid transparent; border-left:8px solid #deb3ba; } //javascript部 $(function() { $(".hvr").on({ 'mouseenter':function(){ var text = $(this).attr('data_text'); $(this).append(''+text+''); }, 'mouseleave':function(){ $(this).find(".dsp_tooltips").remove(); } }); }); //html部
1 メニュー1 2 メニュー2 3 メニュー3 4 メニュー4
form入力値を英文字小文字(半角)から大文字に強制変換 [HTML/CSS/JavaScript]
WEB上の入力で英文字の大文字に限定したい場合がある。しかし小文字入力された場合再度入力を促すのもユーザビリティが良くない。そこで小文字で入力されても、Keyが押されたイベントで大文字に変換して入力formに戻すと大文字で入力されたように見える。このコード書いたときの備忘録。
実際のサンプル
//******* javascript部 function chkChra() { var dt = document.getElementById("dt").value; if(dt.match(/[^A-Za-z]/)) { document.getElementById("dt").focus(); return false; } dt = dt.toUpperCase(); document.getElementById("dt").value = dt; } //****** html部
連動プルダウンメニュー(Ajaxでサブメニューの値読み出し) [HTML/CSS/JavaScript]
連動プルダウンメニューをAjaxで実装した時の備忘録。
カテゴリpulldownメニューの変化でAjaxでPHPの宛先取得を呼び出し、宛先を戻値で受け取りinnerHTMLでhtmlの宛先select部に書き出す。
// ******** javascript部(カテゴリのPulldownメニュー変化で呼び出される) function getAtesaki() { var category = document.getElementById("category").value; //選択値取得 //****ajaxでget_atesaki.php呼び出し $.ajax({ type: "POST", url: "get_atesaki.php", data: {"category": category}, success: function(res) { // res: ","区切り宛先リスト var htmlStr = ""; var list_atesaki = res.split(","); for(var i = list_atesaki.length; i--;) { htmlStr = htmlStr + " // ******** PHP部(get_atesaki.php) $sql = "SELECT 宛先 FROM t_宛先 WHERE カテゴリ='".$category."'"; $result = $link->query($sql); $atesaki_list = ""; while($row = $result->fetchArray()) { $atesaki_list .= $row['宛先'].","; } $atesaki_list = mb_substr($atesaki_list, 0, -1); echo $atesaki_list;
Input formの数値に電卓風カンマ追加 [HTML/CSS/JavaScript]
input formの入力データに電卓風に数値入力毎にその時の桁数で3桁毎にカンマを追加するスクリプトを作成してみた。Key入力されたイベント(onKeyUp)でtoLocateStringメソッドを使用してカンマを追加、その後入力フォームに戻すようにしている。
IE11,Chrome,Firefox,Operaで動作するが、Safariでは動作しなかった。
//javascript部 function insertComma() { var num = document.getElementById("dt").value; //入力データ取得 num = num.replace(/,/g,""); //カンマ削除 var dsp = new Number(num); document.getElementById("dt").value = dsp.toLocaleString(); //入力フォームに表示 } //html部
実際の動作
Javascript で日付の妥当性チェック [HTML/CSS/JavaScript]
これまで、WEB入力された日付入力の妥当性チェックを行うめ、各月の日数(28,29,30,31日)、閏年のチェックを自力でコーディングしていた。しかしDateクラスのオブジェクトから日付に関する年/月/日/曜日の値を取得するメソッドを使用すると簡単に日付のチェックができることが判った。実際のコードは以下。
//妥当性チェック関数 function chkDate() { var chkdate = document.getElementById("indate").value; //yyyy/mm/dd形式のチェック if(!chkdate.match(/^\d{4}\/\d{2}\/\d{2}$/)){ alert("日付の形式が違います。"); document.getElementById("indate").focus(); return false; } if(chkdate.getFullYear() == y &&chkdate.getMonth() == m-1 &&chkdate.getDate() == d){ // getMonthは0~11のためm-1とする return true; } else { alert("日付に間違いがあります。"); document.getElementById("indate").focus(); return false; } }
Button clickで項目の表示・非表示制御(clickで引数渡し) [HTML/CSS/JavaScript]
テーブル表示したとき、特定項目はクリックした時のみ表示したい場合がある(下図参照)。しかしclickした行の情報を引数として渡さなければ、idセレクターで指定することができない。この機能を実装したときの備忘録。
実際のサンプルはここ。
上が通常時、下がフォルダボタンをクリックしたとき。
Javascript部 HTML部
Rep.No | 発信日 | 件名 | 添付File |
---|---|---|---|
試16/1 | 2016/07/15 | 件名1 | 1 files <br> 1_1_test.pdf |
試16/2 | 2016/07/16 | 件名2 | 2 files 2_1_test.pdf 2_2_test.pdf |
ファイルのアップロードをボタン一つで実現 [HTML/CSS/JavaScript]
ファイルアップロードを行う場合ブラウザでファイル選択ボタンの配置が違い、下図のようにブラウザによって見た目が変わってしまう。
そこでファイル選択ボタンを非表示にして、アップロードボタンのみでにできるようなのでここを参照に作ってみた。
Javascript部 /*-------------------------------- ダミーボタンを押した時の処理 ----------------------------------*/ $(function(){ $('.submit_button11').click(function() { var key = $(this).attr("id"); $('#file_'+key).click(); return false; }); $('input[type="file"]').change(function(){ var files = this.files; var key = this.id; key = key.split("_"); var key_id = key[1]; uploadFiles(files, key_id); return false; }); }); /*------------------------------ アップロード処理 --------------------------------*/ function uploadFiles(files, key_id) { var fd = new FormData(); // ファイル情報を追加する fd.append("MAX_FILE_SIZE", 18000000); //Max 18MBに制限 fd.append("file", files[0]); fd.append("key_id", key_id); // Ajaxでアップロード処理をするファイルを渡す $.ajax({ url: './upload.php', type: 'POST', data: fd, processData: false, contentType: false, success: function(res) { var tg = res.split(","); var key_id = tg[1]; var error_msg = tg[2]; if(error_msg != "0") { alert("Error: "+error_msg); } location.href="./edit.php?rno="+key_id; return false; } }); return false; } PHP部(upload.php) $link = new SQLite3(DB_NAME); $id = $_POST['key_id']; $updir = "./data/"; $filename = $_FILES['file']['name']; if($_FILES["file"]["error"] <> UPLOAD_ERR_OK) { if($_FILES['file']['error'] == UPLOAD_ERR_FORM_SIZE){ $error_msg= 'File size 18Mbyteを超えています。'; } elseif($_FILES['file']['error'] == UPLOAD_ERR_NO_FILE){ $error_msg = 'Fileが選択されていません。'; } elseif($_FILES['file']['error'] == UPLOAD_ERR_INI_SIZE) { $error_msg = 'File size '.ini_get('upload_max_filesize') . 'を超えています。'; } else { $error_msg = 'その他のエラーが発生しました。'; } } else { $sql = "INSERT INTO t_file(rep_id, file_name) VALUES('".$id."','".$filename."') "; unset($result); $result = $link->query($sql); $last_id = $link->lastInsertRowid(); if(move_uploaded_file($_FILES['file']['tmp_name'], $updir.$last_id."_".$filename)==TRUE){ $error_msg = "0"; } else { $error_msg = "File Upload失敗"; } print $filename.",".$_POST['key_id'].",".$error_msg; exit; html部
複数iframeの処理件数を親frameで表示 [HTML/CSS/JavaScript]
親frameにiframeで複数の子画面を作り、そこでDB処理した処理件数を親frameに合計表示する必要がありコードを書いたときの備忘録。iframeでの処理結果はDBに反映し、処理結果は親frameからDB操作で取得可能としている。
iframe側複数(Javascript) //親Frameの件数表示functionを起動 // $henkou: 処理件数変化時->1、初期値t->0 $(function(){ var henkou = <?php echo $henkou; ?>; if(henkou == 1) parent.$.parentFunc(); }); 親frame側(Javascript) //iframe側から起動されるfunction (function($) { $.parentFunc = function() { /* ajaxで処理件数取得 */ var syain_no = <?php echo $kaiin_no; ?>; //Javascriptに会員番号渡し $.ajax({ type: "POST", url: "get_num.php", data: {"kaiin_no": kaiin_no}, success: function(res) { var dt_res = res.split(","); var num_n1 = dt_res[0]; var num_n2 = dt_res[1]; var num_n3 = dt_res[2]; var num_goukei = dt_res[3]; $('#i_n1').html(num_n1); $('#i_n2').html(num_n2); $('#i_n3').html(num_n3); $('#i_goukei').html(num_goukei); } }); }; })(jQuery); //HTML表示件数表示部 <sapn id="i_n1"><?php echo $n1 ?></span > //n1~$goukeiは親画面初期値 <sapn id="i_n2"><?php echo $n2 ?></span > <sapn id="i_n3"><?php echo $n3 ?></span > <sapn id="i_gouki"><?php echo $goukei ?></span > // get_num.php(処理件数の取得) // Ajaxで起動されechoで帰値渡し <?php // 処理件数取得部分略 echo $num_n1.",".$num_n2.",".$num_n3.",".$goukei; ?>
JavascriptでGET変数取得(URL?以降の文字列) [HTML/CSS/JavaScript]
ある理由によりLogin画面のファイル名をindex.htmlにしたい場合があった。機能としてはLogin情報を入力後、Login情報をチェックするPHPスクリプトに遷移。PHPスクリプトはLoginが有効な場合次の処理に遷移、無効な場合エラー情報をURLの後に?を付けてLogin画面に戻す。戻されたLogin画面はURLの後に?エラー情報がある場合はLogin画面にエラー情報を表示し再度入力を促す機能を有する。PHPで作成すれば簡単なスクリプトになるが、URLの?以降のGET変数をJavascriptだけで作成したときの備忘録。