新規記事の投稿を行うことで、非表示にすることが可能です。
2012年10月12日
placeholder 実装(その2)
今回は HTML5 の placeholder に対応していないブラウザ(IE)で、
プレースホルダーのような仕組について検証しています。
前回は span をテキストボックスの前面に配置するところまで行ないました。
今回は、動きについて解説します。
テキストボックスの前面に置いたプレースホルダーは、
下記の特徴を持っていなければ、使い勝手がよくありません。
・クリックできない
・ドラッグできない
そこで、クリックイベントとドラッグイベントで、
テキストボックスにフォーカスを移すようにすればいいと思います。
クリックイベントは、span をクリックしたときに、テキストボックスにフォーカスを移します。
ドラッグ開始イベントは、 span をドラッグしようとしたタイミングでドラッグを解除し、テキストボックスにフォーカスを移します。
テキストボックスにフォーカスを移すと、span は非表示になります。
テキストボックスからフォーカスを外すと、値が入っている場合は非表示のままで、空だった場合は span を再表示させます。
span を再表示させる場合は、inline を指定します。
{a8.net http://books.livedoor.com/item/1752906}
{a8.net http://books.livedoor.com/item/3389102}
プレースホルダーのような仕組について検証しています。
前回は span をテキストボックスの前面に配置するところまで行ないました。
今回は、動きについて解説します。
テキストボックスの前面に置いたプレースホルダーは、
下記の特徴を持っていなければ、使い勝手がよくありません。
・クリックできない
・ドラッグできない
そこで、クリックイベントとドラッグイベントで、
テキストボックスにフォーカスを移すようにすればいいと思います。
// span は定義済みのプレースホルダー
// txt は対象のテキストボックス
// クリック防止
span.onclick = function() {
txt.focus();
return false;
};
// ドラッグ防止
span.ondrugstart = function() {
txt.focus();
return false;
};
span.style.MozUserSelect = 'none';
span.style.userSelect = 'none';
// span 表示・非表示
txt.onfocus = function() {
span.display = 'none';
};
txt.onblur = function() {
if(txt.value) {
span.style.display = 'none';
} else {
span.style.display = 'inline';
}
};
クリックイベントは、span をクリックしたときに、テキストボックスにフォーカスを移します。
ドラッグ開始イベントは、 span をドラッグしようとしたタイミングでドラッグを解除し、テキストボックスにフォーカスを移します。
テキストボックスにフォーカスを移すと、span は非表示になります。
テキストボックスからフォーカスを外すと、値が入っている場合は非表示のままで、空だった場合は span を再表示させます。
span を再表示させる場合は、inline を指定します。
{a8.net http://books.livedoor.com/item/1752906}
{a8.net http://books.livedoor.com/item/3389102}
【このカテゴリーの最新記事】
-
no image
-
no image
-
no image
-
no image
-
no image
posted by FJT at 07:14| javascript
2012年10月10日
placeholder 実装(その1)
今回は HTML5 で実装されている、placeholder の実装を非対応ブラウザで実現してみましょう。
HTML5 に対応していないモダンブラウザと言えば、ひとつしかありません。
それに Firefox 3.6 まだ配布しているでしょうか?こちらも検証してみたいと思います。
まず placeholder のサポート判定ですが、以下の記述を使いましょう。
比較的簡単に実装する場合、テキストボックスの未入力時に、灰色で文字を表示する、
また、フォーカスがあたると非表示にする対応が考えられます。
この実装方法は、該当項目が必須であれば問題ありません。
必須でないときは、灰色で表示されている文字列で次の画面に送られてしまいます。
回避策としては、テキストボックスの上に、文字列表示用の span を重ねてあげれば良さそうです。
フォーカス時には span を非表示に、フォーカス解除時はテキストボックスが空かどうかで
表示可否が決まります。
静的配置の上にspan を重ねる方法について、Firefox の実装方法は簡単です。
span を作成し、親要素の offsetLeft, offsetTop を style.left, style.top にあててやれば OK です。
IE はひとクセあります。offsetLeft と offsetTop は親要素からの位置になっています。
親要素は offsetParent で取得でき、親要素をたどって、style.position が relative または absolute になっていない要素までの offsetLeft, offsetTop を加算していきます。
今回はここまでです。
{a8.net http://books.livedoor.com/item/3481813}
HTML5 に対応していないモダンブラウザと言えば、ひとつしかありません。
それに Firefox 3.6 まだ配布しているでしょうか?こちらも検証してみたいと思います。
まず placeholder のサポート判定ですが、以下の記述を使いましょう。
if(document.createElement('input').placeholder !== undefined) {
return;
}
比較的簡単に実装する場合、テキストボックスの未入力時に、灰色で文字を表示する、
また、フォーカスがあたると非表示にする対応が考えられます。
この実装方法は、該当項目が必須であれば問題ありません。
必須でないときは、灰色で表示されている文字列で次の画面に送られてしまいます。
回避策としては、テキストボックスの上に、文字列表示用の span を重ねてあげれば良さそうです。
フォーカス時には span を非表示に、フォーカス解除時はテキストボックスが空かどうかで
表示可否が決まります。
静的配置の上にspan を重ねる方法について、Firefox の実装方法は簡単です。
span を作成し、親要素の offsetLeft, offsetTop を style.left, style.top にあててやれば OK です。
span.style.left = txt.offsetLeft + 'px';
span.style.top = txt.offsetTop + 'px';
IE はひとクセあります。offsetLeft と offsetTop は親要素からの位置になっています。
親要素は offsetParent で取得でき、親要素をたどって、style.position が relative または absolute になっていない要素までの offsetLeft, offsetTop を加算していきます。
var left = 0;
var top = 0;
var elm = txt;
while (elm) {
if (elm.currentStyle.position != 'relative' && elm.currentStyle.position != 'absolute') {
left += elm.offsetLeft;
top += elm.offsetTop;
} else {
break;
}
elm = elm.offsetParent;
}
span.style.left = left + 'px';
span.style.top = top + 'px';
今回はここまでです。
{a8.net http://books.livedoor.com/item/3481813}
posted by FJT at 01:54| javascript
2012年10月04日
スタイルシートを追加する
仕事の都合で、スタイルシートを javascript で定義する必要が出てきましたので、書いておきます。
スタイルシートの定義は、以下のケースに分けて考えます。
・Internet Explorer
・それ以外
もう定番ですね。
Internet Explorer の場合
createStylesheet メソッドで、直接スタイルシートを追加します。
Internet Explorer 以外の場合
style タグを作成し、sheet オブジェクトを取得します。
見てわかるとおり、スタイルシートの作成は、新しくスタイルシートを生成して、その中に定義をします。
このとき、既存のスタイルシートに定義を追加をしないようにしましょう。
既存のスタイルが存在しない場合や、javascript で上書きされてしまう可能性があるからです。
{a8.net http://books.livedoor.com/item/3389102}
{a8.net http://books.livedoor.com/item/2019205}
{a8.net http://books.livedoor.com/item/292325}
スタイルシートの定義は、以下のケースに分けて考えます。
・Internet Explorer
・それ以外
もう定番ですね。
Internet Explorer の場合
createStylesheet メソッドで、直接スタイルシートを追加します。
// スタイルシート生成、sheet オブジェクト取得
var sheet = document.createStyleSheet();
// スタイル追加
sheet.addRule('BODY', 'background-color:red);
Internet Explorer 以外の場合
style タグを作成し、sheet オブジェクトを取得します。
// style タグ生成
var style = document.createElement('style');
style.type = 'text/css';
document.getElementsByTagName('head')[0].appendChild(style);
// sheet オブジェクト取得
var sheet = style.sheet;
// スタイル追加
sheet.insertRule('BODY{background-color:red}', 0);
見てわかるとおり、スタイルシートの作成は、新しくスタイルシートを生成して、その中に定義をします。
このとき、既存のスタイルシートに定義を追加をしないようにしましょう。
既存のスタイルが存在しない場合や、javascript で上書きされてしまう可能性があるからです。
{a8.net http://books.livedoor.com/item/3389102}
{a8.net http://books.livedoor.com/item/2019205}
{a8.net http://books.livedoor.com/item/292325}
posted by FJT at 06:05| javascript
2012年10月01日
キャッシュの考え方
VBScript というか、Classic ASP でのキャッシュの考え方についてです。
動的なページを作るときに、毎回データアクセスして、
計算して結果表示と行なっているようなページが、一番開発は楽です。
この場合、一番重い、データアクセスについてはデータベースシステムによって自動でキャッシュされます。
他の機能の場合は毎回実行されることになるので、Application 変数を有効に活用することになります。
なお、Application 変数に ADO.Conntetion オブジェクトを格納する方法は推奨されていません。
ほとんど変化が無いであろう動的ページ自体のキャッシュについては、考える余地がありそうです。
具体的には、キャッシュされる HTML を Application 変数に入れておき、要求があり次第 HTML を直接返します。
Application の添え字はアプリケーション単位で任意なので、
今回の例では「resource:///」のように URI っぽくしてみました。
Application 変数に格納する値は、オブジェクトではないほうがいいと思いますので、
文字列が効果的だと思います。
もし XML を格納したい場合は、インデントなどを正規化した XML 文字列を格納すればいいわけです。インデントは人間の見た目を重視するだけなので、キャッシュとコンピュータ間では必要ないと思います。また、メモリ節約、DOM 構築が短縮されるため、微々ですが、高速化が期待できます。
キャッシュは、データベースが一時的に使えなくなったときに、とりあえずの情報として出すことができます。これも活用方法があるのではないでしょうか。
ということで、キャッシュ機能は、つけられるアプリケーションについてはつけましょう。
{a8.net http://books.livedoor.com/item/1729788}
動的なページを作るときに、毎回データアクセスして、
計算して結果表示と行なっているようなページが、一番開発は楽です。
この場合、一番重い、データアクセスについてはデータベースシステムによって自動でキャッシュされます。
他の機能の場合は毎回実行されることになるので、Application 変数を有効に活用することになります。
なお、Application 変数に ADO.Conntetion オブジェクトを格納する方法は推奨されていません。
ほとんど変化が無いであろう動的ページ自体のキャッシュについては、考える余地がありそうです。
具体的には、キャッシュされる HTML を Application 変数に入れておき、要求があり次第 HTML を直接返します。
Response.Write Application("resource///localhost/test.asp")
Application の添え字はアプリケーション単位で任意なので、
今回の例では「resource:///」のように URI っぽくしてみました。
Application 変数に格納する値は、オブジェクトではないほうがいいと思いますので、
文字列が効果的だと思います。
もし XML を格納したい場合は、インデントなどを正規化した XML 文字列を格納すればいいわけです。インデントは人間の見た目を重視するだけなので、キャッシュとコンピュータ間では必要ないと思います。また、メモリ節約、DOM 構築が短縮されるため、微々ですが、高速化が期待できます。
キャッシュは、データベースが一時的に使えなくなったときに、とりあえずの情報として出すことができます。これも活用方法があるのではないでしょうか。
ということで、キャッシュ機能は、つけられるアプリケーションについてはつけましょう。
{a8.net http://books.livedoor.com/item/1729788}
2012年09月24日
Canvas で文字の大きさを測る
Canvas の中で文字を描画するとき、大きさを取得しなければなりませんが、
大きさを取得する方法について書きます。
Canvas の場合は、Graphics で記述することになります。
drawString を使用します。
この際に、たとえば枠でくくるような機能が欲しい場合に、
文字列の大きさを把握する必要があります。
これを、以下のようにして取得しています。
本来は枠に隙間を入れたりして調整しますが、だいたい上記のようなコードを入れています。
枠自体の取得は簡単ですが、文字列を表示するときに、縦座標で getAscent の結果を
考慮に入れておかないと、ずれることになるので注意が必要です。
getAscent は、フォントのベースラインの高さです。文字列を描くときの基準座標になりますが、他の描画と合わせる際はベースライン分も入れておきましょう。
{a8.net http://books.livedoor.com/item/1062223}
大きさを取得する方法について書きます。
Canvas の場合は、Graphics で記述することになります。
drawString を使用します。
この際に、たとえば枠でくくるような機能が欲しい場合に、
文字列の大きさを把握する必要があります。
これを、以下のようにして取得しています。
final String s = "あいうえお";
Graphics g = canvas.getGraphics();
Font f = Font.getDefaultFont();
int width = f.getBBoxWidth(s);
int height = f.getBBoxHeight(s);
int top = 10;
int left = 10;
g.drawRect(left, top, width, height);
g.drawString(s, left, top + f.getAscent());
本来は枠に隙間を入れたりして調整しますが、だいたい上記のようなコードを入れています。
枠自体の取得は簡単ですが、文字列を表示するときに、縦座標で getAscent の結果を
考慮に入れておかないと、ずれることになるので注意が必要です。
getAscent は、フォントのベースラインの高さです。文字列を描くときの基準座標になりますが、他の描画と合わせる際はベースライン分も入れておきましょう。
{a8.net http://books.livedoor.com/item/1062223}
2012年09月21日
スクリプト署名について
今回は、スクリプト署名について書きます。
VBA などが特にそうなのですが、マクロなどを作った時に、
ファイルを開きなおしたときに「信用できないマクロです」のようなメッセージが表示されます。
一般にコンピュータウィルスと疑われてしまいます。
何かいい方法はないものかと考え、スクリプトの署名について調査を行いました。
VBA などのスクリプトにデジタル証明書を添付して、スクリプトを更新したことを証明します、
これを他の人が更新した場合、デジタル証明書は破棄されます。
「このスクリプトは、確かに自分が書きましたよ」の証明なのです。
デジタル証明書ですが、公の証明書は費用が掛かります。
そこで、自己証明書を作成します。
自己証明書は、認証機関から認められていない証明書のことで、
警告は出るのですが、本人であるという証明自体は行なうことができます。
また、使う側の話になりますが、証明書を信頼できれば、その作成者については、
以降は警告が出ずに使用することが可能になります。
{a8.net http://books.livedoor.com/item/372412}
{a8.net http://books.livedoor.com/item/1831089}
VBA などが特にそうなのですが、マクロなどを作った時に、
ファイルを開きなおしたときに「信用できないマクロです」のようなメッセージが表示されます。
一般にコンピュータウィルスと疑われてしまいます。
何かいい方法はないものかと考え、スクリプトの署名について調査を行いました。
VBA などのスクリプトにデジタル証明書を添付して、スクリプトを更新したことを証明します、
これを他の人が更新した場合、デジタル証明書は破棄されます。
「このスクリプトは、確かに自分が書きましたよ」の証明なのです。
デジタル証明書ですが、公の証明書は費用が掛かります。
そこで、自己証明書を作成します。
自己証明書は、認証機関から認められていない証明書のことで、
警告は出るのですが、本人であるという証明自体は行なうことができます。
また、使う側の話になりますが、証明書を信頼できれば、その作成者については、
以降は警告が出ずに使用することが可能になります。
{a8.net http://books.livedoor.com/item/372412}
{a8.net http://books.livedoor.com/item/1831089}
2012年09月11日
ブラウザ判定
・Miocrosoft Internet Explorer
条件付きコンパイルで判定可能です。
/*@cc_on!*/false
IE の場合は /*@cc_on〜*/ の中身が実行され、「!false」=「true」と解釈されます。
IE 以外ではそのままコメント扱いされるので、「false」のままと解釈されます。
<バージョン番号の判定(IE 前提)>
・IE9
新たに追加された opacity スタイルシートで判定します。
ie9 = (document.documentElement.style.opacity !== undefined);
・IE8
document.documentMode の存在有無で判定できますが、互換モードでも IE8 と判定されます。
互換モードの場合は documentMode で返される値をみてもいいと思います。
ie8 = (document.documentMode !== undefined);
・IE7
新たに使用できるようになった、XMLHttpObject で判定します。
ie7 = (!!window.XMLHttpRequest);
・IE6
スタイルシート textOverflow で判定します。
ie6 = (document.documentElement.style.textOverflow !== undefined);
・Mozilla Firefox
古いバージョンでは document.getBoxObjectFor で判定します。
新しいバージョンでは moz 系の属性、たとえば window.mozInnerScreenX で判定します。
ffold = (document.getBoxObjectFor !== undefined);
ff = (window.mozInnerScreenX !== undefined);
・Opera
window.opera で判定します。
opera = (!!window.opera);
・Apple Safari
window.safariHandler で判定します。
→間違いでした。ユーザー定義オブジェクトでした。
window.Selection window.Window を組み合わせます。
safari = (!window.Selection && !window.Window);
・Google Chrome
window.chrome で判定します。
chrome = (!!window.chrome);
{a8.net http://books.livedoor.com/item/3481813}
条件付きコンパイルで判定可能です。
/*@cc_on!*/false
IE の場合は /*@cc_on〜*/ の中身が実行され、「!false」=「true」と解釈されます。
IE 以外ではそのままコメント扱いされるので、「false」のままと解釈されます。
<バージョン番号の判定(IE 前提)>
・IE9
新たに追加された opacity スタイルシートで判定します。
ie9 = (document.documentElement.style.opacity !== undefined);
・IE8
document.documentMode の存在有無で判定できますが、互換モードでも IE8 と判定されます。
互換モードの場合は documentMode で返される値をみてもいいと思います。
ie8 = (document.documentMode !== undefined);
・IE7
新たに使用できるようになった、XMLHttpObject で判定します。
ie7 = (!!window.XMLHttpRequest);
・IE6
スタイルシート textOverflow で判定します。
ie6 = (document.documentElement.style.textOverflow !== undefined);
・Mozilla Firefox
古いバージョンでは document.getBoxObjectFor で判定します。
新しいバージョンでは moz 系の属性、たとえば window.mozInnerScreenX で判定します。
ffold = (document.getBoxObjectFor !== undefined);
ff = (window.mozInnerScreenX !== undefined);
・Opera
window.opera で判定します。
opera = (!!window.opera);
・Apple Safari
window.safariHandler で判定します。
→間違いでした。ユーザー定義オブジェクトでした。
window.Selection window.Window を組み合わせます。
safari = (!window.Selection && !window.Window);
・Google Chrome
window.chrome で判定します。
chrome = (!!window.chrome);
function evaluate(_element) {
val elm = _element;
var ret = 'Unknown';
if(/*@cc_on!*/false) {
var ie9 = (document.documentElement.style.opacity !== undefined);
var ie8 = (document.documentMode !== undefined);
var ie7 = (!!window.XMLHttpRequest);
var ie6 = (document.documentElement.style.textOverflow !== undefined);
ret = 'Internet Explorer ' + (ie9 ? '9' : ie8 ? '8' : ie7 ? '7' : ie6 ? '6' : '5.5 less');
} else if(document.getBoxObjectFor !== undefined) {
ret = 'Old Firefox';
} else if(window.moxInnerScreenX !== undefined) {
ret = 'Mozilla Firefox';
} else if(!!window.opera) {
ret = 'Opera';
} else if(!window.Selection && !window.Window) {
ret = 'Apple Safari';
} else if(!!window.chrome) {
ret = 'Google Chrome';
}
this.value = ret;
{a8.net http://books.livedoor.com/item/3481813}
posted by FJT at 05:58| javascript
2012年09月10日
AudioPresenter の使い方
今回は久しぶりに DoJa の記事です。
AudioPresenter について書きます。
AudioPresenter は音声出力をするためのものです。
まず、インスタンスを取得します。
これに、音声ファイルを設定します。
簡単に再生はできたのですが、音楽の切替え方がわかりませんでした。
ap.stop() で良さそうなのですが、どうやらすぐには停止しないようです。
そこで、以下のようにしてみました。
まず、次の音声を予約できる変数を用意します。
次に MediaListener を定義します。
MediaAction で、AudioPresenter.AUDIO_COMPLETE と
AudioPresenter.AUDIO_STOPPED に対して nextSound の処理を入れます。
ひとまずこれで良さそうです。
AudioPresenter について書きます。
AudioPresenter は音声出力をするためのものです。
まず、インスタンスを取得します。
AudioPresenter ap = AudioPresenter.getAudioPresenter();
これに、音声ファイルを設定します。
MediaSound md = MediaManager.getSound(...);
ap.setSound(md);
ap.play();
簡単に再生はできたのですが、音楽の切替え方がわかりませんでした。
ap.stop() で良さそうなのですが、どうやらすぐには停止しないようです。
そこで、以下のようにしてみました。
まず、次の音声を予約できる変数を用意します。
MediaSound nextSound;
次に MediaListener を定義します。
ap.setMediaListener(new MediaListener() {
public void MediaAction(int type, int param){
switch(type) {
case AudioPresenter.AUDIO_COMPLETE:
case AudioPresenter.AUDIO_STOPPED:
// 停止後
}
}
})
MediaAction で、AudioPresenter.AUDIO_COMPLETE と
AudioPresenter.AUDIO_STOPPED に対して nextSound の処理を入れます。
if(nextSound != null) {
ap.setSound(nextSound);
ap.play();
nextSound = null;
}
ひとまずこれで良さそうです。
2012年09月06日
If 文の特性について
今回は If 文の特性について書きます。
VBScript では If 文などで分岐するときに、
失敗ケースを先に書いておくことをおすすめします。
問題になりそうな書き方は以下のとおりです。
これを、以下のような書き方にします。
肝となるのは On Error Resume Next と
If 文に実行時エラーが発生する可能性があることです。
On Error Resume Next がある If 文では、評価式の中でエラーが発生すると、
Then 以降の処理を実行してしまいます。
これが、予期しない処理を生んでしまうわけです。
したがって、If 文の書き方は、Else 以降に正常処理を書いておくほうが良いのです。
チェックに引っかかった場合の処理ということで、先頭にまとめて書いておけば
ソースの統一感も出ると思います。
もし不思議な処理でお悩みの方は、上記の書き方に変えてみることをおすすめします。
{a8.net http://books.livedoor.com/item/1660109}
VBScript では If 文などで分岐するときに、
失敗ケースを先に書いておくことをおすすめします。
問題になりそうな書き方は以下のとおりです。
On Error Resume Next
Set scr = CreateObject("Scripting.FileSystemObject")
IIf Not scr.FileExists(arg) Then
If Not scr.FolderExists(arg) Then
Call MainProcess(arg)
Else
MsgBox "チェックBに失敗しました"
End If
Else
MsgBox "チェックAに失敗しました"
End If
これを、以下のような書き方にします。
On Error Resume Next
Set scr = CreateObject("Scripting.FileSystemObject")
If scr.FileExists(arg) Then
MsgBox "チェックAに失敗しました"
ElseIf scr.FolderExists(arg) Then
MsgBox "チェックBに失敗しました"
Else
Call MainProcess(arg)
End If
肝となるのは On Error Resume Next と
If 文に実行時エラーが発生する可能性があることです。
On Error Resume Next がある If 文では、評価式の中でエラーが発生すると、
Then 以降の処理を実行してしまいます。
これが、予期しない処理を生んでしまうわけです。
したがって、If 文の書き方は、Else 以降に正常処理を書いておくほうが良いのです。
チェックに引っかかった場合の処理ということで、先頭にまとめて書いておけば
ソースの統一感も出ると思います。
もし不思議な処理でお悩みの方は、上記の書き方に変えてみることをおすすめします。
{a8.net http://books.livedoor.com/item/1660109}
2012年09月02日
defer について
script を書いていて目にすることがあるのが、defer 属性です。
これは何をしているのかな?とは思っていましたが、
つい調べずに通り過ぎてしまいました。
今回の記事として調べてみましたので、書いておきます。
この属性を定義しておく場合、まず推奨する記述ですが、以下のとおりにします。
<script type="text/javascript" defer="defer"></script>
属性名だけ定義する記述は見かけなくなりました。
XHTML では文法エラーになるからだと思います。
これを定義すると何が変わるかというと、スクリプトの実行順序です。
何も設定しない場合は、script タグが出てきた段階で実行されます。
defer がある場合は、DOM が構築された後で実行されます。
defer のあるスクリプト内で、以下の実験をしてみました。
var elms = document.getElementsByTagName("*");
alert(elms[elms.length - 1].tagName);
現在処理しているタグ名を取得します。
普通は処理中の script タグが返されますが、defer スクリプトの場合は body が返されます。
つまり、DOM 構築後に動かすことができます。
各ブラウザで実験してみたところ、onLoad より早いタイミングで動いているようです。
DOM 構築後に DOMContentLoaded のようにしている箇所については、
もしかして代用ができれるかもしれません。
もちろん、引数解析と DOM 構築イベントを両方使っている場合は適用できません。
次に async 属性について解説します。
これは、async 非同期の名前があらわすとおり、起動するタイミングがわかりません。
スクリプトが起動でき次第動かすものなので、負荷が掛からないようにする処理などに
向いていると思います。
{a8.net http://books.livedoor.com/item/1934172}
{a8.net http://books.livedoor.com/item/1826530}
posted by FJT at 07:51| javascript