SQLの窓

2016年05月27日


Google Chrome で音声認識の結果をブログの投稿テキストエリアに転送するブックマークレット



この Seesaa ブログでもテストしました(リッチテキストは使用できません)。ブックマークレットを実行すると、ページの左上に IFRAME のウインドウを埋め込みます。その後、ページ内の対象のテキストエリアにカーソルを置くと開始ボタンが使えるようになるので『開始』をクリックします。

あとは、マイクで話すだけです。時々固まって動作しなくなる場合があるのでその場合は、『終了ボタン』を押すして再度開始ボタンを押して再開して下さい。

終了ボタンを押すと停止状態になり、テキストエリア内のテキストを編集しても結構です。最後に改行等を入れて開始ボタンで再開すると、最後の位置に追加して行きます。

長い時間何も音声入力が無いと自動的に終了します。

Google Chrome で音声認識の精度は想像以上に凄いです。学生がおもしろがって般若心経を朗読はじめたんですが、見事に認識されました(凄い)。

※ 前後にある文章や語句によって結果を変更して行くのがリアルタイムに見て取れる場合があります
▼ ブックマークレット登録用リンク
音声からテキスト

コードのメインは、Google Chrome での音声認識処理 を使用しています。但し、処理部分は私のサイトの recognition.js の中にあります。
parent.document.getElementById("if").style.position='absolute';
parent.document.getElementById("if").style.width='400px';
parent.document.getElementById("if").style.height='100px';
parent.document.getElementById("if").style.left='0px';
parent.document.getElementById("if").style.top='0px';
parent.document.getElementById("if").style.zIndex=0x7FFFFFFF;
parent.document.getElementById("if").style.borderColor='#000000';
parent.document.getElementById("if").style.borderWidth='1px';
parent.document.getElementById("if").style.borderStyle='solid';

parent.window.ds = parent.document.createElement('div');
parent.window.ds.setAttribute('id','ds')
parent.document.body.appendChild(parent.window.ds);
parent.document.getElementById("ds").style.position='absolute';
parent.document.getElementById("ds").style.width='400px';
parent.document.getElementById("ds").style.height='100px';
parent.document.getElementById("ds").style.left='8px';
parent.document.getElementById("ds").style.top='8px';
parent.document.getElementById("ds").style.zIndex=0x7FFFFFFE;
parent.document.getElementById("ds").style.backgroundColor='#000000';

var userAgent = window.navigator.userAgent.toLowerCase();

if (userAgent.indexOf("msie") > -1) {
	parent.document.getElementById("ds").style.filter='alpha(opacity=18)';
}
else {
	parent.document.getElementById("ds").style.opacity=.18;
}


str="";
str+="<body style='margin:0;background-color:#ffffff;padding:15px;'> \n";
str+="<style> \n";
str+=" * { \n";
str+=" font-family:";
str+=" \"メイリオ\", Meiryo, \"MS Pゴシック\"; \n";
str+=" font-size:12px;";
str+="} \n";
str+="</style> \n";

str+="<"+"script src=\"//ajax.googleapis.com/ajax/libs/jquery/2.2.2/jquery.min.js\"></"+"script> \n";
str+="<div id=\"check\"></div> \n";
str+="<input id=\"st_btn\" type=\"button\" value=\"開始\" disabled> \n";
str+="<input id=\"ed_btn\" type=\"button\" value=\"終了\" disabled> \n";
str+="<div id=\"info\" style='display:inline-block;'></div> \n";
str+="<div id=\"result\"><div id=\"first_text\"></div></div> \n";

str+="<"+"script> \n";
str+="$( function(){ \n";
str+=" \n";
str+="	load_action(); \n";
str+=" \n";
str+="} ); \n";
str+="</"+"script> ";


str+="</body> \n";

document.write( str );
document.close();

parent.scroll(0,0);

var target_textarea;
var rec = null;
var target;
var back_text = "";

function load_action() {

	parent.focus();

	var iid = setInterval(function(){
		parent.focus();
		target_textarea = parent.document.activeElement;
		if ( (target_textarea.tagName).toLowerCase() == "textarea" ) {
			$("#check").text("textarea を取得しました");
			clearInterval(iid);
			$("#st_btn").prop("disabled", false);
			$("#ed_btn").prop("disabled", false);
		}
		else {
			$("#check").text("テキストエリアにカーソルを置いて下さい");
		}
	},500);

	if ( typeof webkitSpeechRecognition === 'undefined' ) {
		$("#info").text("使用できません");
		$("#st_btn").prop("disabled", true);
		$("#ed_btn").prop("disabled", true);
	}
	else {

		target = $("#first_text");

		// インスタンス作成
		rec = new webkitSpeechRecognition();
		// 初期設定
		rec.lang = "ja-JP";
		rec.interimResults = true;
		rec.continuous = true;
		// イベント登録
		rec.onerror = function(){
			$("#info").text("error");
		};
		rec.onnomatch = function(){
			$("#info").text("nomatch");
		};
		rec.onsoundstart = function(){
			$("#info").text("音検知");
		};
		rec.onsoundend = function(){
			$("#info").text("soundend");
		};
		rec.onspeechstart = function(){
			$("#info").text("スピーチ開始");
		};
		rec.onspeechend = function(){
			$("#info").text("スピーチ終了");
		};

		rec.onstart = function(){
			$("#info").text("開始");
		};
		rec.onend = function(){
			$("#info").text("終了");
		};
		// 結果テキストの作成
		rec.onresult = function(ev){
			var obj = ev.results;
			for (var i = ev.resultIndex; i < obj.length; i++ ) {
				if( obj[i].isFinal ) {
					target.text(obj[i][0].transcript);
					target = $("<div></div>");
					$("#result").append(target);
					target_textarea.value = back_text + $("#result").text();
				}
				else {
					target.text(obj[i][0].transcript);
				}
			}
		};	

		// ボタンイベント
		$("#st_btn").on("click",function(){

			back_text = target_textarea.value;

			rec.start();
			$("#st_btn").prop("disabled",true);
		})
		$("#ed_btn").on("click",function(){
			rec.stop();
			$("#st_btn").prop("disabled",false);
			$("#result").html("<div id=\"first_text\"></div>");
			target = $("#first_text");

		})
	}

}
途中、IE のチェックをしているところがありますが、汎用テンプレートを使用して作成しているからです。

改行を入れて読みやすくしたブックマークレットコード
javascript:
var%20wnd=document.createElement('iframe');
wnd.setAttribute('id','if');
wnd.frameBorder=0;
document.body.appendChild(wnd);
var%20url='';
if((location.href).substr(0,5)=='https'){
	url='https://lightbox.sakura.ne.jp/toolbox/recognition.js';
}else{
	url='http://toolbox.winofsql.jp/recognition.js';
}
wnd.contentWindow.document.write('<script src=\''+url+'\' charset=\'utf-8\'></script>')
最後の document.write は DOM でも書けますが、どうせ js のほうでは画面を作成するのに document.write を使用せざるを得ないので同じ事です。初期画面の HTML や JavaScript の文字列化はこちらから実行できます。
( プログラム用文字列 の JavaScript ボタン )


posted by lightbox at 2016-05-27 22:41 | Comment(0) | JavaScript オブジェクト | このブログの読者になる | 更新情報をチェックする

2016年05月24日


Google Chrome での音声認識処理






試したくて、マイクを見にヤマダ電機に言ったら、最低でも780円くらいしたのでやめて、古い WEBカメラを引っ張り出して使ったら使えました。

参考にしたのは、こちら。確認した仕様はこちら。

処理の中核を確認して、音声が途切れる毎に表示 DIV を追加する方式にして実装しました。イベントはたくさんありますが、直接必要なのは result イベントです。全く音声がない時間が5秒くらい? 続くと自動的に終わります。

Google Chrome の設定のプライバシーのコンテンツの設定でマイクを選びました。例外の管理では、一度ブロックしたサイトの削除して使えるようにできます。



ソースコード
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.2.2/jquery.min.js"></script>

<input id="st_btn" type="button" value="開始">
<input id="ed_btn" type="button" value="終了">
<div id="info"></div>
<div id="result">
	<div id="first_text"></div>
</div>
<script>
var rec = null;
var target = $("#first_text");

$(function(){
	if ( typeof webkitSpeechRecognition === 'undefined' ) {
		$("#info").text("使用できません");
		$("#st_btn").prop("disabled", true);
		$("#ed_btn").prop("disabled", true);
	}
	else {
		// インスタンス作成
		rec = new webkitSpeechRecognition();
		// 初期設定
		rec.lang = "ja-JP";
		rec.interimResults = true;
		rec.continuous = true;
		// イベント登録
		rec.onerror = function(){
			$("#info").text("error");
		};
		rec.onnomatch = function(){
			$("#info").text("nomatch");
		};
		rec.onsoundstart = function(){
			$("#info").text("音検知");
		};
		rec.onsoundend = function(){
			$("#info").text("soundend");
		};
		rec.onspeechstart = function(){
			$("#info").text("スピーチ開始");
		};
		rec.onspeechend = function(){
			$("#info").text("スピーチ終了");
		};

		rec.onstart = function(){
			$("#info").text("開始");
		};
		rec.onend = function(){
			$("#info").text("終了");
		};
		// 結果テキストの作成
		rec.onresult = function(ev){
			var obj = ev.results;
			for (var i = ev.resultIndex; i < obj.length; i++ ) {
				if( obj[i].isFinal ) {
					target.text(obj[i][0].transcript);
					target = $("<div></div>");
					$("#result").append(target);
				}
				else {
					target.text(obj[i][0].transcript);
				}
			}
		};	

		// ボタンイベント
		$("#st_btn").on("click",function(){
			rec.start();
			$("#st_btn").prop("disabled",true);
		})
		$("#ed_btn").on("click",function(){
			rec.stop();
			$("#st_btn").prop("disabled",false);
		})
	}
	
});

</script>

関連する記事

ほぼ、Google Chrome 限定ですが Web Speech API の現時点での実装と問題点回避方法



posted by lightbox at 2016-05-24 02:08 | Comment(0) | JavaScript オブジェクト | このブログの読者になる | 更新情報をチェックする

2016年05月14日


ほぼ、Google Chrome 限定ですが Web Speech API の現時点での実装と問題点回避方法

※ 長い文章を試すと、安全なのは 80文字くらいでした。長すぎると壊れて、Google Chrome を再起動する必要がありました

何故か最初のロードで speechSynthesis.getVoices() は一覧を取って来ません。この一覧でコンボボックスを作る必要があるので、とても回りくどい事をしています。

インターネットを調べましたが、過去のものは動かないものが多く、理由はこの Voice をセットしていない事が原因でした。

また、Firefox では、 about:config で、media.webspeech.synth.enabled を設定する必要があるのと、設定しても Voice が一つしか取得されず英語のみで、何故か Microsoft の 『Microsoft Anna - English (United States)』で、仕様がイマイチよく解りません。コンボボックスは選択しなくても英語を入力すれば話してくれます


UI を jQuery で実装
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.2.2/jquery.min.js"></script>
<textarea id="target_text" style='width:300px;height:60px;'>こんにちは</textarea><br>
<input type="button" id="speech_button" value="実行">
<select id="voice"></select>

<script>
var voice_types;

$(function(){

	if ( typeof SpeechSynthesisUtterance === 'undefined' ) {
		$('#target_text').val("Web Speech API は使えません");
	}

	// 何故か初回が取れない
	voice_types = speechSynthesis.getVoices();
	if ( voice_types.length == 0 || $('#voice').children().length == 0 ) {
		// 無かった場合、もう一度
		get_voice_type ()
	}

	$("#speech_button").on("click", function() {
		// 念のために取り出す
		voice_types = speechSynthesis.getVoices();
		if ( voice_types.length == 0 ) {
			// 再取得で無かった場合、もう一度
			get_voice_type ();
			return;
		}

		var speech = new SpeechSynthesisUtterance($("#target_text").val());

		// 選択した言語を使う
		speech.voice = voice_types[ $('#voice > option:selected').val() ];

		speechSynthesis.speak(speech);

	});


});

function get_voice_type () {
		setTimeout(function(){
			voice_types = speechSynthesis.getVoices();
			$('#voice > option').remove();
			for( i = 0; i < voice_types.length; i++) {
				$('#voice').append($('<option>').text(voice_types[i].name).val(i));
			}
			$('#voice').prop("value",11);
		},100);
}

</script>

ここでは使っていませんが、pitch は声の高さを 0.1 づつで 1.6 ぐらいが限界みたいです(それ以上はかすれた変な声)。rate は速さで 0.1 づつ増やせますが、1.8 くらいで聞き取りは限界です。

関連する記事

Google Chrome での音声認識処理



posted by lightbox at 2016-05-14 14:57 | Comment(0) | JavaScript オブジェクト | このブログの読者になる | 更新情報をチェックする

2014年10月08日


JavaScript の String と Date オブシェクトに、9999/99/99 書式の文字列日付を取り出すメソッドを追加する

月と日が一桁の場合、前に "0" を付加する為に、String.prototype.right がある事が前提です。 

文字列からのアプローチは、年・月・日の区切り文字に対して sdate を実行します(引数に Date オブジェクト)。
Date オブジェクトからのアプローチは、日付オブジェクトに対して、sdate を実行して、引数には区切り文字を指定します 
<script type="text/javascript">
String.prototype.right = function(n){
	var str = this.valueOf();
	str = str.substr(str.length-n,n);
	return str;
}
String.prototype.sdate = function(dt){
	var str = this.valueOf();
	var today = dt.getFullYear() + str + ("0"+(dt.getMonth()+1)).right(2) + str + ("0"+dt.getDate()).right(2);
	return today;
}
Date.prototype.sdate = function(str){
	var today = this.getFullYear() + str + ("0"+(this.getMonth()+1)).right(2) + str + ("0"+this.getDate()).right(2);
	return today;
}

console.log( "-".sdate(new Date()) )
console.log( (new Date()).sdate("-") )
</script>



タグ:javascript
posted by lightbox at 2014-10-08 11:16 | JavaScript オブジェクト | このブログの読者になる | 更新情報をチェックする

2014年02月01日


JavaScript オブジェクト作成の4態

1) 通常 JSON 記法
2) 無名 function 記法
3) 有名 function による インスタンス作成
<script type="text/javascript">

var obj1 =  {
	myobj: {
		func: function(){ return this.value },
		value: "OK"
	}
}

var obj2 = new function() {
	this.myobj = {
		func: function(){ return this.value },
		value: "OK"
	}
}

function obj() {
	this.myobj = {
		func: function(){ return this.value },
		value: "OK"
	}
}

var obj3 = new obj();

console.dir(obj1.myobj.func());
console.dir(obj2.myobj.func());
console.dir(obj3.myobj.func());
console.dir(obj1);
console.dir(obj2);
console.dir(obj3);
</script>


この結果では当然ですが、有名ファンクションでは『型』は function 名となっています。

さらに、もう一つの形として、Object 型の最初から myobj を設定しておくと以下のようになります。
<script type="text/javascript">
Object.prototype.myobj = {
	func: function(){ return this.value },
	value: "OK"
}

var obj1 =  {
}

var obj2 = new function() {
	this.myobj = {
		func: function(){ return this.value },
		value: "OK"
	}
}

console.dir(obj1.myobj.func());
console.dir(obj2.myobj.func());
console.dir(obj1);
console.dir(obj2);
</script>


空のオブジェクトでも、myobj が使用可能になりますが、全てのオブジェクトに対して定義されてしまいます。しかし、同名のプロパティを上書きするとそちらが有効になります。





posted by lightbox at 2014-02-01 18:37 | JavaScript オブジェクト | このブログの読者になる | 更新情報をチェックする

2013年03月22日


JavaScript の function を new したものが、JSON フォーマットで記述した『Object』と同じである事のテスト

function は、他の言語で言うところの『クラス』のようなものですが、実際の扱いはそんなに簡単ではありません。しかし、少なくともこの二つが『インスタンス』である事は間違いなさそうです。

ですから、jQuery の .data メソッドでエレメントに対して『インスタンス』を保存する事ができるという事なので、以下の記事での改造はそれを利用しています。

使いどころが難しいですが、入力をコンボボックス化する jQuery プラグインの実装が不便だったので、modify しました。
そもそも、jQuery のプラグインは、jQuery の インスタンスに対してのメソッドの実装です。プラグインは、jQuery の機能を借りて、そのメソッドが特有の振る舞いをするような『オブジェクト』を window の中に作りだします。
そして、再度そのオブジェクトを操作する為にそのオブジェクトを参照する必要があるので、どこかに保存しなければなりません。
当然、再度参照するなら jQuery の インスタンスを介して( 実際はセレクタで選択されたもの )再度参照されるべきだと思います。
しかし、このプラグインでは単純に配列を作ってそこへ push していただけなので、『何番目に何が居る』かをプログラマは番号で呼び出すようになっていました。
これでは意味が無いので プラグインが作った『オブジェクト』を .data で 元の要素に保存しました。
( jQuery で console.log(typeof $("#test")); と実行すると object と表示される )
<script type="text/javascript">
function myJson() {
	this.prop = "JSON";
}

j1 = new myJson();
console.log( typeof j1 );
console.dir( j1 );

j2 = { prop: "JSON" };
console.log( typeof j2 );
console.dir( j2 );
</script>


さらに、new でインスタンスが作成された時に、プロパティとして持っているものは function 内で this で定義する事になっていますが、これは、function の名前に対する prototype に インスタンスをセットしてもいい事になっているので、こんな書き方ができる事になります。
<script type="text/javascript">
function myJson1() {
}
function myJson2() {
	this.prop = "JSON";
}

myJson1.prototype = new myJson2();

j1 = new myJson1();	  // 本体にプロパティは無い
console.dir( j1 );        // プロトタイプに prop があります
console.log( j1.prop );   // JSON と表示される
</script>
さらに、ほんの少し書き方が違いますが、以下のようにしても同じ結果を得る事ができます。

call メソッドは、他の『クラス』の実際に記述されているプロパティに対して効果があるので、継承したいプロパティは function 内に書いておく必要があります。

つまり、結果が同じようでいて、JSON フォーマットの記述である『オブジェクト』ではできない事が function で書くと可能になるという事です。
<script type="text/javascript">
function myJson1() {
	myJson2.call( this );
}
function myJson2() {
	this.prop = "JSON";
}

j1 = new myJson1();	  // 本体にプロパティは無い
console.dir( j1 );        // 本体に prop があります
console.log( j1.prop );   // JSON と表示される
</script>


タグ:javascript JSON
posted by lightbox at 2013-03-22 01:10 | JavaScript オブジェクト | このブログの読者になる | 更新情報をチェックする

2012年06月16日


JavaScript による半角と全角の相互変換(カタカナを除く)完成版

ちょっと必要だったのでインターネットでライブラリ無いか調べてみたら、特に無い上に完成版が無かったので完成させてみました。

s.charCodeAt(0) - 0xFEE0 というのをやってらっしゃった方が居られたので、これがベストだと思いましたが、何故か数字とアルファベットの範囲指定されておられたので一括で文字範囲指定しました。あと、名前空間で関数名が衝突しないようにしてあります。( lboxtool は自由に変える部分です )

※ 円マークがバックスラッシュになるのは仕様なので必要ならば改造すればいいと思います
<script type="text/javascript">
window.lboxtool={
tohan : function(str) {
	return str.replace(/[!-〜]/g, function(s) {
	    return String.fromCharCode(s.charCodeAt(0) - 0xFEE0);
	});
}
,
tozen : function(str) {
	return str.replace(/[\!-\~]/g, function(s) {
		return String.fromCharCode(s.charCodeAt(0) + 0xFEE0);
	});
}
}
</script>
<input type="button" value="半角に" onclick='document.getElementById("target").value=lboxtool.tohan(document.getElementById("target").value)'>
<input type="button" value="全角に"onclick='document.getElementById("target").value=lboxtool.tozen(document.getElementById("target").value)'>
<br />
<textarea id="target" style='width:400px;height:80px;'>!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~</textarea>





posted by lightbox at 2012-06-16 09:42 | JavaScript オブジェクト | このブログの読者になる | 更新情報をチェックする

2012年04月19日


Three.js で行われている整然としたクラス作成

Three.js は、Canvas や WebGL を使った 3D を表現するライブラリですが、中を読むのに
このようなクラス定義が基本なので非常に解りやすいです。
<!doctype html>
<html lang="en">
	<head>
		<title>サンプル</title>
		<meta charset="utf-8">
		<style>
		</style>
	</head>

<body>
<script>
var R101 = {};
R101.Class = function(){
	this.version = "1.01";
	this.colors = [];
	this.flg = false;
};
R101.Class.prototype = {
	constructor: R101.Class,
	method1: function() {
		alert("method1:"+this.version);
	},
	method2: function() {
		alert("method2:"+(this.data||"未定義です"));
	},
	method3: function() {
		alert("method3:"+this.flg);
		this.data = {};
	}
}

var obj = new R101.Class();

</script>

<input type="button" value="method1" onclick="obj.method1();" />
<input type="button" value="method2" onclick="obj.method2();" />
<input type="button" value="method3" onclick="obj.method3();" />
</body>
</html>
まず、R101 と言う名前空間を作成していますが、一般的にライブラリを作成する時に有効で、
変数が他から独立して作成されるようになります。R101 は、一般的な JavaScript のオブジェク
トになります。そこに、R101.Class として、function を定義しています。
( ※ R101.Class では、this で変数を作成して、後に作成されるインスタンスで参照されます。)

R101.Class.prototype に、JavaScript のオブジェクトを設定し、そのメンバとして、コンストラ
クタとメソッドを定義しています。ここで、たとえ prototype の設定をしなくても、コンストラ
クタは R101.Class になり、以下の実行を行うと一致します

if ( R101.Class === obj.constructor ) {
	console.log("一致");
}

しかし、それではメソッドの定義を R101.Class 内でする事になり、記述上コンストラクタとメソ
ッドとプロパティの定義がごちゃ混ぜになってしまいますが、この場合だと見事に3か所に分けて
定義できますし、後から見ても一目瞭然となります。

Windows8 Metro JS SDK でもよく使われていた || の意味

alert("method2:"+(this.data||"未定義です"));

この || は最後に true 扱いになったものを利用すると言う意味で、this.data が
定義されていた場合はその中を表示しますが、未定義の場合は "未定義です" のみを
表示します


posted by lightbox at 2012-04-19 22:11 | JavaScript オブジェクト | このブログの読者になる | 更新情報をチェックする

2012年02月11日


JSON オブジェクトの stringify メソッドの第3引数の使い方

JSON.stringify Function (JavaScript)

上記リンク先は Microsoft の英文ドキュメントです。IE に関しては、IE8 と IE9 の
標準モードで動作します。
Supported in the following document modes: Internet Explorer 8 standards,
Internet Explorer 9 standards. Not supported in the following document 
modes: Quirks, Internet Explorer 6 standards, Internet Explorer 7 standards.
Firefox、Google Chrome、Opera、Safari のいずれでも動作します。
<script type="text/javascript">
alert(JSON.stringify( {"type": 1, "name": "test", "obj":{"level": 2,"value": 1},"arr": [1,2,3]},null,4));
</script>
コードのテスト

■ 第3引数は省略されると、スペース無しで文字列が作成されます
■ 第3引数が数字の場合は、その数のスペースでインデントされて整形されます
■ 第3引数に何か文字列が入っている場合は、その文字列でインデントされます
(その際、"\t" 等が適当です)
■ 第3引数が文字列の場合、最初の10文字が使用されます



タグ:JSON
posted by lightbox at 2012-02-11 20:25 | JavaScript オブジェクト | このブログの読者になる | 更新情報をチェックする

2011年11月26日


JS : 自分用名前空間を使ってページのロードイベントを登録

IE8 までは、attachEvent しかありませんでしたが、IE9 では
addEventListener が使えるのでこんな感じでいいかと思います

window['文字列'] は、
var 文字列 と同等です。その中に {} でオブジェクトを作成して onload
プロパティを定義しています。中身は function で無名関数を登録です。

※ 使用時は、lightbox.onload で参照しています
<script type="text/javascript">
window['lightbox'] = { onload: function() {
		alert('ロードされました');
	}
};

if ( window.addEventListener ) {
	window.addEventListener('load', lightbox.onload, false);
}
else {
	window.attachEvent('onload', lightbox.onload);
}
</script>


posted by lightbox at 2011-11-26 22:45 | JavaScript オブジェクト | このブログの読者になる | 更新情報をチェックする

2011年11月12日


Object.prototype が window オブジェクトに適用されるおはなし

このコードが IE9 で動きました。IE以外では全部動いてます。


<script type="text/javascript">
Object.prototype.myVersion = "lightbox 1.1"
Object.prototype.log = function(str){try{console.log(str)}catch(e){}}

window.log(window.myVersion);
window.log("おーーい");
</script>


posted by lightbox at 2011-11-12 15:10 | JavaScript オブジェクト | このブログの読者になる | 更新情報をチェックする

2011年08月18日


JS : クロスドメインの IFRAME からデータを JSON 形式で引き渡す

以下には、lightbox.on.coocan.jp/message_cd.htm をIFRAME で埋め込んでいます。
当然このブログはドメインが違うので、本来ならばアクセスできませんが、postMessage
の第二引数に "*" を渡す事によって(本来は個別指定)、 どんなドメインへもメッセージ
を送る事ができます。
( 開発者ツールを開いて実行して下さい : IE8 でも動きます )

ただ、送れるメッセージは文字列で一つだけなので、送り出すほうで JSON の文字列を
用意しておいて、こちら側ではそれを eval して利用しています。お互いのドメインの
管理者か同じまたは信頼し合えるならば、この方法で多くのデータを一度にやりとりで
きるはずです。

または、IFRAME 側を、埋め込むだけでどこでも使えるような一つの完全なユニットと
して設計する為に必要です。
データを受け取る為の定義(get_post_message)
※ 実際は、js ライブラリ化して、script 要素で読み込めば使えるようにします
<script type="text/javascript">
function get_post_message(e) {
	var prop;
	var result = eval(e.data);
	try {
		if ( console.dir ) {
			console.dir(result);
		}
		else {
			for( prop in result ) {
				console.log(prop+":"+result[prop]);
			}
		}
	}
	catch(e){}
}
if ( window.addEventListener ) {
	window.addEventListener('message',get_post_message, false);
}
else {
	window.attachEvent('onmessage',get_post_message);
}

</script>
<iframe
	src="http://lightbox.on.coocan.jp/message_cd.htm"
	name="myframe"
	frameborder="1"
	scrolling="yes"
	width="300"
	height="100"
></iframe>

ユニット側
<!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">
<script type="text/javascript">
function t_message() {
	var value1 = document.getElementById("message1").value;
	var value2 = document.getElementById("message2").value;
	var objString = '({ "message1": "'+value1+'", "message2": "'+value2+'" })';
	parent.postMessage( objString, "*" );
}
</script>
</head>
<body>

<input
	type="text"
	id="message1"
	style='width:200px;'
	value="日本語表示1"
/>
<br />
<input
	type="text"
	id="message2"
	style='width:200px;'
	value="日本語表示2"
/>
<br />
<input
	type="button"
	value="post"
	onclick='t_message();'
/>

</body>
</html>



posted by lightbox at 2011-08-18 22:39 | JavaScript オブジェクト | このブログの読者になる | 更新情報をチェックする

2011年03月10日


JavaScript : 右から指定した文字数を取りだす right メソッドを String オブジェクトに追加

必要な時に定義しておくだけで良いですが、これを使って文字列の前を指定した文字列で埋めて固定長の長さの文字列を取りだす事ができます。

10文字以内の前ゼロであれば、

("0000000000"+x).right(n) ですね。

unicode メソッドは、right を使って \uxxxx という unicode 形式の文字列を作成します。これは、直接使うのでは無く、日本語文字列をキャラクタセットに依存しない文字列にする為の作業用です。
<script type="text/javascript">
String.prototype.right = function(n){
	var str = this.valueOf();
	str = str.substr(str.length-n,n);
	return str;
}
String.prototype.unicode = function() {
	var str = this.valueOf();
	var re = new RegExp("[^A-Za-z0-9_\f\n\r\t\v]","g");
	str = str.replace(re,function(s){
		var str;
		str = s.charCodeAt(0).toString(16);
		str = "0000"+str;
		str = str.right(4);
		str = "\u"+str;
		return(str);
	})
	return str;
}
</script>




posted by lightbox at 2011-03-10 15:51 | JavaScript オブジェクト | このブログの読者になる | 更新情報をチェックする

2010年11月03日


JSON と文字列の関係

外部より JSON フォーマットのデータを取得した時点では「文字列」ですから、それを JavaScript で使うようにする方法は一般的ですが、そこから「先」は結構多用で一般的では無いような気がします。

そもそも、JSON の a["a2"] は、連想配列のように見えますが、特殊文字で定義されたプロパティを参照する為の書式ですし。

また、eval 使うにあたって、配列はそのままであるとか、for in も結構実際に使うと面倒な構文であったりします。

JavaScript は、自分が知ってる言語の中では、最も難解で不可思議な機能を持ったものだと思っています。
<script type="text/javascript">
function scriptTest(evt) {

	// JSON 文字列を実体に変える一般的では無い方法
	var x = (new Function( 'return {"a1":"Finction","a2":"オブジェクトの","a3":"テスト"}' ))();
	alert(x.a1+x.a2+x.a3);

	// JSON 文字列
	var str_json = '{"a1":1,"a2":2,"a3":3}';

	// オブジェクト化
	var a = eval('(' + str_json + ')');

	// プロパティとして参照	
	alert( a.a2 );

	// 特殊文字のプロパティを参照する書式
	alert( a["a2"] );

	// 配列文字列
	var arr_str = '["a1","a2","a3"]';

	// 配列化
	a = eval(arr_str);

	// 配列として参照
	alert( a[1] );

	// 文字列リストに変換
	alert( a.join(",") );

	// リスト文字列を配列化
	a = 'a1,a2,a3'.split(",");

	// 配列として参照
	alert( a[1] );

	// 文字列リストに戻す
	alert( a.join(",") );

	// 配列を、JSON 文字列に変換
	var str = "";
	for( i = 0; i < a.length; i++ ) {
		if ( i != 0 ) {
			str += ",";
		}
		str += '"'+i+'":"'+a[i] + '"';
	}

	// オブジェクト化
	a = eval('({' + str + '})');

	// 特殊文字のプロパティを参照
	alert( a["1"] );

	// オブジェクト内のプロパティの一覧
	for( x in a ) {
		alert( x + ":" +a[x]);
	}
}
</script>
<input type="button" value="実行" onclick='scriptTest(event);'>



タグ:JSON javascript
posted by lightbox at 2010-11-03 16:15 | JavaScript オブジェクト | このブログの読者になる | 更新情報をチェックする

2010年10月14日


JavaScript : ネームスペースの作成

記述の仕方によって違ったように見えやすい仕様ですが、結局は、var x = {} で作成する事のできるオブジェクトの配列の定義を、window の下の任意の名前で定義します。

window["myname"] は、window.myname というプロパティとなり、myname.prop_or_method のような形で定義して行きます。
<!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>JavaScript</title>
<style>
* {
	font-size:16px;
}
</style>
</head>

<body>

<script type="text/javascript">
function scriptTest(obj) {
	createNameSpace("lbox","1.0","lightbox");

	lbox.msgbox("こんにちは。", lbox.version, lbox.author, obj.parentNode.innerHTML );
}
</script>
<div>
<input type="button" value="実行" onclick='scriptTest(this);'>
</div>
<script type="text/javascript">
function createNameSpace(topName,version,author) {
	if ( !window[topName] ) {
		window[topName] = {}
	}
	window[topName].version = version;
	window[topName].author = author;
	window[topName].msgbox = function(){
		var i, s="", numargs = arguments.length;
		for (i = 0; i < numargs; i++) {
			s += arguments[i] + "\n";
		}
		alert(s + "\n\n" + (new Date()).toLocaleString());
	}

}
</script>

</body>
</html>



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

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

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

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

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


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

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

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

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

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


Windows
container 終わり

フリーフォントで簡単ロゴ作成
フリーフォントでボタン素材作成
フリーフォントで吹き出し画像作成
フリーフォントではんこ画像作成
ほぼ自由に利用できるフリーフォント
フリーフォントの書体見本とサンプル
画像を大きく見る為のウインドウを開くボタンの作成

Android SDK ポケットリファレンス
改訂版 Webデザイナーのための jQuery入門
今すぐ使えるかんたん ホームページ HTML&CSS入門
CSS ドロップシャドウの参考デモ
Google Hosted Libraries
cdnjs
BUTTONS (CSS でボタン)
イラストAC
ぱくたそ
写真素材 足成
フリーフォント一覧
utf8 文字ツール
右サイド 終わり
base 終わり