2011年01月24日


JavaScript : Safari for Windows 5.0.3 の困ったバグとその対処方法 : alert、confirm でフォーカスがセットされていない。

Windows XP だけで起きていたり、環境によって違うかもしれませんが、
結構致命的で、Safari の為だけにコードを書かないといけないので困ります。
これは操作するほうが注意しないといけない内容ですが、対応したい場合は
setTimeout を使います。

10 ミリセカンド後でいいので、alert や confirm の処理を含んだ function
を setTimeout で呼び出す事で正しく動作します。これをしないと、表示している
メッセージボックスは、クリックしても一度目は反応しません。それでころか、1
度目にボタンをクリックすると、その後ろ側にある HTML に対して反応してしまい
ます。

かなり、致命的です

HTML のインラインで書く場合は、無名 function を使い、イベント用の文字列
はシングルクォートで表現するといいです。そうすると、プログラム出現率の高
い、ダブルクォートを心おきなく使えます。

※ シングルクォートが必要な場合は、' を使えます。
<input type="button" value="action" onclick='alert("I can&#39;t fly.")'>

<input type="button" value="action" onclick='

	setTimeout(function(){
		alert("I can&#39;t fly.")
	},10);

'>



posted by at 2011-01-24 15:28 | Comment(0) | JavaScript | このブログの読者になる | 更新情報をチェックする

2010年12月17日


google.load + YUI Loader で、カラーピッカーを設置

最初このブログに直接埋め込んだら、どうもいろんな環境が混ざりすぎて
まともに動いたのは Google Chrome だけでした。仕方ないので IFRAME で
埋め込んでいますが、showModalDialog を使うといいと思います。

基本的には、YUI 2 のサンプルのままなのですが、そのままで使えたら苦労しない
のが YUI でして。。。。

まず、結果のコードの取得方法として3つ用意しましたが、そのうちの一つは
サンプル通りの get メソッドで、あとはこちらで追加実装です。そもそも、
テキストフィールドが変更可能なままなので、readonly にする為にプロパティ
から内部 ID を取得して直接アクセスしています。

また、初期処理のイベント(available)は継承元のイベントを使用しています。

chgValue はこちらで追加した新しいプロパティで、変更された値を picker
から直接アクセスできるようにしました。

後、どういうわけかポインタ用の画像は自分で用意する必要があるみたいですが、
サンプルなので、Yahoo のをそのまま使っています。実際に使う時はダウンロード
してどこかに保存して使います。また、IE ではグラデーションが「標準モード」で
ないと動かないので注意して下さい。
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
</head>
<body style='margin:0'>

<script type="text/javascript" src="http://www.google.com/jsapi" charset="utf-8"></script>
<script type="text/javascript">
google.load("yui", "2.8.2");
</script>
<script type="text/javascript">
new YAHOO.util.YUILoader({
	require: ['colorpicker','fonts'],
	loadOptional: true,
	onSuccess: function() {
		var Event = YAHOO.util.Event;
		Event.onDOMReady(function() {
			picker = new YAHOO.widget.ColorPicker("color_picker", {
				showhsvcontrols: true,
				showhexcontrols: true,
					images: {
						PICKER_THUMB: "http://developer.yahoo.com/yui/examples/colorpicker/assets/picker_thumb.png",
						HUE_THUMB: "http://developer.yahoo.com/yui/examples/colorpicker/assets/hue_thumb.png"
					}
				});
	
				picker.on("rgbChange", function(o){
						picker.chgValue = o; 
					}
				);
				picker.on("available", function(o){
						// 初期編集不可
						document.getElementById(picker.ID.HEX).setAttribute("readonly","true") 
						document.getElementById(picker.ID.R).setAttribute("readonly","true") 
						document.getElementById(picker.ID.G).setAttribute("readonly","true") 
						document.getElementById(picker.ID.B).setAttribute("readonly","true") 
						document.getElementById(picker.ID.H).setAttribute("readonly","true") 
						document.getElementById(picker.ID.S).setAttribute("readonly","true") 
						document.getElementById(picker.ID.V).setAttribute("readonly","true") 
						picker.chgValue = {};
						picker.chgValue.newValue = [255, 255, 255];
						picker.chgValue.prevValue= [255, 255, 255];
					}
				);
	
				Event.on("reset", "click", function(e) {
					picker.setValue([255, 255, 255], false);
				});
	
				Event.on("gethex1", "click", function(e) {
					alert(picker.get("hex")); 
				});
				Event.on("gethex2", "click", function(e) {
					alert(document.getElementById(picker.ID.HEX).value); 
				});
				Event.on("gethex3", "click", function(e) {
					alert(picker.chgValue.newValue + " : " + picker.chgValue.prevValue); 
				});
		});
	}
}).insert();
</script>

<div class="yui-skin-sam" style='padding:10px;background-color: #eeeeee;width: 420px; height:220px;'>
<div id="color_picker" style='position: relative;'></div>
</div>

<input type="button" id="reset" value="初期値">
<input type="button" id="gethex1" value="RGB表示(1)">
<input type="button" id="gethex2" value="RGB表示(2)">
<input type="button" id="gethex3" value="RGB表示(3)">

</body>
</html>



posted by at 2010-12-17 22:28 | Comment(0) | JavaScript | このブログの読者になる | 更新情報をチェックする

2010年11月19日


jQuery の $(document).ready の実際の中身と $(window).load と prototype.js での onload 実装と $ メソッドをリネームして混在使用

$(document).ready() と 書いても $(window).ready() と書いても同じ事になります。
内部では、IE と Gecko で実装は違いますが、いずれも document のイベントです。

Gecko-Specific DOM Events - MDC Doc Center でそのイベントについて書かれていて、
「"load" とは異なり画像が読み込まれるのを待ちません」とあります。で、何故か日本
語ページの訳が間違っていて、window のイベントと書かれていますが、英文ページでは
document オブジェクトのイベントと書かれており、jQuery でもそう扱われています。

IE のほうは、onreadystatechange Event とあって、これも document オブジェクト
のイベントでかなり前から実装されていたようです。

いずれも、それらのイベントで仮に失敗しても確実な window の load イベントでフォ
ローするという念の入った実装となっています。

$(window).load は、そのままで window の onload イベントの実装に使われています。
$(document).ready() は、通常の onload イベントの実装と比較しましたがとてもうまく
動作しており、$(window).load も正しく動作する事を確認しています
( 通常の登録より後に実行される事を確認済です )
bindReady: function() {
	if ( readyBound ) {
		return;
	}

	readyBound = true;

	// Catch cases where $(document).ready() is called after the
	// browser event has already occurred.
	if ( document.readyState === "complete" ) {
		// Handle it asynchronously to allow scripts the opportunity to delay ready
		return setTimeout( jQuery.ready, 1 );
	}

	// Mozilla, Opera and webkit nightlies currently support this event
	if ( document.addEventListener ) {
		// Use the handy event callback
		document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false );
		
		// A fallback to window.onload, that will always work
		window.addEventListener( "load", jQuery.ready, false );

	// If IE event model is used
	} else if ( document.attachEvent ) {
		// ensure firing before onload,
		// maybe late but safe also for iframes
		document.attachEvent("onreadystatechange", DOMContentLoaded);
		
		// A fallback to window.onload, that will always work
		window.attachEvent( "onload", jQuery.ready );

		// If IE and not a frame
		// continually check to see if the document is ready
		var toplevel = false;

		try {
			toplevel = window.frameElement == null;
		} catch(e) {}

		if ( document.documentElement.doScroll && toplevel ) {
			doScrollCheck();
		}
	}
},

以下は、prototype.js における window の onload イベントの実装用の記述ですが、
prototype.js と jQuery を混在させる為に jQuery の $ メソッドを $j にリネーム
してテストしています。
Event.observe(window, 'load', function(){ alert("prototype") });
jquery-1.4.4.min.js の場合、3箇所の変更で、E.$ を E.$j に変更します。
$j(document).ready(function() {

	try {
		console.log("ready");
	}
	catch(e){}

	$j("#box1").html("<div style='padding: 3px 0 0 6px;'><a href='../'>ホーム</a></div>");
	$j("#footer").html("<address>Copyright (c) 2010 xxx All Rights Reserved.</address>");

});

以下は、混在コード内で通常のオブジェクト参照の使用です
Event.observe(window, 'load', function(){ 

	alert( $j("#box1").html() );
	alert( $j("#box1")[0].innerHTML );

	$j("#box1").each( function(index) {
		alert(index + ': ' + this.innerHTML );
		alert(index + ': ' + $j(this).html());
	});

});

$j(document).ready(function(){

	// prototype 参照
	alert( $("box1").innerHTML );

})



posted by at 2010-11-19 22:28 | Comment(0) | JavaScript | このブログの読者になる | 更新情報をチェックする

2010年11月03日


JSON 文字列の末端の値を PATH 形式で参照する

eval で JSON 文字列をオブジェクトに変換していますが、外部から取得する
文字列である場合、内容が危険でないかチェックする必要があります。
( prototype.js を参考にすると良いと思います )

JSON データのフォーマットは、占いAPI のものを使っているので、実際
運用しているものです。但し / でパス表現する為に、日付は / から - に変えて
います。また、内容の文章は自分で作って書き換えました。

日付の下層のデータは配列になっていますので、そのままパスに加える事によって
容易に参照可能です。
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=euc-jp">
<title>JSON PATH</title>
<style>
* {
	font-size:16px;
}
</style>

</head>
<body>
<textarea id="json" cols=60 rows=8 wrap="off" >{
    "horoscope": {
        "2010-10-24": [{
            "content": "考えすぎに注意。あなたが思っているほどその問題はそれほど大きくありません。良く周り見ると他に楽しい事が待っています。",
            "item": "マンゴー",
            "money": 2,
            "total": 1,
            "job": 1,
            "color": "丹",
            "day": 24,
            "love": 2,
            "rank": 12,
            "sign": "牡羊座"
        },
        {
            "content": "迷った場合は第一印象を優先。迷うのが楽しい事もありますが、迷い過ぎると他の事に良い影響が出なかったりします。",
            "item": "回数券",
            "money": 2,
            "total": 2,
            "job": 3,
            "color": "黄土",
            "day": "",
            "love": 2,
            "rank": 10,
            "sign": "双子座"
        },
        {
            "content": "一番身近に居て、常にあなたの事を見守ってくれる人がいます。あなたももう少しその人の事を大切にすると幸せになれます。",
            "item": "てぶくろ",
            "money": 5,
            "total": 4,
            "job": 4,
            "color": "藍",
            "day": "",
            "love": 5,
            "rank": 3,
            "sign": "魚座"
        }]
    }
}</textarea>
<br>
<input id="path" type="text" size=60 value="horoscope/2010-10-24/1/content">
<hr>
<script	type="text/javascript">

// JSON 文字列の取得
var json_str = document.getElementById("json").value;

// オブジェクト化
var json = eval("(" + document.getElementById("json").value + ")");

// *********************************************************
// JSON を PATH 形式で参照する
// *********************************************************
function jsonPath( json, path ) {

	var arr = path.split("/");

	for( var i = 0; i < arr.length; i++ ) {
		json = json[arr[i]]

	}

	return json;
}
function scriptTest(evt) {

	// JSON での直接参照
	// alert( json.horoscope["2010-10-24"][1].content );

	// PATH 参照
	var path  = document.getElementById("path").value;

	// 表示
	alert( jsonPath( json, path ) );

}
</script>

<input type="button" value="実行" onclick='scriptTest(event);'>

</body>
</html>



関連する記事

VBScript : WSH で JSON 文字列からデータを取得する


posted by at 2010-11-03 13:34 | Comment(0) | JavaScript | このブログの読者になる | 更新情報をチェックする
Seesaa の各ページの表示について
Seesaa の 記事がたまに全く表示されない場合があります。その場合は、設定> 詳細設定> ブログ設定 で 最新の情報に更新の『実行ボタン』で記事やアーカイブが最新にビルドされます。

Seesaa のページで、アーカイブとタグページは要注意です。タグページはコンテンツが全く無い状態になりますし、アーカイブページも歯抜けページはコンテンツが存在しないのにページが表示されてしまいます。

また、カテゴリページもそういう意味では完全ではありません。『カテゴリID-番号』というフォーマットで表示されるページですが、実際存在するより大きな番号でも表示されてしまいます。

※ インデックスページのみ、実際の記事数を超えたページを指定しても最後のページが表示されるようです

対処としては、このようなヘルプ的な情報を固定でページの最後に表示するようにするといいでしょう。具体的には、メインの記事コンテンツの下に『自由形式』を追加し、アーカイブとカテゴリページでのみ表示するように設定し、コンテンツを用意するといいと思います。


※ エキスパートモードで表示しています

アーカイブとカテゴリページはこのように簡単に設定できますが、タグページは HTML 設定を直接変更して、以下の『タグページでのみ表示される内容』の記述方法で設定する必要があります

<% if:page_name eq 'archive' -%>
アーカイブページでのみ表示される内容
<% /if %>

<% if:page_name eq 'category' -%>
カテゴリページでのみ表示される内容
<% /if %>

<% if:page_name eq 'tag' -%>
タグページでのみ表示される内容
<% /if %>
この記述は、以下の場所で使用します