SQLの窓

2016年03月09日


IFRAME 内に外部の javascript を読み込んで画面を作成する / document.write での構築

結果的には、JSONP のもっと規模の大きいもので、外部定義で WEBページを全て作ってしまう方法です。

以下の IFRAME 内のページはこのようなコードで実装されています
<input type="button" value="IFRAME 内へのアクセス" onclick='document.getElementById("cross_domain_frame").contentWindow.document.body.style.backgroundColor = "#c0c0c0"'>

<iframe
	src="about:blank"
	id="cross_domain_frame"
	style="width:600px;height:900px"
></iframe>
<script type="text/javascript">
str="<"+"script charset=\"utf-8\" src=\"http://toolbox.winofsql.jp/js/string_html.js\"></"+"script> ";
document.getElementById("cross_domain_frame").contentWindow.document.write(str);
document.getElementById("cross_domain_frame").contentWindow.document.close();
</script>
しかも、about:blank に書き込むので元々同一ドメインという事になるので、DOM で IFRAME 内へアクセスする事ができます(当然中から本体へのアクセスもできます)。また、http://toolbox.winofsql.jp/js/string_html.js の中身は全て文字列の書き込みになっていて、普通に作った HTML+CSS+JavaScript のページのコードをこちらのツールで文字列に変換しています。

※ contentWindow.document は contentDocument に書き換える事ができます
document.write で書き込んだ画面内には、さらに外部ライブラリとして jQuery や jQuery プラグインや SyntaxHighlighter が使用されていますが、正しく動作しています

本当のつかいどころ

この方法でブックマークレットから任意のページに画面を埋め込んで、そこから本体のページをコントロールするプラグインを作成できます。本体側は簡単な設定でそれを拒否する事もできますが、プラグインするのは個人なので、特定のサービス以外でそのような実装はあまり見た事がまだありません。

自分は以前、『手書きブログ』というサービスで、当時パレットが自由に設定できなかった部分をこの手法でブックマークレット経由でプラグインを作成して配布していた事がありましたが、本体の HTML 構成が変更されない限り、普通に機能を追加できます。

▼ 使用例
というわけで、『関西向け東電プレミアムプラン シュミレーション』ブックマークレットを作成しました



posted by lightbox at 2016-03-09 21:20 | JavaScript DOM | このブログの読者になる | 更新情報をチェックする

2015年01月28日


JavaScript : setTimeout の第一引数の正しい書き方。

IE10、IE11 で第三引数以降を使って関数に値を引き渡せるので、第一引数は無名関数を書くか、定義済みの関数名を書くのが正解です。但し、過去の IE9 以前の対応が必要な場合は、グローバル変数等を使用すればいいと思います。文字列は使えますが、セキュリティ上の理由から避けたほうが良いとされています。

昔の IE のマニュアルにはこう書いていたのですが、

文字列。指定されたインターバルで実行されるコード。
(  eval() を使うのと同様の理由で非推奨です / Mozilla のドキュメント より )

最新のマニュアルではこう書かれています。
( このドキュメントでは、第3引数が正しくないようです / 正解は Mozilla のドキュメントを参照 )

指定した間隔が経過したときに実行されるコードを示す関数ポインタや文字列を指定します( Microsoft の英文には API なので、実際に function pointer とあります )


▼ 無名関数


現在では関数名を記述する場所で無名関数をその場に書く事が多いですが、もちろん文字列でも動作します。文字列の場合は、処理する内容をタイマーが発生する時間に内容を確定させておく事が重要です( 全て文字列なので、それがかならずそのまま実行される事を利用します )

具体的には、関数内に値を埋め込む事で時間差の問題を解決できます。

関数名では、IE11、Firefox、Google Chrome、Opera で第三引数(関数の引数の数ぶん第4、第5と指定できます)が利用できる事を確認しています。
( IE では IE10 以降で第3引数が使用できるようです )
<script type="text/javascript">

var param = "NO!"

function startTest(param) {

	// OK はこの時点で確定です
	// ※ 文字列に startTest の引数を埋め込んでいます
	setTimeout(
		'(function(str){alert(str)})("startTestの引数:'+param+'");',
		500);

	// 第三引数で、setTimeout 実行時点の値を引き渡します
	// 関数の引数を第三引数以降で渡します
	// ( IE9 以前は実装されていません )
	setTimeout(
		function(a,b){console.log(param);alert(a+" / "+b)},
		600,
		"setTimeoutの引数:" + param,
		"ここは第4引数です");

	setTimeout(
		refTest,
		700,
		param,
		"ここは第4引数です");

	// param 内は NO! になります
	// ※ グローバルの param を参照します
	setTimeout('alert("グローバル:"+param)',1000);

}

function refTest(a,b) {

	console.log(param);
	alert("定義済み関数の参照:"+a+" / "+b)

}

startTest("OK");

</script>



posted by lightbox at 2015-01-28 06:40 | JavaScript DOM | このブログの読者になる | 更新情報をチェックする

2014年11月06日


JavaScript でクリックの代替( 古くは dispatchEvent で呼び出し )、現在は jQuery の click() ではリンクの URL を開く事はでき無いので、$("セレクタ")[0].click() 等を併用します。

現在 IE、Google Chrome、Firefox では dispatchEvent を使用しなくても click() だけで実行できるようです。元々、このメソッドは IE では古くから使用でき、特にリンクのクリックに対する代替として良く使われていたのですが、他のブラウザでは dispatchEvent を使う必要がありました( かなり昔です )

しかし、jQuery の click メソッドでは通常の click イベントは起きるのですが、a 要素の url を開く動作が実行されないという実情があります。ですから、その場合(URLを開きたい場合)だけは $("セレクタ").click() では無く、$("セレクタ").get(0).click() か、$("セレクタ")[0].click() とする必要があります
▼ 書き方の比較
<pre>
<a id="target20141106"
	target="_blank"
	href="https://www.google.co.jp/?gws_rd=ssl"
	onclick='console.log("normalイベント発生")'
>www.google.co.jp</a>

▼ ◎ うまく行きます 
<input type="button"
	value="DOMでリンクをclick()"
	onclick="document.getElementById('target20141106').click();">

▼ × うまく行きません 
<input type="button"
	value="jQueryでリンクをclick()"
	onclick="$('#target20141106').click();">

▼ ◎ うまく行きます 
<input type="button"
	value="jQueryでリンクをclick()"
	onclick="$('#target20141106').get(0).click();">
▼ ◎ うまく行きます 
<input type="button"
	value="jQueryでリンクをclick()"
	onclick="$('#target20141106')[0].click();">
</pre>

www.google.co.jp

▼ ◎ うまく行きます


▼ × うまく行きません


▼ ◎ うまく行きます


▼ ◎ うまく行きます


▼ dispatchEvent を使用した記述

2011 年の最初の頃は、Firefox で制限があったのですが、今は皆 (IE, Chrome, Firefox) 正常に動作しているようです
<script type="text/javascript">

var flg = "ノーマル";

function clickAction(id) {

	flg = "代替";

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

	if (userAgent.indexOf("msie") > -1) {
		document.getElementById(id).click();
	}
	else {
		var clickevent=document.createEvent("MouseEvents");
		clickevent.initEvent("click", true, true);
		document.getElementById(id).dispatchEvent(clickevent);
		console.log("IE以外とIE11")
	}

	flg = "ノーマル";

}

</script>
<span id="target"
  onclick='alert(flg)'
  style='cursor:pointer'>JavaScriptクリック
</span>
<input type="button"
  value="クリックのかわり"
  onClick='clickAction("target")'>
<a id="link"
  href="about:blank"
  target="_blank">通常のリンク
</a>
<input type="button"
  value="クリックのかわり"
  onClick='clickAction("link")'>




(1)JavaScriptクリック (2) (3)通常のリンク (4)
(1) は onclick で alert を呼び出しています
(2) のボタンで (1) の click イベントを呼び出しています
(3) は href で新しいウインドウを開く普通のアンカーです
(4) のボタンで (3) のイベントを呼び出しています


▼ submit ボタンに対する click() テスト

jQuery で記述すると単純な click イベントは非常にシンプルになりましたが、アンカーのURL先へのページ移動は実行されませんでした

※ しかし、submit ボタンによる form の処理は実行されました
<script>
$(function(){
	$("#submit_button").val("送信")
	.click(function(){
		$("#target2").click();	
	});
});
</script>

<span id="target2"
  onclick='alert("ここを実行")'
  style='cursor:pointer'>JavaScriptクリック
</span>
<form target="_blank">
  <input id="submit_button"
    type="submit"
    name="submit">
</form>
<input type="button"
  value="JavaScript 送信"
  onclick='$("#submit_button").click()'>


JavaScriptクリック
● 一番上をクリックすると、JavaScript だけの実行
● 真ん中(submitボタン)をクリックすると、一番上をクリックした事にして、さらに通常の送信

一番下(ただのbutton)をクリックすると、真ん中をクリックした事になって、さらに連動して一番上もクリックした事になります


posted by lightbox at 2014-11-06 15:06 | JavaScript DOM | このブログの読者になる | 更新情報をチェックする

2014年03月26日


JavaScript : リンクから _blank で開いたページを JavaScript で閉じる場合の動作テスト



要点は、IE が window.close だけでは「確認用のメッセージボックス」を表示する為、そのチェックを回避するコードが他のブラウザでどうなるのか試す事が目的です。結果は結構多彩になりました。単純にリンクで開かれたウインドウ内で処理する場合は、IE 以外は同じ動作をするのですが、新しく開かれたページの中の IFRAME のアクセスと、ブックマークで開かれた IFRAME 内のアクセスで結構いろいろ違いが出ました( Chrome と Safari は 同じです )

閉じるボタンが配置されたテストページ 

以下のコードをテストします。
(window.open("","_self")).close();

以下はこのページに埋め込まれた IFRAME で、window を parent に変更しています。
当然このページとは別のドメインなので、両方ともエラーになると思ったのですが、実際はそうでは無く不思議な事に別ドメインから親ページを閉じれる傾向があると解りました。逆に、閉じれなかったのは Firefox のみで、IE は、単純な close ですと、常に確認用のメッセージボックスが表示されます。

IE だけに関して言うと、window.close() でメッセージボックスが表示される仕様となっているので、業務アプリ的には、こちらのほうがありがたいのは言うまでもありませんが、なかなか不思議な結果となっています。

以下は、動的に作成した IFRAME 内のボタンです。ブログでは同一ドメインのページを保存できないので代替えです。
この処理では、同一ドメインのはずなのですが、傾向としては parent.close() がほぼ使えないという結果になってはいます。ただ、どんな場合もメッセージ付きで IE では動作します。また、IE と、Webkit では共通して
(window.open("","_self")).close(); の処理は意味がある事になるようです。



posted by lightbox at 2014-03-26 13:14 | JavaScript DOM | このブログの読者になる | 更新情報をチェックする

2014年03月06日


JavaScript : ブラウザの表示を半透明で暗くする方法( scrollHeight で高さ決定 )





上に DIV を重ねるのでそのままではなにもできなくなりますので、さらに手前にコントローラーを作成するのが通常ですが( Lightbox ) 元に戻すには、追加した div を削除する必要があります。

IE に関しては、IE11 の 開発者ツールで各バージョンで確認しました。
var ds = document.createElement('div');
ds.setAttribute('id','ds')
ds.style.position='absolute';
ds.style.width=Math.max(document.documentElement.scrollWidth,document.body.scrollWidth)*2+'px';
ds.style.height=Math.max(document.documentElement.scrollHeight,document.body.scrollHeight)*2+'px';
ds.style.left='0px';
ds.style.top='0px';
var userAgent = window.navigator.userAgent.toLowerCase();
if (userAgent.indexOf("msie") > -1) {
	ds.style.display = 'none';
	var appVersion = window.navigator.appVersion.toLowerCase();
	if (appVersion.indexOf("msie 10.0") > -1) {
		ds.style.backgroundColor = '#000000';
		ds.style.opacity=.5;
	}
	else {
		ds.style.backgroundColor = '#000000';
		ds.style.filter='alpha(opacity=50)';
	}
}
else {
	ds.style.backgroundColor = '#000000';
	ds.style.opacity=.5;
}
document.body.appendChild(ds);
if (userAgent.indexOf("msie") > -1) {
	ds.style.display = '';
}



タグ:javascript
posted by lightbox at 2014-03-06 22:44 | JavaScript DOM | このブログの読者になる | 更新情報をチェックする

2014年02月27日


JavaScript DOM と jQuery : エレメントの参照

いくつかの一般的な参照方法と、最近知った id をそのまま使う方法(IE以外)と、jQuery を使った参照です


▼ jQuery

<script>
if ( !window.jQuery ) {
	if ( typeof window[window.location.hostname+'.loadjQuery'] === 'undefined' ) {
		if ( window.addEventListener ) {
			window[window.location.hostname+'.loadjQuery'] = '//ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js';
		}
		else {
			window[window.location.hostname+'.loadjQuery'] = '//ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js';
		}
	}
	document.write("<"+"script src=\"" + window[window.location.hostname+'.loadjQuery'] + "\"></"+"script>");
}
</script>
<form name="frm">
<input type="text" id="fld_id" name="fld_name" value="ABC">
</form>

<input type="button" value="FORM参照" onclick='alert(frm.fld_name.value)'>
<input type="button" value="IE以外で簡易id参照" onclick='alert(fld_id.value)'>
<input type="button" value="id参照" onclick='alert(document.getElementById("fld_id").value)'>
<input type="button" value="name参照" onclick='alert(document.getElementsByName("fld_name")[0].value)'>
<input type="button" value="tag参照" onclick='alert(document.getElementsByTagName("input")[0].value)'>
<br>
<br>▼ jQuery<br>
<input type="button" value="jQuery参照" onclick='alert($("#fld_id").val())'>
<input type="button" value="jQueryのDOM参照1" onclick='alert($("#fld_id").get(0).value)'>
<input type="button" value="jQueryのDOM参照2" onclick='alert($("#fld_id")[0].value)'>

tag 参照は、同じ要素が複数あるページでは先頭以外でうまくいきません。このページでは実際には以下のように記述しています
alert(document.getElementsByName("frm")[0].getElementsByTagName("input")[0].value)
目的の要素を含む要素で確定させておいて、その中の同じ要素の何番目かという選択をします


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

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

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

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

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


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

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

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

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

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



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

CSS ドロップシャドウの参考デモ
イラストAC
ぱくたそ
写真素材 足成
フリーフォント一覧
utf8 文字ツール
右サイド 終わり
base 終わり