Situation

iPhone Safariを使うときにあるInput boxで何か入力後”return”キーのkeydownイベントをキャッチして、何かしらのアクションを行いたい、のが目的です。よくあるのがreturnキーでformをsubmitしたり、ボタンクリックのアクションを行ったり、キーボードを隠したりするところですかね。

Keydown event

*13</em>という数字がreturnキーのkeydown時のコードです。実はJavascript経験がある方ならすぐ分かると思いますが、13Enterキー*のコードでもあります。

もう一つのTipはキーボードを隠したいときはjQueryのblur()を使えばOKです。

参考:http://stackoverflow.com/questions/5932317/how-to-capture-the-keyboard-return-event-on-iphone-browser

coffee-scriptをMacportsを使ってインストールし、TextMateのcoffee-script bundleでコンパイルするメモです。 注意すべきなのはたとえターミナルでcoffeeが実行できても、TextMateはPATHをインクルードしないので(インクルードしているのは/usr/binらしい)、/usr/binにcoffeeのシンボリックを作る必要があります。 またcoffee-scriptをコンパイルするにはnodejsとnpm(Node Package Manager)が前提条件となるため、それらのインストールも必要です。

これでtextmateでcommand + Bでコンパイル後のJavascriptが表示できるようになります!

#javascript #jquery

jQueryのappendやafterは全部DOM Manipulation、つまりDOM操作のメソッドであります。どう違うかは下記ソースコードを見るのが一番速いでしょう。

append(prepend,appendTo,prependTo)は要素内に、子供要素として貼り付ける

$('<span>span text</span>').appendTo(".chapter");

<div class="chapter"> ... </div>

組み立てた結果:

<div class="chapter">
	...
	<span>span text</span>
</div>

append、appendToは最後の子供要素として、prepend、prependToは最初の子供要素として挿入する感じです。

after(before,insertAfter,insertBefore)は要素の外、つまり同一のレベルで兄弟要素として貼り付ける

$('<span>span text</span>').insertAfter(".chapter");

組み立てた結果:

<div class="chapter">
	...
	<span>span text</span>
</div>

htmlタグがなければ無効

$('some text').appendTo(".chapter");

htmlに何の変更もないです。

#javascript #snippet
// 数値を日本円表現にフォーマット。
// 例:12345 -> 12,345
num2Currency = function(obj) {
  // 画面項目の値
  var str = obj.value;
  var num = new String(str).replace(/,/g/"");
  while(num != (num =num.replace(/^(-?\d+)(\d{3})/,"$1,$2")));
  obj.value = num;
}

// 日本円表現を数値にフォーマット。
// 例:123,45 -> 12345
currency2Num = function(obj) {
  var str = obj.value;
  var num = str.replace(/,/g,"");
  obj.value = num;
}
#javascript

今まで全然気付かなかったんです、 JavascriptのArrayにはdeleteみたいなAPIがないことに。 配列の要素をindex指定で削除したい場合は代わりにsplice関数を使います。

splice関数

とほほからのレファレンスでは

array.splice(start, n, e1, e2, …) (N4) 0 から数えて、start 番目から n 個の要素を削除し、その代わりに e1, e2, …を値とする要素を埋め込みます。戻り値は JavaScript のバージョンによって異なります。

var xx = new Array("A", "B", "C", "D", "E", "F", "G");
xx.splice(2, 3, "c", "d", "e");   // "C", "D", "E" が小文字になります

indexで配列の要素を削除するには

myArray.splice(index, 1);

indexは削除する要素のindex、1はこの一つだけを削除する意味で 他のパラメータはいらないです。 またsplice後は配列そのものが変更されます。

#javascript

スクロールバーを最下部に移動するJavascriptです。

普通のJavascriptで書くと

function goBottom(targetId) {
    var obj = document.getElementById(targetId);
    if(!obj) return;
    obj.scrollTop = obj.scrollHeight;
}

完全にjQueryで書くとこんな感じ

function goBottom(targetId) {
  var target = $("#" + targetId);
  $(window).scrollTop(target.offset().top);
}

これ以外はhiddenのinput項目を最下部に置いといて、 それをfocusするような技もありけど、、

#javascript

面白いかと思ったのでメモしときます。

普通の書き方

var rows = document.getElementsByTagName('tr');

for( var i = 0; i < rows.length; i++ ) {

   rows*i*.className = 'newclass';

   rows*i*.style.color = 'red';
  ...
}

効率のいい書き方

var rows = document.getElementsByTagName('tr');

for( var i = 0, row; row = rows*i*; i++ ) {

    row.className = 'newclass';

    row.style.color = 'red';
    ...
}

参考サイト:http://www.javaeye.com/topic/455376

#javascript

JavaをやってからJavascriptを触ったので、 Javascript変数にブロックレベルのスコープがないことにビックリしました。 if文ブロックか、forループブロックか関係なく、 function内に定義された変数は全て同じスコープ:functionのスコープになります。

例えば

function test(o) {
    var i = 0;                      // i is defined throughout function
    if (typeof o == "object") {
        var j = 0;                  // j is defined everywhere, not just block
        for(var k=0; k < 10; k++) { // k is defined everywhere, not just loop
            document.write(k);
        }
        document.write(k);          // k is still defined: prints 10
    }
    document.write(j);              // j is defined, but may not be initialized
}

変数kとjはそれぞれif文のブロック、forループのブロック内に定義されたが、 実はfunctionのスコープとなりfunction内ならどこでも参照できます。

これをしっかり理解しないと以下のようなミスが起こしやすいです。

var scope = "global";
function test() {
    alert(scope);         // Displays "undefined", not "global"
    var scope = "local";  // Variable initialized here, but defined everywhere
    alert(scope);         // Displays "local"
}

test();

一番目のalertは”global”だと思ったらこの記事を読む価値はあるでしょう。 一番目のalertは”undefined”を表示します。 なぜならさっき言ったように変数のスコープはfunction内に跨るのです。 varで宣言する位置、順番と関係ありません。

ここではfunction内で同じ名前でscopeという変数が宣言され、 “global”の値を持つグローバル変数は上書きされました。 そして一番目のalert時のscopeは初期化されていないため、undefinedとなってしまいます。

上記のコードを書き換えると以下と同じです。

function test() {
    var scope;       // Local variable is declared at the start of the function
    alert(scope);    // It exists here, but still has "undefined" value
    scope = "local"; // Now we initialize it and give it a value
    alert(scope);    // And here it has a value
}

誤解を招かないように変数の宣言はfunctionの先頭に置くのが大事ですね。

#javascript

window.open()で新規開いた小窓ウィンドウで親ウィンドウのdocumentを取得するには 下記のプロパティを使います。

window.opener.document

これで親ウィンドウの値を取得するだけではなく、 値を編集することもできます。

例えば下記のコードは親ウィンドwのフォーム内のテキストをAAAに変更します。 新規開いたページに記述します。

window.opener.document.FORM1.TEXT1.value = "AAA";

参考サイト

とほほのJavascriptレファレンス:ウィンドウオブジェクト

#javascript

FirebugのJavaScript、HTML、CSSをシンタクスハイライトするアドオンです。

firewindow

ダウンロード

FireRainbow Download

機能概要

  • Mixed syntax highlighting powered by CodeMirror
    • Javascript
    • HTML
    • CSS
  • Advanced features:
    • Color theme can be modified using Firebug’s CSS panel
    • Highlighting is applied incrementally (good performance)
    • Color themes available on GitHub

追記

今まで使ったところブレークポイントが付けない不具合がありました。 不具合発生時、firebug内のソースがハイライトしてないので疑いがあると判断し、 いったんマウスホイルを一回回すとソースはハイライトされブレークポイントもつけるようになりました。 これで一応回避できます。

#javascript

テキストボックスの文字を選択された状態にする方法とその解除方法です。 IEの場合selectボックスにselect()関数を使うとJavaScriptエラーになります。 Firefoxは大丈夫です。

function selectFocusText(element){
	// for IE
	if (element.nodeName == "SELECT") return;
	element.select();
};

function unselectFocusText(){
	// for IE
	if (document.selection) {
		document.selection.empty();
	// for Firefox
	} else if (window.getSelection) {
		window.getSelection().removeAllRanges();
	}
};
#javascript

ここが危ない!Web2.0のセキュリティ:第1回 Ajaxとクロスサイトスクリプティング|gihyo.jp … 技術評論社の勉強メモ&実験です。

実験

あるJavaScriptの拡張子をcsvに変更してSCRIPTタグでそれをインポートするHTMLを用意します。

そのJavaScriptを実行しようとするとIEのデフォルトセキュリティオプションでは、

ファイルのダウンロードダイアログが出ます。

Firefoxは拡張子がcsvにもかかわらずちゃんとJavaScriptと認識してそれを実行します。

原理

CSVファイルは単にカンマで区切られたデータですので,スクリプトは実行されないはずです。

Internet Explorerの仕様にセキュリティ設定に「内容によってファイルを開く」という設定ががあります(図2)。

これは,Internet Explorerがファイルの中身を見て,その中にHTMLっぽい文字列が含まれていればHTMLだと判断するということを意味しています。このため拡張子やレスポンスに含まれるContent-Typeヘッダとは関係なく,外部から参照可能なファイルにはクロスサイトスクリプティング対策が必要であるということになります。

一方,Firefoxの場合はレスポンスのContent-Typeヘッダを見て判断しますので,ファイルの中身が何っぽいのかを気にする必要はありません。

http://gihyo.jp/dev/serial/01/web20sec/0001?page=2

この観点からはIEのほうがセキュリティの面で高いと見られます。

#javascript

現象

FirebugでJavaScriptをデバッグしようとするとこんなエラーになりました。

``` Failed to load source for sourceFile top-level http://sample.com/jquery.js script.tags( X| 1094 1095 ... ```

環境

  • Firefox : 3.5.5
  • firebug : 1.4.5

調査

ぐぐって見ましたが、いい回答が見つかりませんでした。

同じバグにあった方のブログでのやり方で、

firebugを1.3.0に戻してもダメでした。

さらに1.3.3ではこの問題が解決されたと、firebugの公式サイトの回答がありました。


結局は..

エラーとなるプロジェクトを丸ごとTomcatサーバに置いたら、firebugで普通に見れました。

なぜかははっきり分かりませんが、この同じプロジェクトをずっとローカルで開発してきて、

firebugも全然問題なく使ったから、やたらおかしいです。

#javascript

argumentsは配列じゃないため、配列のメソッドは

使えません。ということは本を読んだとき当たり前だと思ったんですが、

実際コードに落としたときは

自然とargument.slice()を書いちゃいました。

argumentsで配列のメソッドを使うには

Array.prototype.<配列のメソッド>.call(arguments,<パラメータ>)</p> ```js Array.prototype.slice.call(arguments, 2) ```

上記の意図としてはarguments.slice(2)の表現に近いです。

argumentsはarray-likeオブジェクト

ここでちょっとargumentsの基本知識を復習します。

length属性もあるし、[]でindex指定のオブジェクトを参照できますけど、

argumentsは配列に似ているオブジェクトだけです。

予約語

Technically, argumentsは予約語ではないですが、

予約語として認識してよいです。

つまりargumentsという変数は作成しないでってことです。


```js function foo(x){ alert(x); var arguments; arguments[0] = null; //xの値が変更されちゃう alert(x); // null が出力される } ```
callee Property

Refers to the function that is currently being executed.

今実行中のファクションを参照しています。

```js function(x) { if (x <= 1) return 1; return x * arguments.callee(x-1); } ``` </div>

#javascript

知っておくべきこと

  • ActiveXはIE専用のものと理解してよい、Firefoxなどでは存在しない
  • new ActiveXObject(“Microsoft.XMLHTTP”)でIEのXMLHttpRequestが生成される
  • IE のバージョンによっては、”Microsoft.XMLHTTP”の代わりにこれらも使用できるそうです:
    • “Msxml2.XMLHTTP.5.0”
    • “Msxml2.XMLHTTP.4.0”
    • “Msxml2.XMLHTTP.3.0”
    • “Msxml2.XMLHTTP”
  • もし生成できればActiveXコントロールは有効になっている

検出ソースコード

// ブラウザがIEの場合
if (window.ActiveXObject) {
  try {
  //IEのXMLHttpRequestオブジェクトを試しに生成
  var xhr = new ActiveXObject("Microsoft.XMLHTTP");
  } catch (e) {
    alert('ActiveXコントロールは無効になっています');
  }
}


参考サイト

動画をHTMLに埋め込むヒント - faireal.net

#javascript

javaをやってからJavaScriptにかえると、なかなかなれませんね。

例えばJavaではオーバーロードができるが、JavaScriptには通用しない。

すごく簡単に言うと、オーバーロードは多重定義の意味で、同じメソッド名で違う型、数のパラメータがある時、それぞれ一つのメソッドとして認められる。 一方、JavaScriptでは後勝ちです。先に定義したものが無効になります。

function func(param) {
  alert(param);
}

function func() {
  alert(1);
};

func('test');
func();

同じfuncの名前で作られた関数で、一個目はparamというパラメータがついてる。 二番目はパラメータがない。すると結果は: 1 1 になります。常に後で定義したものが勝ちます。

function func() {
  alert(1);
};

function func(param) {
  alert(param);
}

これは「test undefined」になります。