SQLの窓

2017年11月13日


HTML 上のデータをローカルに保存する jQuery プラグイン

FileSaver.js が必要です。

保存タイプ

1) text 
    要素の内部テキストを取得( value または innerText )
    ※ nobom プロパティを true にすると UTF8N で保存されます
    ( nobom のデフォルトは false )

2) html
    要素の outerHTML を取得

3) table
    テーブル要素を csv データとして取得
    ※ nobom プロパティを false にして UTF8 で保存する事によって、Excel で読み込めます
    ( nobom のデフォルトは false )

4) image (URL で指定された画像の場合)
    そのままそのサーバーからダウンロード
    IE が、A 要素の download 属性をサポートしていないので IE は 不可
    ( ie プロパティでその際のエラーメッセージ指定できます )

5) image (base64 で指定された画像の場合)
    base64 をバイナリに変換して保存


所属コード所属名称作成日更新日
0001営業部第一2004/05/052004/05/05
0002営業部第二2004/05/052004/05/05
0003営業部第三2004/05/052004/05/05
1001総務部2008/04/022008/04/02

デモ用のコード
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/FileSaver.js/1.3.3/FileSaver.js"></script>
<script src="https://lightbox.sakura.ne.jp/demo/template/lightbox-env/saver.js"></script>
<script>
$(function(){

	$("#btn_text")
		.on( "click", function(){
			$("#textarea").save( {
				type : "text",
				name : "mydata.txt",
				nobom : true
			} );
		});

	$("#btn_tbl")
		.on( "click", function(){
			$("#tbl").save( {
				type : "table",
				name : "mydata.csv",
				nobom : false
			} );
		});

	$("#btn_html")
		.on( "click", function(){
			$("body").save( {
				type : "html",
				name : "mydata.html",
				nobom : true

			} );
		});

	// IE は対象外
	$("#btn_img")
		.on( "click", function(){
			$("#img").save( {
				type : "image",
				ie: "IE では画像を右クリックしてメニューから保存して下さい"			// IE 用メッセージ
			} );
		});

	// IE も OK
	$("#btn_base64")
		.on( "click", function(){
			$("#base64").save( {
				type : "image"
			} );
		});

	$("#btn_img,#btn_text,#img,#textarea,#base64,#btn_base64")
		.css({ "display": "inline-block", "vertical-align": "top" });

	$("#tbl")
		.css({ "margin-top": "15px" });


});


</script>
<div>
<input id="btn_text" type="button" value="textarea(テキスト)">
<input id="btn_tbl" type="button" value="テーブル(CSV)">
<input id="btn_html" type="button" value="BODY(HTML)">
<input id="btn_img" type="button" value="画像(URL)">
</div>
<div style='margin-top:10px'>
<input id="btn_base64" type="button" value="画像(base64)">
<img id="base64"  src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABkAAAAZCAYAAADE6YVjAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAASdSURBVEhLlVZ/TNRlGP/ccSRwcMkEhLWgVAItwDxysaWLVmKj8aN/GvRjiYFzyq9qE2uJILUkJhtji2BOc9ay1ejXGIOkBsEKuqSrtSRS2ik/5owxjsjweHre5/3CHcpN+YwP73PP+3nf5/3xvM8daCX4oYPo5aeIvvnUcNwebh1kdoboWBnRAyxNYNqZicyNzHf2cb/bEPoHK/2g50ui/CSiWJaoAEnMzaCT60060IPMZKbqf26z3qUfsMIHnut61WpCtepUZhrzIebJN+jj480EgBr3FxC9lqmDPWLWuvuYW5jNh4zJvOBlcaQFVOQCn38GRLI9H4Devz34MTgav2x/FiOXLsPZ14Mro5dhi1yLjWnbcNe1SWxynsVWmwlPhptgCZwHxtQ8h4HdlTKlQEIZmLkHVBYNWh0AWfFKucoEKo0CudXOfOD91Npw06Ds7Gyqra2ljo4OcrlchlBjfHycuru7qb6+XnQWi2XJWPq9z1D6HtcTVpi//kcUJSUlKC8vx9zcHOLj46VboaurC4GBgTCZTDCbzeCJ5bPVasXIyAgyMjJgZt2BNcBb+elAQ5ceKKGGBoniQb33e1fiS6fTSbGxscv23chT9khOBp42zntI2irdSZTCJqfkhUujiwNyc3OlTU5OJofDQTk5OZSXlye+sLAwSk9PFzslJYUSEhLE7u3p0e+IF0wnamR6HYQvXILU7CLHBZeIMzM5RRnKVrvwhfIlJSXR4OCg2E1NTVRVVSW2468xold4rHpDD3N6Kz2dadBR1zEnx+ls93ciLiws1AK24+LixB4eHqbi4mLx2Ww22rFjh9ipqakUEREh9sTkFJFrSI6fNjCHznEQ9ar5JdNOPksGX66ICwr4wTGUnZiYSKOj3mP0x6ioKBkj2MRzqtN5/Rky4+m9wBxL/rjC/xgBFt36ICQkBHV1dWKXlpZKyytHf38/2tvb0dbWhoGBAUxMTEgf+toAD7f/MbdlcXgFdSeqlLxbQV2On2VVvjux2+3EaS22SgDVxsTESP+yeGGLrm2q1DBUWgNZGZAEb34bXBvE5QvWge9A7KCgIGnHxlT9WAae68C3P+mdPL9LXDrI3jcBN7cm5nuHxOULFSQ4OFjs6elpcOaJXV1dLe0SNB4A7uR2irm/Vlw6SKIdiOYd8J+l8xNxzc9zsTOgXvbMzIzYHo8Hra2tYldWVqKlpUXsRbQc4wHcpm4AVkeISwdR2FMD/Au4SG0HCF2jBQput1suVoEfnZQSrmfyuaioSErP985fgYGvxIdZ5r6j2laQmzEwtd6bjsMfNYtv7br4Rd8Ncvrz4kXCKuuS/oMxoFm/VZixIMwPZ7d6sY+G0GDFi4v+Ex98aCh90Pk+NfHEAYZmgb5Y8qX1asVBhF1zo7K/EbjKjhDmHcARF9+FNRSHf+OMsoTypXJnfRlw+jSnG2usTH4T5yfZvTUHofcmoO4oZ+oCJNRy6DxD9Hi4LjcLX8PKfsymW/WuFFW1zbqbqO2UMfBmsOIWOH+OaM92/YNBTapKhaqy6jdAzW6iq+OG0D9YuQIcP0L0UhpR9xeG43ZA9D+D0zyeXYGzAwAAAABJRU5ErkJggg==">
<img id="img" src="http://toolbox.winofsql.jp/image/jquery.png">
<textarea id="textarea">あいうえお</textarea>
</div>

<table id="tbl">
<tbody><tr><th>所属コード</th><th>所属名称</th><th>作成日</th><th>更新日</th></tr>
<tr><td>0001</td><td>営業部第一</td><td>2004/05/05</td><td>2004/05/05</td></tr>
<tr><td>0002</td><td>営業部第二</td><td>2004/05/05</td><td>2004/05/05</td></tr>
<tr><td>0003</td><td>営業部第三</td><td>2004/05/05</td><td>2004/05/05</td></tr>
<tr><td>1001</td><td>総務部</td><td>2008/04/02</td><td>2008/04/02</td></tr>
</tbody></table>


saver.js

$.fn.extend({

	save : function(option){

		option = option || {};
		var type = option.type || "text";
		var mime = option.mime || "text/plain";
		var name = option.name || "save.txt";

		var charset = "utf-8";
		var nobom = option.nobom || false;

		if( type == "text" ) {
			var text = $(this).val();
			if ( text == "" ) {
				text = $(this).text();
			}
			saveAs(
				new Blob(
					[text]
					, {type: mime + ";charset=" + charset}
				)
				, name, nobom
			);

		}

		if( type == "html" ) {
			var text = $(this).prop("outerHTML");
			saveAs(
				new Blob(
					[text]
					, {type: mime + ";charset=" + charset}
				)
				, name, nobom
			);
		}

		if( type == "table" ) {
			var csv = "";
			var cnt = 0;
			$(this).find("tr").each( function(){

				$(this).find("td,th").each(function( col_cnt ){
					if ( col_cnt != 0 ) {
						csv += ",";
					}
					csv += "\"" + $(this).text() + "\"";
				});
				csv += "\n";
				cnt++;

			} );
			saveAs(
				new Blob(
					[csv]
					, {type: mime + ";charset=" + charset}
				)
				, name, nobom
			);
		}

		if( type == "image" ) {
			var src = $(this).prop("src");
			// base64 bin
			if ( src.substr(0,5) == "data:" ) {
				var bin = atob(src.split(',')[1]);
				var head = src.split(',')[0];
				var type = head.split(/[:;]/)[1];
				var buffer = new Uint8Array(bin.length);
				for (var i = 0; i < bin.length; i++) {
					buffer[i] = bin.charCodeAt(i);
				}
				var blob = new Blob([buffer.buffer], {type: type});
				if ( type == "image/jpeg" ) {
					name = "save" + (new Date()).getTime()+".jpg";
				}
				if ( type == "image/gif" ) {
					name = "save" + (new Date()).getTime()+".gif";
				}
				if ( type == "image/png" ) {
					name = "save" + (new Date()).getTime()+".png";
				}
				saveAs( blob, name );
			}
			// url
			else {
				var userAgent = window.navigator.userAgent.toLowerCase();
				// OLD IE
				if (userAgent.indexOf("msie") > -1) {
					if ( typeof option.ie !==  'undefined' ) {
						alert(option.ie);
					}
					else {
						alert("unsupported!");
					}
					return;
				}
				// IE11
				else if (userAgent.indexOf("trident/7.0") > -1) {
					if ( typeof option.ie !==  'undefined' ) {
						alert(option.ie);
					}
					else {
						alert("unsupported!");
					}
					return;
				}
				else {
					var work = src.split("/");
					var name = work[work.length-1];
					var download = $("<a></a>").css("display","none").appendTo("body");
					download.prop({"href" : src, "download": name });
					download.get(0).click();
					download.remove();
				}
			}

		}

		return $(this);

	}
});





posted by lightbox at 2017-11-13 11:13 | Comment(0) | プラグイン作成(jQuery) | このブログの読者になる | 更新情報をチェックする

2017年11月06日


jQuery のプラグインで動的なコントロールの処理を作成 : add_button / set_event / set_link

add_button : 対象の直後にボタンを追加
set_event : 対象にイベントを登録
set_link : 対象のテキストをリンクに変更

set_link における p1 と p2 のオプションは、URL 内に %1 と %2 という文字列を含ませて、それぞれ p1 と p2 で置換するオプションです。Query String  として WEB アプリケーションのパラメータとして利用する事を想定していますが、URL エンコードは自分で行う必要があります

プラグインのソースコード

$.fn.extend({

	add_button : function(option){

		var input = $("<input type='button'>")
			.val( option.val )
			.insertAfter($(this))
			.on("click", option.click )
		;

		if ( typeof option.id !==  'undefined' ) {
			input.prop("id", option.id);
		}
		if ( typeof option.class !==  'undefined' ) {
			input.addClass(option.class);
		}
		if ( typeof option.css !==  'undefined' ) {
			input.css( option.css );
		}
		return $(this);

	},

	set_event : function(option){

		$(this).on(option.event, option.action );

		if ( typeof option.id !==  'undefined' ) {
			$(this).prop("id", option.id);
		}
		if ( typeof option.class !==  'undefined' ) {
			$(this).addClass(option.class);
		}
		if ( typeof option.css !==  'undefined' ) {
			$(this).css( option.css );
		}
		return $(this);

	},

	set_link : function(option){

		if ( typeof option.target ===  'undefined' ) {
			option.target = "_blank";
		}

		var text = $(this).text();
		$(this).html("");

		if ( typeof option.p1 !==  'undefined' ) {
			option.url = option.url.replace("%1", option.p1 );
		}
		if ( typeof option.p2 !==  'undefined' ) {
			option.url = option.url.replace("%2", option.p2 );
		}

		var a = $("<a>")
			.prop("href", option.url)
			.prop("target", option.target)
			.text( text );
		;

		if ( typeof option.class !==  'undefined' ) {
			a.addClass(option.class);
		}

		if ( typeof option.css !==  'undefined' ) {
			a.css( option.css );
		}

		$(this).append(a);
		return $(this);

	}
});


add_button のサンプルコード
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="https://lightbox.sakura.ne.jp/demo/template/lightbox-env/helper.js"></script>
<script>

$(function(){

	// ボタン追加
	$("#target").add_button({
		"id" : "new_button",
		"val" : "追加されたボタン",
		"class" : "btn btn-primary ml-5",
		"css" : { "background-color" : "navy", "color" : "white"  },
		"click" : function(){
			alert("クリックされました");
		}
	});
	

});

</script>

<span id="target">テキスト表示</span>

add_button で作成された HTML
<input type="button" value="追加されたボタン" id="new_button" class="btn btn-primary ml-5" style="background-color: navy; color: white;">

set_event のサンプルコード

このサンプルは、テーブルの表示を JSON から作成している処理の一部です。obj["所属"] には4桁の数字文字列が入っています。
		col_data = $("<td></td>").appendTo( row_data );
		col_data.text( obj["所属"] );
		col_data.set_event({
			"css" : { "text-decoration": "underline", "cursor": "pointer" },
			"event" : "click",
			"action" : function(){
				window.open("../syozoku-upd/syozoku.php?code=" + obj["所属"] );
			}
		});



set_link のサンプルコード

このサンプルも、テーブルの表示を JSON から作成している処理の一部です。
		col_data = $("<td></td>").appendTo( row_data );
		col_data.text( obj["社員コード"] );
		col_data.set_link({
			"url" : "../syain-upd/syain.php?code=%1",
			"p1" : obj["社員コード"]
		});




posted by lightbox at 2017-11-06 11:18 | Comment(0) | プラグイン作成(jQuery) | このブログの読者になる | 更新情報をチェックする

2017年10月29日


TD 内のテキストを入力可能にする tableinput.js / jQuery プラグイン

テーブルの TD 要素の中がテキストのみの場合、tableinput.js プラグインで入力可能になります

オプションを省略したり、rowstart を省略すると、先頭の行を対象外にします。( rowstart の デフォルトは 1 )

tableinputEach によってテーブルの一覧を td のコレクション(jQuery のオブジェクト)単位で取得します

td.data("change") で、データが変更されたかどうかを取得できます
td.data("text") で最初のデータを取得できます

▼ 画像


▼ デモ実行
コード 氏名 フリガナ
0001 浦岡 友也 ウラオカ トモヤ
0002 山村 ひろよ ヤマムラ ヒロヨ
0003 多岡 冬行 タオカ フユユキ
0004 高田 冬美 タカタ フユミ
0005 内高 友之 ウチタカ トモユキ

上のデモのコード
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="https://lightbox.sakura.ne.jp/demo/template/lightbox-env/tableinput.js" charset="utf-8"></script>
<style>
.inputtd {
	text-decoration: underline;
	cursor: crosshair;
	background-color: pink;
}
.tableinput {
	font-family: Arial, Helvetica, Verdana, "ヒラギノ角ゴPro W3", "Hiragino Kaku Gothic Pro", Osaka, "メイリオ", Meiryo, "MS Pゴシック", sans-serif;
	font-size: 16px;
}

#target_table {
	border-collapse: collapse;
	border: solid #c0c0c0 1px;
	background-color: #FFFFFF;
}
#target_table  th {
	padding: 10px;
	border: solid #808080 1px;
	background-color: silver;
}
#target_table td {
	padding: 10px;
	border: solid #c0c0c0 1px;
}
</style>
<input type="button" id="tableinput_action" value="実装">
<input type="button" id="tableinput_check" value="変更の確認" disabled>
<table id="target_table">
<tbody>
	<tr>
		<th>コード</th>
		<th style='width:200px'>氏名</th>
		<th style='width:200px'>フリガナ</th>
	</tr>
	<tr>
		<td>0001</td>
		<td>浦岡 友也</td>
		<td>ウラオカ トモヤ</td>
	</tr>
	<tr>
		<td>0002</td>
		<td>山村 ひろよ</td>
		<td>ヤマムラ ヒロヨ</td>
	</tr>
	<tr>
		<td>0003</td>
		<td>多岡 冬行</td>
		<td>タオカ フユユキ</td>
	</tr>
	<tr>
		<td>0004</td>
		<td>高田 冬美</td>
		<td>タカタ フユミ</td>
	</tr>
	<tr>
		<td>0005</td>
		<td>内高 友之</td>
		<td>ウチタカ トモユキ</td>
	</tr>
</tbody>
</table>
<div id="result"></div>
<script>
$("#tableinput_action").on("click", function(){
	$("#target_table")
		.tableinput({ "inputwidth": "180px", "maxlength": 50, "col": 1, "class": "inputtd", "inputclass": "tableinput" })
		.tableinput({ "inputwidth": "180px", "maxlength": 50, "col": 2, "class": "inputtd", "inputclass": "tableinput" })
	;

	$(this).prop("disabled", true );
	$("#tableinput_check").prop("disabled", false );
});

$("#tableinput_check").on("click", function(){

	var text = "";
	$("#target_table").tableinputEach(function(i,row){

		// 1行目を処理しない
		if ( i == 0 ) {
			return;
		}

		// row は、td のコレクション
		var td1 = row.eq(1);
		var td2 = row.eq(2);

		// データが変更されていた場合
		if ( td1.data("change") || td2.data("change") ) {

			text +=  i + " : " + td1.text() + " : " + td2.text();
			text +=  " / 元データ : " + td1.data("text") + " : " + td2.data("text") + "<br>";

		}

	});

	$("#result").html(text);

});
</script>

tableinput.js のコード

$.fn.extend({
	tableinput : function(option){

		option = option || { "rowstart":1, "col": 0 };
		if ( typeof option.rowstart ===  'undefined' ) {
			option.rowstart = 1;
		}
		if ( typeof option.col ===  'undefined' ) {
			option.col = 0;
		}

		this.data("tableinput_option_" + option.col, option);

		this.find("tr").each(function(i){

			if ( i < option.rowstart ) {
				return;
			}

			var td = $(this).find("td").eq(option.col);
			if ( typeof option.class !==  'undefined' ) {
				td.addClass( option.class );
			}

			var text = td.text();
			td.data("text", text );

			td.on("click", function(){
				if ( $(this).data("input") != "use" ) {
					// 入力切替えフラグ
					$(this).data("input", "use" );
					// 入力内容
					var text_now = $(this).text();
					// TD の表示を消去
					$(this).text("");
					// 入力を追加
					var input = $("<input>")
							.appendTo($(this)) // TD に追加
							.val(text_now) // テキストセット
							.focus() // フォーカスセット
							// focusout で元に戻す
							.on( "focusout", function(){
								// 現在の入力
								var text = $(this).val();
								// 親 TD
								var td = $(this).parent();
								// データが変更されていたら『変更フラグ』をセット
								if ( text != td.data("text") ) {
									td.data("change", "yes");
								}
								else {
									td.data("change", "");
								}
								// TD に値を戻して 切替えフラグを消去
								td
									.append(text)
									.data("input", "" );
								// INPUT を削除
								$(this).remove();
							});
					if ( typeof option.inputwidth !==  'undefined' ) {
						input.css("width", option.inputwidth );
					}
					if ( typeof option.maxlength !==  'undefined' ) {
						input.prop("maxlength", option.maxlength );
					}
					if ( typeof option.inputclass !==  'undefined' ) {
						input.addClass( option.inputclass );
					}

				}
			});
		});
		// 自分自身を返す
		return this;
	},
	tableinputEach : function(func){

		this.find("tr").each(function(i){

			func(i,$(this).find("td"));

		});

	}
});



関連する記事

テーブルのTDをクリックしたら、INPUT で値を変更可能にして、元の値と違うものにはフラグを立てる処理を絵で書いて説明してみました





posted by lightbox at 2017-10-29 14:03 | Comment(0) | プラグイン作成(jQuery) | このブログの読者になる | 更新情報をチェックする

2015年07月27日


スマホとPC で別の処理を記述できる jQuery のストリートビュープラグイン

スマホ対応をする為 userAgent の文字列を内部で使用していますが、StreetViewOnSh メソッドと StreetViewOnPc メソッドの引数としても再度渡しています。さらに、StreetView メソッドで作成した StreetViewPanorama クラスのインスタンスも引数として渡しているので、未実装の処理も追加で簡単に記述できます 
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
<script src="https://maps.googleapis.com/maps/api/js?v=3.exp&sensor=false"></script>
<script>
$.fn.extend({
	StreetView : function(a,b){
		var pos = new google.maps.LatLng(a,b);
		// jQuery オブジェクトに StreetViewPanorama をセット(後で使用します)
		this
			.data( "pano", 
				new google.maps.StreetViewPanorama(
					this[0],
					{ position: pos }
				)
			);
		// プラグインの戻り値の無い処理の標準仕様として自分自身を返す
		return this;
	},
	// 向き	と 上下 の値をセットします
	StreetViewPov : function(a,b){
		var pov = {
			heading: a,  
			pitch: b 
		}
		// jQuery オブジェクトにセットした StreetViewPanorama を使用しています
		this.data( "pano" ).setPov(pov);
		// プラグインの戻り値の無い処理の標準仕様として自分自身を返す
		return this;
	}, 
	// 拡大率をセットします( 0 〜 5 / 小数以下あり )
	StreetViewZoom : function(a){
		// jQuery オブジェクトにセットした StreetViewPanorama を使用しています
		this.data( "pano" ).setZoom(a);
		// プラグインの戻り値の無い処理の標準仕様として自分自身を返す
		return this;
	},
	StreetViewOptions( a ) {
		// jQuery オブジェクトにセットした StreetViewPanorama を使用しています
		$( this ).data( "pano" ).setOptions(a);
		// プラグインの戻り値の無い処理の標準仕様として自分自身を返す
		return this;
	},
	StreetViewOnSh: function( callback ) {
		var ua = navigator.userAgent.toLowerCase();
		if ( ua.indexOf("iphone") > -1 || ua.indexOf("android") > -1 ) {
			(callback.bind(this,ua,this.data( "pano" )))();
		}
		return this;
	},
	StreetViewOnPc: function( callback ) {
		var ua = navigator.userAgent.toLowerCase();
		if ( ua.indexOf("iphone") <= -1 && ua.indexOf("android") <= -1 ) {
			(callback.bind(this,ua,this.data( "pano" )))();
		}
		return this;
	}
	

});

$(function(){
	$('#pano_40671578')
	.StreetView(40.671578,-73.962557)
	.StreetViewPov(-128,10)
	.StreetViewOnPc( function(userAgent,StreetViewPanorama){
		// PC の場合の処理
		this.css("width","600px");
		this.css("height","400px");

		// 追加のブラウザ判定に使用する
		console.log(userAgent);
		// 実装していない処理は、直接実行
		console.log(StreetViewPanorama.getPov())
	})
	.StreetViewOnSh( function(userAgent,StreetViewPanorama){
		// スマホ の場合の処理
		this.css("cssText","width:290px!important;height:290px!important");
		this.StreetViewZoom(2.5);

		// 追加のブラウザ判定に使用する
		console.log(userAgent);
		// 実装していない処理は、直接実行
		console.log(StreetViewPanorama.getZoom())
	})
	;

	// PC と スマホ 共通な場合
	$('#pano_40671578_b')
	.StreetView(40.671578,-73.962557)
	.StreetViewPov(-106.13,8.69)
	.StreetViewZoom(2.65)
	.StreetViewOptions({
		/* addressControl: false, */
		/* zoomControl: false, */
		/* panControl: false, */
		scrollwheel: false,
		disableDefaultUI: true
	})
	.css("width","600px")
	.css("height","480px")
	.css("margin-top","10px")
	;

});
</script>
<div id="pano_40671578"></div>
<div id="pano_40671578_b"></div>
スマホの処理として、表示サイズを強制的に変更する為に important を使用していますが、これは jQuery で important 設定する方法としてかなり前から公開されているもので、一度に全ての設定を行う必要があります。
	$('#pano_40671578')
	.StreetView(40.671578,-73.962557)
	.StreetViewPov(-128,10)
	.StreetViewOnPc( function(userAgent,StreetViewPanorama){
		// PC の場合の処理
		this.css("width","600px");
		this.css("height","400px");

		// 追加のブラウザ判定に使用する
		console.log(userAgent);
		// 実装していない処理は、直接実行
		console.log(StreetViewPanorama.getPov())
	})
	.StreetViewOnSh( function(userAgent,StreetViewPanorama){
		// スマホ の場合の処理
		this.css("cssText","width:290px!important;height:290px!important");
		this.StreetViewZoom(2.5);

		// 追加のブラウザ判定に使用する
		console.log(userAgent);
		// 実装していない処理は、直接実行
		console.log(StreetViewPanorama.getZoom())
	})
	;
実際問題スマホの環境では、さらに考慮すべき事項や、複雑なサイト環境によっては IFRAME を使わざるを得ない場合があり、簡単に行くとはかぎりませんが、場合を確実に分けて記述できるメリットはあると思います。


関連する記事
jQuery のプラグインとしてストリートビューを利用する

(callback.bind(this))(); で、無名 function で使用される this に this を引き継ぐ




posted by lightbox at 2015-07-27 15:08 | プラグイン作成(jQuery) | このブログの読者になる | 更新情報をチェックする

2015年07月23日


jQuery のプラグインとしてストリートビューを利用する

とにかく、ストリートビューは何かと面倒な事が多いので、jQuery の簡潔さでどの程度表現できるかやってみました。
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
<script src="https://maps.googleapis.com/maps/api/js?v=3.exp&sensor=false"></script>
<script>
$.fn.extend({
	StreetView : function(a,b){
		var pos = new google.maps.LatLng(a,b);
		// jQuery オブジェクトに StreetViewPanorama をセット(後で使用します)
		$( this )
			.data( "pano", 
				new google.maps.StreetViewPanorama(
					$(this)[0],
					{ position: pos }
				)
			);
		// プラグインの戻り値の無い処理の標準仕様として自分自身を返す
		return this;
	},
	// 向き	と 上下 の値をセットします
	StreetViewPov : function(a,b){
		var pov = {
			heading: a,  
			pitch: b 
		}
		// jQuery オブジェクトにセットした StreetViewPanorama を使用しています
		$( this ).data( "pano" ).setPov(pov);
		// プラグインの戻り値の無い処理の標準仕様として自分自身を返す
		return this;
	}, 
	// 拡大率をセットします( 0 〜 5 / 小数以下あり )
	StreetViewZoom : function(a){
		// jQuery オブジェクトにセットした StreetViewPanorama を使用しています
		$( this ).data( "pano" ).setZoom(a);
		// プラグインの戻り値の無い処理の標準仕様として自分自身を返す
		return this;
	},
	StreetViewOptions( a ) {
		// jQuery オブジェクトにセットした StreetViewPanorama を使用しています
		$( this ).data( "pano" ).setOptions(a);
		// プラグインの戻り値の無い処理の標準仕様として自分自身を返す
		return this;
	}
});

$(function(){
	$('#pano1')
	.StreetView(40.671578,-73.962557)
	.StreetViewPov(-128,10)
	.css("width","600px")
	.css("height","400px")
	.css("margin-bottom","10px")

	$('#pano2')
	.StreetView(40.671578,-73.962557)
	.StreetViewPov(-106.13,8.69)
	.StreetViewZoom(2.65)
	.StreetViewOptions({
		/* addressControl: false, */
		/* zoomControl: false, */
		/* panControl: false, */
		scrollwheel: false,
		disableDefaultUI: true
	})
	.css("width","600px")
	.css("height","480px")
;

});
</script>
<div id="pano1"></div>
<div id="pano2"></div>
Google のサンプルはやたらと、オプションを一括で渡したがるので、とても解りにくいと思っていましたし、固定的で汎用性が無いかもしれませんが、これで十分なのでこのほうがいいかもしれません。
▼ ストリートビュー上のコントロールを排除して、マウスホイールによるズームを出来ないようにしています。
StreetViewOptions メソッドは、使用可能なオプションを後から設定しますが、ここで試しているようにいろいろな UI をキャンセルする場合に使用します。

heading と pitch と zoom は、こちらで動かしながら取得できます。画像だけで良い場合もこちらで URL を取得できます( 最後に設定変更ボタン )。




Google の API リファレンス

StreetViewPanorama class
Google Street View Image API
StreetViewPanoramaOptions



posted by lightbox at 2015-07-23 15:32 | プラグイン作成(jQuery) | このブログの読者になる | 更新情報をチェックする

2015年07月22日


jQuery の簡単なプラグインを $.fn.extend で作成( 0〜9のみ入力可能なフィールド )

プラグインとしては、一応 IE8、IE9、Chrome、Firefox、Opera、Safari で動作はしていますが、入力制限でうまく行かない場合があると洒落にならないので、実用としては考えていないコードです。

ただ、プラグインの考え方としては良く解りやすいと思います。対象となる入力フィールドに対して一括で jQuery で入力制限を行った上に、CSS で色とサイズと最大入力数も同時設定しています。

try 〜 catch が入って変な事になっているのは、IE8 に対応する為です。returnValue = false では、特にエラーになる事は無かったのですが(実際ではIEのみ実行にしたほうがよさそうです)、一応念のため。preventDefault は、IE8 以前ではエラーになるはずです。
<!-- 古いIE用に 1.9.1 を使用しています -->
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<input class="numField" type="text">
<input class="numField" type="text">
<input class="numField" type="text">
<script>

// プラグインの作成( fn.extend )
$.fn.extend({ 
	numField: function(){
		$(this).on('keydown', function(evt) {
			// *********************************
			// 以下入力を受け付けるキーの処理
			// *********************************
			// 数字( 0〜9 )
			if ( 48 <= evt.keyCode && evt.keyCode <= 57 ) {
				return;
			}
			// テンキー( 0〜9 )
			if ( 96 <= evt.keyCode && evt.keyCode <= 105 ) {
				return;
			}
			// 矢印
			if ( 37 <= evt.keyCode && evt.keyCode <= 40 ) {
				return;
			}
			// DEL
			if ( evt.keyCode == 46 ) {
				return;
			}
			// タブ
			if ( evt.keyCode == 9 ) {
				return;
			}
			// バックスペース
			if ( evt.keyCode == 8 ) {
				return;
			}
			// *********************************
			// 以下入力を受け付けないキーの処理
			// *********************************
			// 古い IE 用
			if (navigator.userAgent.toLowerCase().indexOf("msie") > -1) {
				try{
					evt.returnValue = false;
				}catch(ex){}
			}
			try{
				// イベントがキャンセル可能である場合、
				// 上位ノードへのイベントの 伝播 (propagation) を止めずに、
				// そのイベントをキャンセルします。
				evt.preventDefault();
			}catch(ex){}
		});
		// プラグインの標準仕様として実行後は自分自身を返す
		return this;
	}  
});

// プラグインの実行
$(".numField").numField()
	.css({
		"background-color":"pink",
		"width":"70px"
	})
	.attr("maxlength",6);

</script>



タグ:javascript jquery
posted by lightbox at 2015-07-22 13:22 | プラグイン作成(jQuery) | このブログの読者になる | 更新情報をチェックする

2014年11月21日


INPUT type="number" の振る舞いをブラウザ間で調整する jQuery プラグイン

INPUT type="number" の振る舞いをブラウザ間で調整する でテストした結果を元に、jQuery のプラグインを作成しました。

対応するに値するのは、Chrome と Firefox と IE11(10) だけです

ブラウザは、Google Chrome と Firefox と IE だけです。さらに、Google Chrome のスピンボタンを非表示にする為に、INPUT 要素には id が必須となっています。その場合は、後から表示するような実装はしていません。IE の場合は、スピンボタンが最初から無いので、JQuery UI の spinner を使うようにしています。ただ、IE の入力チェックが type="number" に対して他のブラウザのように動作しないので、type="text" に変更した上で、pattern 属性でチェックさせている為、0〜9 の文字しか入らない実装になっています。

※ IE9 以前で、autoNumber.js を実装するようにしました。

Opera と Safari for Windows をテストしました

どちらも問題あるので、結局 IE9 以前と同じ対応になっています。
( Safari for Windows は Apple で長い間バージョンアップされていません )


<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/jqueryui/1.10.1/themes/base/jquery-ui.css">
<script src="//ajax.googleapis.com/ajax/libs/jqueryui/1.10.1/jquery-ui.min.js"></script>
<script type="text/javascript">
$.fn.extend({ 
	type_number: function(option){

		// オプションが省略された場合の対応
		option = option || {};
		// INPUT 要素のみ対象
		if ( $(this).prop("tagName").toUpperCase() != 'INPUT' ) {
			return;
		}

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

		if ( userAgent.indexOf("msie") > -1 ) {
			if (appVersion.indexOf("msie 10.0") > -1) {
				// 'on' と 'jquery', で spinner を使う, それ以外はスピンボタン無し
				if ( option.spin == 'on' || option.spin == 'jquery' ) {
					$(this).spinner(option);
					$(this).attr( "type", "text" );
					$(this).attr( "pattern", "^[0-9]+$" );
				}
				else {
					$(this).attr( "type", "text" );
					$(this).attr( "pattern", "^[0-9]+$" );
				}
			}
			else {
				// IE9 以前で autoNumeric で数値以外を入力不可にする
				var el = this;
				var s = document.createElement("script");
				s.src="http://winofsql.jp/jquery/plugins/number/autoNumeric.js";
				if(s.addEventListener) {
					s.addEventListener("load",callback,false);
				} 
				else if(s.readyState) {
					s.onreadystatechange = callback;
				}
				document.body.appendChild(s);
				function callback() { 
					$(el).autoNumeric('init', {aSep:'',mDec:'0'});
				}
				if ( option.spin == 'on' || option.spin == 'jquery' ) {
					$(this).spinner(option);
				}
			}
		}
		else {
			if ( userAgent.indexOf("trident/7.0") > -1 ) {
				// ※ IE11
				// 'on' と 'jquery', で spinner を使う, それ以外はスピンボタン無し
				if ( option.spin == 'on' || option.spin == 'jquery' ) {
					$(this).spinner(option);
					$(this).attr( "type", "text" );
					$(this).attr( "pattern", "^[0-9]+$" );
				}
				else {
					$(this).attr( "type", "text" );
					$(this).attr( "pattern", "^[0-9]+$" );
				}

			}
			else if (userAgent.indexOf("firefox") > -1) {
				// 標準スピンボタンは 'on', spinner を使う場合は 'jquery', それ以外はスピンボタン無し
				if ( option.spin != 'on' ) {
					// spinner を使う
					if ( option.spin == 'jquery' ) {
						$(this).each(function(){
							if ( $(this).prop("type").toUpperCase() == 'NUMBER' ) {
								$(this).css({ "-moz-appearance": "textfield" });
								$(this).spinner(option);
							}
						});
					}
					else {
						$(this).css({ "-moz-appearance": "textfield" });
					}
				}

			}
			else if (userAgent.indexOf("opera") > -1) {
				// スピンボタンが表示されますが、消す方法が見つからないので
				// IE と同じく jQuery で対応したほうがよさそうです。また、
				// FORM の送信で数字以外の文字のチェックがされないので、
				// 数字のみ入力させるプラグインをさらに実装する必要があります
				// ※ autoNumeric.js は type="text" でのみ有効です
				$(this).attr( "type", "text" );

				var el = this;
				var s = document.createElement("script");
				s.src="http://winofsql.jp/jquery/plugins/number/autoNumeric.js";
				if(s.addEventListener) {
					s.addEventListener("load",callback,false);
				} 
				else if(s.readyState) {
					s.onreadystatechange = callback;
				}
				document.body.appendChild(s);
				function callback() { 
					$(el).autoNumeric('init', {aSep:'',mDec:'0'});
				}

				if ( option.spin == 'on' || option.spin == 'jquery' ) {
					$(this).spinner(option);
				}
			}
			else if (userAgent.indexOf("chrome") > -1) {
				// 標準スピンボタンは 'on', spinner を使う場合は 'jquery', それ以外はスピンボタン無し
				if ( option.spin != 'on' ) {
					// spinner を使う
					if ( option.spin == 'jquery' ) {
						$(this).each(function(){
							if ( $(this).prop("type").toUpperCase() == 'NUMBER' ) {
								$('head').append('<style>#'+$(this).attr('id')+'::-webkit-outer-spin-button,#'+$(this).attr('id')+'::-webkit-inner-spin-button{-webkit-appearance:none;}</style>');
								$(this).spinner(option);
							}
						});
					}
					// スピンボタンを非表示にする為に、スタイル要素を追加
					// ( id があるという前提と、後から表示に切り替える事は考えていない )
					else {
						$(this).each(function(){
							if ( $(this).prop("type").toUpperCase() == 'NUMBER' ) {
								$('head').append('<style>#'+$(this).attr('id')+'::-webkit-outer-spin-button,#'+$(this).attr('id')+'::-webkit-inner-spin-button{-webkit-appearance:none;}</style>');
							}
						});
					}
				}
			}
			else if (userAgent.indexOf("safari") > -1) {
				// Google Chrome の劣化版でした。そもそも最近に
				// バージョンアップされていない気がします。コード
				// 自体は Google Chrome と同じで見た目は同様の
				// 結果になりますが、FORM の送信で数字以外の文字
				// のチェックがされないので、数字のみ入力させる
				// プラグインをさらに実装する必要がありますが、
				// autoNumeric.js は type="text" でのみ有効なの
				// で、Opera と同じコードになります

				$(this).attr( "type", "text" );

				var el = this;
				var s = document.createElement("script");
				s.src="http://winofsql.jp/jquery/plugins/number/autoNumeric.js";
				if(s.addEventListener) {
					s.addEventListener("load",callback,false);
				} 
				else if(s.readyState) {
					s.onreadystatechange = callback;
				}
				document.body.appendChild(s);
				function callback() { 
					$(el).autoNumeric('init', {aSep:'',mDec:'0'});
				}

				if ( option.spin == 'on' || option.spin == 'jquery' ) {
					$(this).spinner(option);
				}

			}
			else {
			}
		}

	}
});

$(function(){
	$("#num1").type_number( { spin: "off" } );
	$("#num2").type_number( { spin: "on" } );
	$("#num3").type_number( { spin: "jquery" } );
});

</script>

<style type="text/css">
* {
	font-family: "メイリオ", Meiryo, "MS Pゴシック";
	font-size: 16px;
}

</style>
<form 
	method="get" 
	id="target_form" 
	target="my_ferame" 
	action="http://winofsql.jp/php_get.php" 
	accept-charset="utf-8">
<pre>
<input 
	id="send_check" 
	class="num"
	type="submit" 
	name="send" 
	value="送信">
▼ type="number" でスピンボタンなし
<input
	id="num1"
	class="num"
	type="number" 
	name="num[]">

▼ type="number" でスピンボタンあり
<input 
	id="num2"
	class="num" 
	type="number" 
	id="ie9" name="num[]">

▼ jQuery spinner
<input 
	id="num3"
	class="num" 
	type="number" 
	id="ie9" name="num[]">
</pre>
</form>
<iframe name="my_ferame" frameborder="1" scrolling="yes" width="400" height="200"></iframe>

以下の3種類の実行でそれぞれの表現が変化します。( spinner へのオプションが必要な場合は、追加で設定します。
$(function(){
	$("#num1").type_number( { spin: "off" } );
	$("#num2").type_number( { spin: "on" } );
	$("#num3").type_number( { spin: "jquery" } );
});



posted by lightbox at 2014-11-21 11:33 | プラグイン作成(jQuery) | このブログの読者になる | 更新情報をチェックする

2014年03月28日


jQuery のプラグイン作成 : 要素のクリックイベントで、画像の実際の縦横サイズちょうどの大きさのウインドウを開いて表示する

ウインドウは、画像がデスクトップの解像度を超える場合の動作は、ブラウザによって違うので、確実に表示できる大きさの画像を指定するのがいいです。いずれにしても、一旦画像をロードしてサイズを取得するので、無駄に大きいものは良くありません。

ウインドウは、計算でデスクトップ中央に表示されます。そのあたりの位置はプラグイン内で変更できます。また、要素に data- で属性として目的の画像をセットするような仕様にするのは簡単ですが、IE の古いブラウザの場合は、コードで対応する必要があります。しかし、現在ではその対応はあまり意味が無いので具体的な記述はしていません。( この記事の最後に、IE 全てに対応し、セレクタで一括指定できるようにしたコードを掲載しました )

IE の場合は、仕様の為か、周りに余白ができます。もうちょっと作りこめば、それもどうにかできますが、画像を表示したいだけなのでこれで十分だと思います。
画像は、Picasa の画像を使用しているので URL が長くなっています。Picasa の画像は、サーバー側でサムネイルを作成できるので、このような場合に便利ですが、長い URL を避けたい場合、Google の URL 短縮を 画像の URL に対して行うといいです。

関連する記事

Picasa のサムネイルの使い方
イメージユニット作成サービス / window.open と Lightbox2 と Shadowbox

<script>
// jQuery ロード部分
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>

<script>
// プラグインインストール部分
$.fn.extend({ 
	setOpenImage: function(url){
		var jq = this;
		var obj = new Image();
		$( obj ).load(function(){
			var __h = this.naturalHeight || this.height;
			var __w = this.naturalWidth || this.width;
			jq.css("cursor", "pointer").click(function(){
				window.open( url,
					"",
					"width="+__w+",height="+__h+",resizable=1,left="+(screen.width-__w)/2+",top="+(screen.height-(__h+100))/2)
			});
		});
		$( obj ).prop( "src", url );
	}
});
</script>

<script>
// ロード後の実装部分
$(function(){
	$("#open_target_1").setOpenImage("https://lh4.googleusercontent.com/-1hrl6J4BkAI/UmfOlBCk8VI/AAAAAAAAQ08/2QbL_BEtAjA/s900/UrbanFuture3_1.jpg");
	$("#open_target_2").setOpenImage("https://lh4.googleusercontent.com/-ivV-h9giVL0/Ul7TtLhF37I/AAAAAAAAQvk/AQJamcu3-mc/s640/ub3_lights.jpg");
});
</script>

<img id="open_target_1" src="https://lh4.googleusercontent.com/-1hrl6J4BkAI/UmfOlBCk8VI/AAAAAAAAQ08/2QbL_BEtAjA/s400/UrbanFuture3_1.jpg">
<img id="open_target_2" src="https://lh4.googleusercontent.com/-ivV-h9giVL0/Ul7TtLhF37I/AAAAAAAAQvk/AQJamcu3-mc/s200/ub3_lights.jpg">

カスタム属性とクラスで一括指定

IE に対する対応は、かなり特殊なので省いてもいいのですが、IE9 と IE10 の時代で outerHTML から属性を取得する処理が必要で、この処理はひょっとすると、他の実装にも役立つかもしれません。

それより何より、HTML の要素に記述する事によって、each 処理で、セレクタによる全ての要素に一括対応ができるようになります。これが一番実質的に意味があるので作成してみました。( 最初のコードでもセレクタによる一括指定はできますが、一つの指定で指定できる画像は一つです )

さらに読みやすくする為に、Google の URL短縮 を実際に使用しています。
<script>
// jQuery ロード部分
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>

<script>
// プラグインインストール部分
$.fn.extend({ 
	setOpenImageAll: function(url){
		this.each(function(idx,elm){

			var jq = $(elm);
			var img_url = url;
			if ( typeof jq[0].dataset !== 'undefined' ) {
				img_url = jq[0].dataset.image;
			}
			if ( typeof jq[0]["data-image"] !== 'undefined' ) {
				img_url = jq[0]["data-image"];
			}
			if ( typeof img_url === 'undefined' ) {
				var wk = jq[0].outerHTML;
				var wk2 = wk.match(/data-image=\"([^"]+)\"/);
				img_url = wk2[1];
			}
			var obj = new Image();
			$( obj ).load(function(){
				var __h = this.naturalHeight || this.height;
				var __w = this.naturalWidth || this.width;
				jq.css("cursor", "pointer").click(function(){
					window.open( img_url,
						"",
						"width="+__w+",height="+__h+",resizable=1,left="+(screen.width-__w)/2+",top="+(screen.height-(__h+100))/2)
				});
			});
			$( obj ).prop( "src", img_url );

		});
	}
});
</script>

<script>
// ロード後の実装部分
$(function(){
	$(".open_image").setOpenImageAll();
});


</script>
<img class="open_image" src="http://goo.gl/kbi8oV" data-image="http://goo.gl/7vItxm">
<img class="open_image" src="http://goo.gl/Dl1Lrv" data-image="http://goo.gl/ZYx6VC">
img_url = jq[0]["data-image"]; は、IE8 以前の対応です。昔の IE は、HTML で書いた属性がそのままプロパティとして実装される仕様でした。ですから、obj.data-image というプロパティが実際に作成されています。しかし、参照する場合、プロパティに -( ハイフン ) は使え無いので、jq[0]["data-image"] という文字列での表現で利用します。

さらに、IE9 と IE10 で、この仕様が無くなったのですが、IE11 でやっと、カスタム属性が利用可能になります。そこで、IE9 と IE10 のみ、outerHTML から文字列を取得して、正規表現で書かれている URL を取得しています。

関連する記事

IE11 から利用可能になったカスタムデータ属性(datasetプロパティ)


タグ:IE jquery dataset
posted by lightbox at 2014-03-28 15:21 | プラグイン作成(jQuery) | このブログの読者になる | 更新情報をチェックする

2014年03月18日


jQuery の回転アニメーションでくるくる回る『実行中アイコン』

常にループする必要があるので、それなりに CPU 負荷がかかります。しかし、CSS だけのアニメーションと比べて特別負荷がかかるようでは無いようです。開始と停止があれば使えるので、後は対象を何にするかだけです。これだと画像を使ったほうがよさそうな気はします。

※ グラデーションを使った最初の DIV のほうがやや負荷が大きいようでした。
※ 最初の DIV のグラデーション指定は、IEでは IE10 以上でないとできません(IE9以前だと filter)






<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>

<style type="text/css">
#target {
	width:20px;
	height:20px;
	border:0px solid #000;
	border-radius: 50px;
	background: linear-gradient(to top, #ffffff, #999999);
	background: -webkit-linear-gradient(top, #fff, #999);
	position: relative;
}
#in_target {
	position: absolute;
	left: 5px;
	top: 5px;
	width:10px;
	height:10px;
	border:0px solid #000;
	border-radius: 10px;
	background-color: #ffffff;
}
#target2 {
	margin-left: 10px;

	border-radius: 50%;	/* 元の形状を丸くする為 */

	font-size: 18px;	/* 位置指定を em でしているので、ここを変更すると半径変更 */
	width: 5px;		/* サイズ変更 */
	height: 5px;

	/* em を使うと、font-size にサイズを連動させる事ができる */
	/* width: .25em; height: .25em; */

	/* box-shadow による影の複数作成 : 位置と色と不透明度を指定 */
	box-shadow:
		0 -.4em       0 0 rgba(50,50,50,1),
		-.28em -.28em 0 0 rgba(50,50,50,.75),
		-.4em 0       0 0 rgba(50,50,50,.50),
		-.28em .28em  0 0 rgba(50,50,50,.25)
	; 
}
</style>
<div class="loop" id="target"><div id="in_target"></div></div>
<br><br>
<div class="loop" id="target2"></div>
<br><br>

<script>
$.fn.extend({ 
	rotateStop: function(){
		this.data("stop", true);
	},
	rotateAction: function(deg, duration, easing){
		var target = this;
		$({kakudo: 0}).animate(
			{kakudo: deg},
			{
				duration: duration,
				easing: easing,
				step: function(now) {
					target.css({
						transform: 'rotate(' + now + 'deg)'
					});
				},
				done: function() {
					if ( typeof target.data("stop") === 'undefined' || target.data("stop") === false ) {
						setTimeout(function(){target.rotateAction(deg, duration, easing)},0);
					}
					else {
						target.data("stop", false );
					}
				}
			}
		);
	}  
});

</script>

<input type="button" value="DIV回転" onclick='$(".loop").rotateAction(360,1000,"linear");'>
<input type="button" value="回転停止" onclick='$(".loop").rotateStop();'>


関連する記事


posted by lightbox at 2014-03-18 13:15 | プラグイン作成(jQuery) | このブログの読者になる | 更新情報をチェックする

2014年03月17日


jQuery を使ったCSS 一括エフェクトアニメーション( rotate, skew, borderRadius, boxShadow )



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>
<script>
$.fn.extend({ 
	miscAnimate: function(deg, duration, easing){
		var target = this;
		$({kakudo: 0, kado: 0, shadow: 0}).animate(
			{kakudo: 360, kado: 30, shadow: 40},
			{
				duration: 3000,
				easing: "swing",
				step: function(now,tween) {
					if ( tween.prop == 'kakudo' ) {
						target.css({
							transform: 'skew(' + now + 'deg) rotate(' + now + 'deg)'
						})
					}
					if ( tween.prop == 'kado' ) {
						target.css({
							borderRadius: now + 'px'
						})
					}
					if ( tween.prop == 'shadow' ) {
						target.css({
							boxShadow: now + 'px '+ now +'px '+ now + 'px '+ now + 'px rgba(0, 0, 0, 0.5)'
						})
					}
				}
			}
		);
	}  
});

</script>

<input type="button" value="開始" onclick='$("#target").miscAnimate();'>
<br><br><br>

<div id="target" style='margin-left:100px;margin-top:100px;width:100px;height:100px;border:1px solid #000;'></div>

step の第二引数の tween は、こういう時に使うものだったのがやっと解りました。ちょっと仕様として不思議なのが、step 内の this は、tween と似たような元々のプロパティの増分がセットされているオブジェクトだったのですが、tween があるのだから、this は 元々のオブジェクトのほうがいいはずです。将来仕様変更あるかもしれませんね。

関連する記事


posted by lightbox at 2014-03-17 17:22 | プラグイン作成(jQuery) | このブログの読者になる | 更新情報をチェックする

jQuery の回転アニメーション / $({kakudo: 0}).animate(properties, options )

jQuery の animate メソッドに渡せるのは、数値表現のプロパティのみなので、使えるものはほとんどありません。例えば、回転処理なんかもそのうちの一つですが、この方法を使えばどんなものでもアニメーション化できます。

この方法を解説していたのは、やはり、stackoverflow( CSS rotation cross browser with jquery.animate() ) でした

このソースでちょっと解りにくいのが、$({kakudo: 0}) の部分ですが、なんの事は無く {kakudo: 0} という超シンプルなオブジェクトに対してアニメーション処理をしようというわけで、このオブジェクトは当然 kakudo プロパティ を持っているので、step イベントが 0 度から 指定角度までの間呼ばれ続けるわけです。

それを利用した単純な繰り返し処理です。

その結果、いとも簡単にページ全体の回転処理を作成する事ができました。





<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>
<script>
$.fn.extend({ 
	rotateAction: function(deg, duration, easing){
		var target = this;
		$({kakudo: 0}).animate(
			{kakudo: deg},
			{
				duration: duration,
				easing: easing,
				step: function(now) {
					target.css({
						transform: 'rotate(' + now + 'deg)'
					});
				}
			}
		);
	}  
});

</script>

<input type="button" value="画像回転" onclick='$("#target").rotateAction(360,1000,"swing");'>
<br>
<input type="button" value="全て回転" onclick='$(document.body).rotateAction(360,5000,"swing");'>
<br><br><br>

<img id="target" src="https://lh5.googleusercontent.com/-kCYTSmTrJXs/URvMQy9ClqI/AAAAAAAARuw/5BTKTk2c_sw/s128/_img.png" style="border: solid 0px #000000" />

関連する記事


posted by lightbox at 2014-03-17 02:01 | プラグイン作成(jQuery) | このブログの読者になる | 更新情報をチェックする

2014年03月16日


jQuery : IFRAME 作成プラグインと、アニメーションによる表示切替

IFRAME を作成するプラグインです。引数は、URL と幅と高さですが、プラグイン部分に引数を追加すれば容易に変更できます。

iframe メソッド で動的に IFRAME を作成しています。一度作成すれば、中の URL の変更は、iframeChange メソッドで行います。

iframeChange メソッドでは、animation メソッドを使用して、表示の切り替えとしてフェードアウトからフェードインを行っています。

animate の連鎖は、jQuery のドキュメント通りに、jQuery のチェーンで行われます。この際、オプションの queue  がデフォルトで true なので正しく動作しますが、false にしてしまうと動作しないので注意して下さい。

最初のアニメーションの終了後、done イベントで次の URL への変更を行っています。通常の complete イベントでも動作しますが、done イベント内では、アニメーションのプロパティやオプションが参照可能です。

▼ 実装のコード
<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>
<script>
$.fn.extend({ 
	iframe: function(url,w,h){
		this.html("");

		// IFRAME 作成
		var obj = document.createElement("iframe");
		obj.src = url
		$(obj).attr("frameBorder", "0");
		$(obj).attr("scrolling", "no");
		$(obj).css("position ", "relative");
		$(obj).css("width", w+"px");
		$(obj).css("height", h+"px");
		this.append(obj);
		return this;
	},
	iframeChange: function(url,w,h){
		this.animate({ opacity: 0 },
		{
			duration: 1500, easing: "swing",
			done: function(animation) {
				console.dir(animation.props);
				console.dir(animation.opts);
				$(this).iframe(url,w,h);
			}
		})
		.animate({ opacity: 1 },		{
			duration: 3000, easing: "swing",
			done: function(animation) {
				console.dir(animation.props);
				console.dir(animation.opts);
			}
		});
	}  
});

$(function(){
	$("#iframe_base").iframe("https://lh3.googleusercontent.com/-YEY-LGIec58/Uq78JcmXG_I/AAAAAAAARs4/Cq8VdOEe1TA/s500/freefont_hanko_kana014.png",500,500)
});

</script>
<input type="button" value="変更" onclick='$("#iframe_base").iframeChange("https://lh5.googleusercontent.com/-qU5uL1LvaM8/UtN7Rhtr3RI/AAAAAAAASEY/tglCi9sGuf8/s250/_img.png",250,250)'> <input type="button" value="戻す" onclick='$("#iframe_base").iframeChange("https://lh3.googleusercontent.com/-YEY-LGIec58/Uq78JcmXG_I/AAAAAAAARs4/Cq8VdOEe1TA/s500/freefont_hanko_kana014.png",500,500)'>
<div id="iframe_base"></div>



posted by lightbox at 2014-03-16 16:05 | プラグイン作成(jQuery) | このブログの読者になる | 更新情報をチェックする

2013年02月27日


jQuery でかなり実用的かもしれない入力制限( 入力値復帰型 )

実用的と言っても以下の二つに比べての話で、見た目はいったん入力したものがフォーカス移動時に元にもどったり、キーで入力したものがいったん表示されて消えるといった見た目はあまり良いものではありません。

jQuery で、指定文字集合のみ入力可能なプラグイン
jQuery の簡単なプラグインを $.fn.extend で作成( 0〜9のみ入力可能なフィールド )

しかし、JavaScript ではここらへんが限界のような気もします。いずれにしても、『処理』として参考にするようなコードである事は間違い無いと思います。

要点

ここで最も重要なのは、『いつ入力前のデータを保存するか』です。ここでは、onfocus と、onkeydown と、onkeyup の3か所で保存しています。但し、それぞれ意味が違います。

❶ onfocus では、最初からフィールドに入っていたものを取得するのが目的で、フォーカスが移動すれば、再度フォーカスを得る直前にまた保存されます。

❷ onkeydown では、何かキーを押す直前の保存なので、一文字づつのチェックの為に使います。しかし、クリップボートから転送される場合には、ここは意味が無いので onfocus で取得済の文字列を使います

❸ onkeyup では、実際の入力文字が該当しない場合に拒否して、❷ で保存したものに戻しますが、うまく行った場合は、保存します。こうする事で、フォーカス移動の無い状態で入力の途中でクリップボードの貼り付けが使用された場合に、戻す文字列量を最小限にします。

データの保存

保存データは、.data を使って、jQuery 内部に保存します。attr を使うと、INPUT 要素に保存できるので、開発者ツールでデバッグがしやすくなるメリットはありますが、.data を使うと、オブジェクトとして保存できるので、拡張が容易になります。
<input class="numField" type="text" />
<input class="numField" type="text" />
<input class="numField" type="text" />

<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
<script type="text/javascript">

$.fn.extend({ 
	allowField: function(str){
		// 対象文字集合を登録しておく
		$(this).data( "allowstr", str );
		$(this).bind('keyup', function() {
			var allowstr = $(this).data( "allowstr" );
			var cur = $(this).data( "cur" );
			var change = $(this).val();
			var char = null;
			for( var i = 0; i < change.length; i++ ) {
				char = change.substr( i, 1 );
				if ( allowstr.indexOf(char) == -1 ) {
					$(this).val(cur);
					return;
				}
			}
			$(this).data( "focus", $(this).val() );

		}).bind('change', function() {
			// ここの処理は、フォーカスがなくなった時にその中に1文字でも対象外
			// の文字が含まれていたら、直前の保存の状態に戻すので、極端な場合は
			// 全く空白になる事があり得ますので注意が必要です
			var allowstr = $(this).data( "allowstr" );
			var focus = $(this).data( "focus" );
			var change = $(this).val();
			var char = null;
			for( var i = 0; i < change.length; i++ ) {
				char = change.substr( i, 1 );
				if ( allowstr.indexOf(char) == -1 ) {
					$(this).val(focus);
					return;
				}
			}
		}).bind('keydown', function() {
			// 現在のデータを保存
			$(this).data( "cur", $(this).val() );
		}).bind('focus', function() {
			// 現在のデータを保存
			$(this).data( "focus", $(this).val() );
		});
		return this;
	}  
});

// プラグインの実行
$(".numField").allowField("1234567890ABCDEFabcdef-")
 .css("background-color", "#e0e0ff")
 .css("width","70px")
 .attr("maxlength",6);

</script>



タグ:jquery javascript
posted by lightbox at 2013-02-27 10:00 | プラグイン作成(jQuery) | このブログの読者になる | 更新情報をチェックする

2013年02月26日


jQuery で、指定文字集合のみ入力可能なプラグイン

プラグインのサンプルとして、keydown イベントのみを使って作成した以下のプラグインと基本的に行っている事は変わりません。

jQuery の簡単なプラグインを $.fn.extend で作成( 0〜9のみ入力可能なフィールド )

▲ と同様実用になるものではありませんが、簡易的な入力制限であれば今回の方法は効果的です。

keydown イベント

このイベントの主体はキーボードに並んでいるキーなので、ほぼ全てのキーが網羅されています。しかし、テンキーと本体での数字キーは別の個体なので、違ったキーが割リ当てられます。また、キー操作を伴うキーを判別できるので、厳密なコントロールができる反面、制御するコード量が多くなるわりに、日本語等を完全にコントロールできないのでメリットがあまりないかもしれません。

keypress イベント

このイベントの主体は、アプリケーションに送られる文字コードが主体です。この場合テンキーから送られる『1』と本体から送られる『1』は同じ『1』を表す数値なので、管理が容易です。しかし、日本語を入力する為に『漢字』キーを少しでもコントロールしようとすると、keydown イベントが必要になるので付加しています。

ですが、結局完全にコントロールはできずに、現実にはブラウザによって挙動が違います。

this について

allowField 内の this は、jQuery のオブジェクトですが、イベント内の this は DOM なので、常に jQuery の処理として見通しを良くする為に、いずれにも $(this) という表現を行っています。

入力可能文字について

この文字集合は、入力フィールド毎に設定されるものなので、attr で要素の属性としてプラグイン作成時に設定し、イベント発生時には DOM より jQuery オブジェクトを作成して attr で取得して対象文字かどうかを判断するようにしています。
<input class="numField" type="text" />
<input class="numField" type="text" />
<input class="numField" type="text" />

<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
<script type="text/javascript">

$.fn.extend({ 
	allowField: function(str){
		// 対象文字集合を登録しておく
		$(this).attr("allowstr",str);
		$(this).bind('keypress', function(evt) {
			// なんらかの文字が割り当てられたキーを押した
			if ( evt.charCode != 0 ) {
				// 保存しておいた、対象文字集合を取り出す
				var allowstr = $(this).attr("allowstr");
				// 押された文字コードから実際の文字を作成する
				var nowstr = String.fromCharCode( evt.charCode );
				// その文字が対象文字集合に含まれていたら、関数を抜ける
				if ( allowstr.indexOf(nowstr) >= 0 ) {
					return;
				}
			
				// 対象文字集合に含まれない場合は、デフォルトの処理をキャンセル
				if (navigator.userAgent.toLowerCase().indexOf("msie") > -1) {
					try{evt.returnValue = false;}catch(ex){}
				}
				try{evt.preventDefault();}catch(ex){}
			}
		}).bind('keydown', function(evt) {
			// 漢字
			// IE9 と Chrome と Safari は拒否できるが、Chrome は漢字モードにはなってしまうので
			// 漢字モードを抜けないと何も入力できなくなる
			if ( evt.keyCode == 229 ) {
				if (navigator.userAgent.toLowerCase().indexOf("msie") > -1) {
					try{evt.returnValue = false;}catch(ex){}
				}
				try{evt.preventDefault();}catch(ex){}
			}
		});
		return this;
	}  
});

// プラグインの実行
$(".numField").allowField("1234567890ABCDEFabcdef-")
 .css("background-color", "#e0e0ff")
 .css("width","70px")
 .attr("maxlength",6);

</script>



タグ:javascript jquery
posted by lightbox at 2013-02-26 10:00 | プラグイン作成(jQuery) | このブログの読者になる | 更新情報をチェックする

2013年02月24日


jQuery の fn.extend メソッドと extend メソッド の違いは $(セレクタ) のメソッドとして実行できるかどうか ( extend の仕様について )

厳密には、prototype の意味が重要になるんですが、それを知っていてもあまり実用とは関係無いので事実だけを考えます。
jQuery.extend = jQuery.fn.extend = function() {
実際にはこのようなコードなので、処理そのものは同じですが、存在する場所が違うので jQuery からの処理を同じようにする事はできません。 fn.extend は、$(セレクタ) のメソッドとなる いわゆる、$(セレクタ) で作成されるオブシェクトは『インスタンス』で、常に prototype を継承して実体が作成されると考えるとしっくり来ます。しかし、extend メソッドでは $.メソッドとして実行できるようになります。よって、同様の処理を行う為には以下のコードのように全く違った実装をする必要があります。
<div id="box1"></div>
<div id="box2"></div>

<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
<script type="text/javascript">

$.extend({ test1:function(a){ this(a).text("test1"); return this(a);}  })

$.fn.extend({ test2:function(){ this.text("test2"); return this;}  })

var x = $("#box1");

x.test2().css("background-color","#c0c0ff");
$.test1("#box2").css("background-color","#c0c0c0");

console.dir(x)

</script>

extend メソッドの仕様

使い方としては、3種類あります。一つは extend(object1,object2) という形で、object1 に object2 をマージするのですが、同じ名前を持つものは置き換えられてしまいます。また、object1 を省略した形は元のオブジェクトに object2 をマージするようです。( これを fn.extend で行うのが一般的なプラグイン作成 )

二つ目の使い方は、extend(true,object1,object2) という使い方で、単純な置き換えをせずにデータが処理されます。具体的には、jQuery のドキュメントを読むか、実際に試すといいと思います。

三つ目は、object = $.extend({}, object1, object2) というような形で、object1 を置き換えずに object に object1 に対して object2 をマージしたオブジェクトを作成する事ができます。



タグ:jquery javascript
posted by lightbox at 2013-02-24 10:00 | プラグイン作成(jQuery) | このブログの読者になる | 更新情報をチェックする
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 終わり