Webサービスでのアカウント削除方法 の探し方
|
12月21日(水) 07:12
|
「Webサービスのアカウントを削除したい!
でもどうすればよいの?!」
って時は、「Setting」(歯車マーク)を開いて
「remove」「Deactivate」等の文字列を探せばよい。
・・・そうか「remove」がキーワードなのか。φ(. .)メモメモ
※日本語化されてないサービスで、彷徨ったです。
※以下は、Twitterでの例。
|
jQueryベースでポップアップメニュー表示
|
11月01日(火) 12:37
|
jQueryベース(タグ内の内容書き換えと発火)でポップアップメニューを表示し、選択されたメニューに応じたfunction()を実行する方法メモ。
「どっかにコピペ可能なコードあるだろう」って探したんだけど、jQuery( selecter ).click() に直接記述するコードはあったもの、
当方の要望に沿うものではなかったので自前実装してみた。あ、基本設計は参考にした「とほほのWWW入門」様のコードと同じです。
わざわざライブラリ化するまでもなく、「その場で書け」ということかもしれない。
自分の欲求に応じて、クラス(っぽいもの)化してみた。左クリック、右クリック(長押し)への紐付けはclick(), contextmenu() で好きなように。
なお、ほぼ同じ内容をQiitaにも掲載。
以下のようにして使う。動作の様子は、こちらのデモを参照。
|
$(document).ready(function(){
var menu1 = new PopupMenu( $, [
{ "title" : "hoge",
"action" : function(){ alert("hoge!"); }
},
{ "title" : "ふが",
"action" : function(){ alert("ふが!"); }
}
]);
var menu2 = new PopupMenuMobile( $, [
{ "title" : "piyo",
"action" : function(e, targetNode){
var target = $(targetNode);
alert( "piyo\r\nクリックエリアの内容:\r\n" + target.text() );
}
},
{ "title" : "foo",
"action" : function(){ alert("foo!"); }
}
]);
var menu3 = new PopupMenuMobile( $, [
{ "title" : "右クリックコンテキストメニュー",
"action" : function(){ alert("スマホでは長押しに相当"); }
}
]);
$("#id_div1").click(function(event){
menu1.show(event, this);
});
$("#id_div2").click(function(event){
menu2.show(event, this);
});
$("#id_div3").click(function(){
menu1.hide(); // これでmenu2, menu3側も閉じる。
}).bind("contextmenu", function(event){
menu3.show(event, this);
return false; // デフォルトのコンテキストメニューを解除
});
});
/**
* 表示位置を左側へずらしたポップアップメニューを、サブクラスとして実装。
*/
var PopupMenuMobile = function( jQueryCommon, menuList ){
PopupMenu.call(this, jQueryCommon, menuList);
};
PopupMenuMobile.prototype = Object.create( PopupMenu.prototype );
PopupMenuMobile.prototype.getMenuPosition = function( event ){
var nX = event.pageX - this.itsMaxStringLength * 14 + 8;
nX = (nX > 0) ? nX : 0;
return { "pageX" : nX, "pageY" : event.pageY };
};
|
上記で利用している、PopupMenu()クラスの定義コードはこちら。
|
/**
* @description ポップアップメニュー表示クラス
* @param{Object} jQueryCommon 利用するjQuery オブジェクトを渡す。静的に使いまわすので、2回目以降はNULL指定可能。
* @param{Object} menuList 表示するポップアップメニューリスト。title, action メンバを持つこと。
*/
function PopupMenu( jQueryCommon, menuList ){
/**
* @description ポップアップメニューに表示するリスト。title, action メンバを持つ。
*/
this.itsMenuList = menuList;
/**
* @description 設定されたポップアップメニューの最大文字列。デフォルト14文字。
*/
this.itsMaxStringLength = (function( list, defaultLength ){
var i, n = list.length, title, action;
for( i=0; i<n; i++ ){
title = list[i].title;
action = list[i].action;
if( (title && action) && ( defaultLength < title.length ) ){
defaultLength = title.length;
}
}
return defaultLength;
}(menuList, 14));
this.itsId = "_id_popup"; // ※init()の中で数字を付加してユニーク化される。
this.init( jQueryCommon );
};
(function(){
/**
* @description ポップアップメニューのdiv要素CSS
*/
var MENU_DIV_CSS = {
"position" : "absolute",
"min-width" : "200px",
"background-color" : "#eeeeee",
"border": "1pt solid #666666",
"box-shadow" : "2px 2px 4px 0px #666666"
};
/**
* @description ポップアップメニューのulタグのCSS
*/
var MENU_UL_CSS = {
"border": "0pt",
"margin" : "2px",
"padding" : "6px",
"line-height": "12pt",
"color": "#000",
"list-style" : "none",
"font-size" : "11pt"
};
/**
* @description ポップアップメニュー項目のCSS
*/
var LI_CSS = {
"padding" : "6px",
"background-color" : "#eeeeee",
"border" : "1px solid transparent"
};
/**
* @description ポップアップメニュー項目のHover時のCSS
*/
var LI_CSS_HOVER = {
"background-color" : "#d1e2f2",
"border" : "1px solid #78aee5"
}; // http://www.tohoho-web.com/wwwxx035.htm
/**
* @description このクラスで利用するjQuery。
*/
var jQ = null;
/**
* @description 生成されたポップアップメニューIDのリスト。
*/
var menuIds = [];
/**
* @description 全てのポップアップメニューを非表示にする。
* @param{String} exceptId 捜査対象外のID。null指定なら、全部を「非表示」にする。
*/
var hideAll = function( exceptId ){
var n = menuIds.length;
var target;
while( 0<n-- ){
target = jQ("#" + menuIds[n]);
if( (menuIds[n] != exceptId) && (target.size() > 0) ){
target.hide();
}
}
}
/**
* @description 最近のshow()で渡された、第一引数Eventと、第二引数。
*/
var staticLastEvent = null, staticLastParam = null;
/**
* @description 本クラスの初期化。
* @param{Object} initJQuery jQueryオブジェクトを渡す。初回以降はnullでも構わない。
*/
PopupMenu.prototype.init = function( initJQuery ){
var BIND_INDEX_ATTR = "data-action-index";
var i, list = this.itsMenuList, n = list.length, str, title, action;
var target, item;
jQ = (!jQ) ? initJQuery : jQ;
this.itsId += "_" + menuIds.length;
target = jQ("body");
target.append( "<div id='" + this.itsId + "' style='display:none;'><div>" );
target = jQ("#" + this.itsId);
target.css( MENU_DIV_CSS );
str = "<ul>";
for( i=0; i<n; i++ ){
title = list[i].title;
action = list[i].action;
if( title && action ){
str += "<li " + BIND_INDEX_ATTR + "='" + i + "'>" + title + "</li>";
}
}
str += "</ul>";
target.append( str );
target = target.children("ul").eq(0);
target.css( MENU_UL_CSS );
target = jQ("#" + this.itsId + " ul li" );
target.css( LI_CSS );
target.hover(
function(){ jQ(this).css( LI_CSS_HOVER ); },
function(){ jQ(this).css( LI_CSS ); }
);
target.click(function(event){
var item = jQ(this);
var index = item.attr( BIND_INDEX_ATTR );
hideAll(null);
list[ index ].action( staticLastEvent, staticLastParam );
})
menuIds.push( this.itsId );
}
/**
* @description ポップアップメニューを表示する。
* メニュー以外の場所をクリックすると消える。他のポップアップメニューが表示された時も、以前のは消える。
* @param{event} event jQuery.click(function(event){})で渡されるeventオブジェクトを指定する。
* 呼び出し先の関数の引数にそのまま渡す。
* @param{Object} paramObj newの際のactionパラメータに指定された関数呼び出し時の第二引数に渡される。
* 通常はthisを渡すこと。
*/
PopupMenu.prototype.show = function(event, paramObj){
/*
[メモ] click() はeventが渡される仕様。
---
jQueryのイベントは、コールバック関数の最初の引数でjQuery.Eventオブジェクトを受け取ることができます。
このオブジェクトを使って、規定のイベント動作のキャンセルや、バブリングの抑制などを行います
http://semooh.jp/jquery/api/events/click/fn/
*/
var target = jQ("#" + this.itsId);
var isShowed = (target.css("display") == "none");
var pos;
hideAll( this.itsId );
if( isShowed ){
pos = this.getMenuPosition( event );
target.css({
"top" : pos.pageY + "px",
"left" : pos.pageX + "px",
});
target.slideDown("fast");
staticLastEvent = event;
staticLastParam = paramObj;
}else{
target.hide();
}
};
/**
* @description ポップアップメニュー表示毎に、表示位置決めのためにcallbackされる。
* サブクラスで任意にオーバーライドのこと。
*/
PopupMenu.prototype.getMenuPosition = function( event ){
return { "pageX" : event.pageX, "pageY" : event.pageY };
};
/**
* @description 表示中のポップアップメニューを全て非表示にする。
*/
PopupMenu.prototype.hide = function(){
hideAll( null );
};
}());
|
以上ー。
|
SIMフリーのWindows10マシンでの MVNOのSIM設定方法
|
10月25日(土) 12:52
|
SIMフリータブレットのWindows10マシンでのMVNOのSIM設定方法について
SIMフリーのWindowsタブレット(TransBookとか)で、MVNOのSIMを使う際に注意すべきこと
⇒「Windows 8.1とWindows10では設定方法が異なる」。
Win10化した場合は、公式手順のWin8.1向け「APN設定ツール」が使えない(実際、当方はNGでした)。
・・・というか、正確にはOS標準ツールで事足りるので、専用ツールは不要だった。
なお、デフォルトで「Docomo JP」とかAPNプロフィルが割り当てられて、一見では電波を掴んでいるよう見えても、
実際に「接続」するとNGなので注意。APN設定直す画面への誘導は無し。
以下の手順で明示的にAPNを設定する必要がある。
Windows10の場合は、Windows側の標準機能を使って以下のようにすると成功した
- 「アクションセンター>全ての設定>ネットワークとインターネット>携帯電話」で
右側に表示された「携帯電話」パネルをクリック。
- 「詳細オプション」ボタンが表示されるのでクリック。
- 「携帯電話会社の設定」パネルから、「インターネットAPNの追加」ボタンを押す。
- APN設定画面が表示されるので、でAPN、ユーザー名、他を入れる。プロファイル名は識別用なので、好きな名称を。
以上ー。
|
レンタルサーバーのプランを変更
|
9月17日(土) 21:07
|
「さくらレンタルサーバー」の「ライトプラン」から「スタンダードプラン」へ乗り換えました。
ドメインは無事にそのまま引き継ぐことが出来たので、見た目としては何も変わってないと思うー。
やっててよかった、サブドメイン!
まだ無料試用期間中なので「やっぱヤーメタ」するかもしれませんけど。
サーバーの容量には不満はなかったんですが、利用可能サービスの方に少々。料金的には、年間で飲み会1回分程度の増額なので、それで「制限なく好きにできる!」環境が手に入るならアリかなーと。
残念ながら「プラン変更」という手続きは存在せず、「新規に利用開始」+「既存アカウントは削除」という手続きを取らざる得ないみたい。そんなわけで、現在は「ライト」と「スタンダード」の2コース契約状態。
移行手順の概要は、こちらのサイト様によくまとまっていて分りやすいので、ここでは割愛。懸念事項だった、ドメインの移管も以下の手順で問題なくできた。ここも先のサイト様での記載と一緒だった。
- 旧垢側で、対象のドメインを「削除」
(※当方は、「さくらインターネットの60種類のサブドメイン」を利用してた。)
- 2時間待つ。
- 新垢側で、「さくらインターネットの60種類のサブドメイン」から、同じドメインを取り直す。
(※大人気のドメインだと、先着順なので、取れないリスクあるかも。当方は問題なくて取り直せましたが。ふぅ、ひと安心ー。)
ハマッたこと。
レンタルサーバー側の仕様がいつの間にか変更に成っていて、これまではサブドメインの「 http://fluorite.halfmoon.jp/ 」にアクセスすると「 http://fluorite.halfmoon.jp/fluorite/ 」にリダイレクトされる仕様だったのが、新しく契約したサーバーだとサブドメイン「 http://fluorite.halfmoon.jp/ 」のままで扱われるようになってた。なので、「 http://fluorite.halfmoon.jp/fluorite/menu.html 」とかに直リンク貼ってた部分がギャー!になった。具体的には、両手たぶメモさんの更新チェック機構。orz
マジかよ。
そういう「変わったら困る部分」は
「サブドメインだから、そっちを引き継げば大丈夫ー」って高をくくってたのにー。orz
さくらインターネットさん固有なのかもしれないけれど、この辺のサブドメインのリダイレクトしようとか、「過去に〜で変わったんだよ」とか知っている方居たら教えてくれー。もやもやするんで。
|
人気No.1返り咲き!・・・だが、
|
9月15日(木) 21:52
|
「
両手たぶメモ」
の
Vector様でのカテゴリ内人気ランキング
にて1番返り咲き♪
なのだけど、よく見たら「Windows Me/98/95用ソフト」に分類されてる。。。
あれー? 推奨はXP以降の環境なんだけどなー??
▽当方のサイトでの動作環境の表示▽
うん、Vector様での「動作環境」の表示も、正しく表記されている。
・・・のに何故95側のカテゴリに???
|
JavaScriptでのクラスな思い続き
|
5月21日(土) 12:22
|
先日の記事「JavaScriptのオブジェクト事始め」の続き。
もう少し、「何がモヤモヤの原因だったのか?」が分かったので徒然に記す。
モヤモヤの原因は
「クラスっぽく書こうとすれば書けるけど、コードの可読性が悪くなる。
ついでに書くべきコード量も増える」
のが嫌だと感じていたから、と判明。そうか、そういうことだったのか、自分。
余計なコードは書きたくない、からクラス(のコンスタラクタ相当の)定義は「function ClassA(){};」ではなく、
「var ClassA = function(){};」を用いるのが良い。後者であればその直後に直ぐ、インスタンスベースのJavaSriptらしく
prototypeを利用できるから。
続いて、メンバ変数のprivate化のために利用した即時関数のオブジェクトは保持する必要ない、ってこと事にも気づいた。
うん、コレでスッキリ。コンスタラクタの直後に書くことで関連も分かり易くなった。よしよし、モヤモヤが晴れた♪
動的変数(インスタンス変数)のprivate化?そんなものは『諦める』でOK!(ぇ。
必ずしも隠蔽しなければならないわけではない。コーディング&メンテナンスし易くさえあればOK。
そこまで全力で「クラスが使いたい!」ってわけではない。プロトタイプベースも良いよ♪
ただ、カプセル化が甘くなることにモヤモヤしてた。それがスッキリしたよ、って話。
以上の話をもって書き直したコードをQiitaへ
「JavaScriptでのクラスの書き方」
として投稿したので、興味ある方はどうぞ♪ 改変後のコードだけ、こちらにも載せておきますね。
≫改変後のコード
|
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<script type='text/javascript' src='./jquery-1.12.3.js'></script>
<script type='text/javascript' src='./jquery.cookie.js'></script>
<script>
var CookieBind = function( cookieName ){
// コンスタラクタ
// ⇒グローバル変数で定義する。
//
this._cookieName = cookieName;
this.itsLoadedStr = this.load(); // このタイミングでは未定義のメソッドも指定可能。
};
(function(){
//
// 続いて、prototypeを用いてメソッドを定義
// ⇒即時関数の中で行うことで、静的praivate変数/メソッドを実装可能。
// クロージャーの仕組みを利用している。
//
// ⇒動的なpraivate変数は諦める。
// (メソッドは、適宜thisを渡すことで動的な実装は可能)。
//
// ⇒JavaScriptの場合は、メソッドは「静的な枠」+「動的なメンバ変数」で実装する。
//
// ※prototype内で function(){} 定義するときは、thisに注意。
// ⇒ function(){ の内部 } では、thisは呼び出し元になり、このクラスインスタンスを指さない。
// ⇒ function() の親側で var self = this; して、function(){ の内部 } では、
// self.〜の形式で呼ぶこと(selfはクロージャーになる)。
//
var COOKIE_OPTION = { expires: 7 }; // 静的プライベート変数
CookieBind.prototype.save = function( str ){
$.cookie( this._cookieName, str, COOKIE_OPTION );
};
CookieBind.prototype.load = function(){
return $.cookie( this._cookieName );
};
CookieBind.prototype.getValue = function(){
return this.itsLoadedStr;
}
CookieBind.prototype.getCookieName = function(){
return this._cookieName;
}
}());
// クラス継承はこちら。
var CookieBind2Input = function( cookieName, id_input, id_button ){
var self = this;
CookieBind.call( this, cookieName ); // 継承元のコンスタラクタを明示的に呼び出す。
this._idInput = id_input;
this._idButton = id_button;
this.load2Input();
$("#" + this._idButton).click( function(){
self.saveByButton(); // この位置は、thisが異なるので注意。
});
};
// 親のメソッドを「継承」する。
CookieBind2Input.prototype = Object.create( CookieBind.prototype );
// サブクラスでのメソッド追加も、同様に即時関数内で行う。
(function(){
// 明示的にインスタンスを渡すことで、praivateな動的メソッドを実装可能。
var privateFunc = function( instance, value ){
var str = value + "\r\nをcookie名 ";
str += instance._cookieName;
str += " に保存しました!";
alert( str );
};
CookieBind2Input.prototype.load2Input = function(){
var value = this.getValue();
if( value ){
$("#" + this._idInput).val( value );
}
};
CookieBind2Input.prototype.saveByButton = function(){
var value = $("#" + this._idInput).val();
if( value.length > 0 ){
this.save( value );
privateFunc( this, value );
}
};
CookieBind2Input.prototype.del = function(){
this.save( null );
}
}());
// 実行例
$(document).ready(function(){
var text_cookie1 = new CookieBind( "key-sample1" );
var text_cookie2 = new CookieBind2Input( "key-sample2", "id_text2", "id_button2" );
var text_cookie3 = new CookieBind2Input( "key-sample3", "id_text3", "id_button3" );
if( text_cookie1.getValue() ){
$("#id_text1").val( text_cookie1.getValue() );
}
$("#id_button1").click( function(){
var text = $("#id_text1").val();
text_cookie1.save( text );
alert( text + "\r\nをcookieに保存しました" );
})
$("#id_clear").click( function(){
text_cookie1.save( null );
text_cookie2.save( null ); // スーパークラスのメソッド呼んでみる。
text_cookie3.del();
alert( "cookieを削除しました" );
})
});
</script>
</head>
<body>
<form>
<input id="id_text1" type="text" style="width: 128;"></input>
<input id="id_button1" type="button" value="保存1"></input>
<br>
<br>
<input id="id_text2" type="text" style="width: 128;"></input>
<input id="id_button2" type="button" value="保存2"></input>
<br>
<br>
<input id="id_text3" type="text" style="width: 128;"></input>
<input id="id_button3" type="button" value="保存3"></input>
<br>
<br>
<input id="id_clear" type="button" value="クッキー削除"></input>
</form>
</body>
</html>
|
もちろんECMAScript6実装ブラウザならclass構文使えるけど、、、IE11では未実装だし。
クロスブラウザの方が私には重要。なのでECMAScript5の範囲で論じてる。
そも論、『諦める』ってしたprivateな動的メンバ変数も、やろうと思えばECMAScript5の範囲で実装可能。
でも、これじゃあ力技に感じないか? 私はスッキリしない。
コードが「NOT リーダブル」と感じたので、「諦める」方がスッキリした。
参考までに、ECMAScript5の範囲(これならIE9〜対応済み)でprivateな動的メンバ変数の実装例は下記。・・・読み難いでしょう?
≫privateな動的メンバ変数の実装コード例
|
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<script type='text/javascript' src='./jquery-1.12.3.js'></script>
<script type='text/javascript' src='./jquery.cookie.js'></script>
<script>
var LikeClass = function( name ){
// コンスタラクタ
// ⇒グローバル変数で定義する。
//
this._name = name;
this._unique = this.createUnique();
};
(function(){
var privateVal = {}; // 疑似的なprivateメンバ変数。カウンタとして利用する。
var _uq = 0; // privateメンバをインスタンス毎に識別するための識別子。
var privateCountUp = function( instance ){ // 疑似的なprivateメソッド
privateVal[ instance._unique ]++;
};
LikeClass.prototype.createUnique = function(){
privateVal[ ++_uq ] = 0; //インスタンス毎に、カウンタを初期化
return _uq;
};
LikeClass.prototype.getName = function(){
privateCountUp( this ); // 呼び出し毎にカウントアップ。
return this._name;
};
LikeClass.prototype.getCount = function(){
return privateVal[ this._unique ];
}
}());
// クラス継承はこちら。
var LikeClassSub = function( name, addStr ){
LikeClass.call( this, name );
this._addStr = addStr;
};
LikeClassSub.prototype = Object.create( LikeClass.prototype );
(function(){
LikeClassSub.prototype.getName = function() {
// privateCountUp( this ); // 親のprivateメソッドは呼べない。
return this._name + "!" + this._addStr; // 親のpublicメンバ+サブクラス側のメンバ。
};
}());
// 実行例
$(document).ready(function(){
var text1 = new LikeClass( "key-sample1" );
var text2 = new LikeClass( "key-sample2" );
var text3 = new LikeClassSub( "key-sample3", "◆" );
$("#id_button1").click( function(){
$("#id_text1").val( text1.getName() + " [" + text1.getCount() + "]" );
})
$("#id_button2").click( function(){
// alert( text2.privateVal ); // 当然、undefined になる。
$("#id_text2").val( text2.getName() + " [" + text2.getCount() + "]" );
})
$("#id_button3").click( function(){
$("#id_text3").val( text3.getName() + " [" + text3.getCount() + "]" );
})
});
</script>
</head>
<body>
<form>
<input id="id_text1" type="text" style="width: 128;"></input>
<input id="id_button1" type="button" value="更新1"></input>
<br>
<br>
<input id="id_text2" type="text" style="width: 128;"></input>
<input id="id_button2" type="button" value="更新2"></input>
<br>
<br>
<input id="id_text3" type="text" style="width: 128;"></input>
<input id="id_button3" type="button" value="更新3"></input>
<br>
</form>
</body>
</html>
|
同じように感じてくれる方の、何かの参考になればうれしい。
※上記の2つのソースコードともに、jquery-1.12.3.js と jquery.cookie.js を利用。
|
HTMLとJavaScriptだけで音声入力 (Google Chrome限定)
|
5月15日(日) 12:12
|
Google Chrome限定だけど、HTMLとJavaScriptだけで音声入力が実現できてしまうらしい。
というわけで、スマホ向けサイトメニュー
(http://fluorite.halfmoon.jp/m/)
の全文検索のキーワード入力に組み込んでみた。
スマホとタブレットで動作確認。へー、すげー。こんな簡単に出来てしまうのか。
本体はSpeechInputWsオブジェクト(グローバル定義)で、こんな感じで使う。
jQuery利用前提(タグ内の内容書き換えと、Deferred利用)。
|
speech_input = new SpeechInputWs( null );
// 録音開始ボタンの動作
$("#id_start_button").click(function(){
var dfd = speech_input.start();
dfd.done( function( text ){
$("#id_output").val( text );
});
});
|
≫SpeechInputWsオブジェクトの定義はこちら。
※適当に別ソースファイルにでも記載してください。
|
/*
[speech_input.js]
encoding="UTF-8"
*/
// Googleの音声入力用のクラス定義
// ref. http://qiita.com/inouet/items/2c9e218c05f547bb6852
// ref. http://www.cyokodog.net/blog/web-speechi-api/
//
// noticeOverlay = null指定可能。その場合は、通知用divを自動生成。
// ,start() で、deferred が返るので、.done( text )で取得して任意に設定する。
//
// ※音声入力の実行可能不可能の自前判定は無いので、別途「スマホ/タブレットのみOK」などの
// 処理を実装の事。
//
var SpeechInputWs = function( noticeOverlay ){
var self = this;
this.itsNoticeOverlayDiv = noticeOverlay;
// 通知用のオーバーレイdivが無ければ自前で生成する。
if( !this.itsNoticeOverlayDiv ){
$("body").append( "<div id=\"_id_overlay_notice\">hoge</div>" );
this.itsNoticeOverlayDiv = $("#_id_overlay_notice");
this.itsNoticeOverlayDiv.css({
"display" : "none",
"width" : "280px",
"height" : "160px",
"text-align" : "left",
"position" : "fixed",
"top" : "24px",
"left" : "24px",
"z-index" : "100",
"background-color": "#cccccc"
});
}
// 一応、毎回初期化???
window.SpeechRecognition = window.SpeechRecognition || webkitSpeechRecognition;
// オブジェクト生成
this.itsRecognition = new webkitSpeechRecognition();
this.itsRecognition.lang = 'ja';
this.itsRecognition.maxAlternatives = 3;
};
SpeechInputWs.prototype._selectTextFromSpeechResult = function( speechResult ){
var dfd = new $.Deferred;
var candidate = speechResult.item(0);
var i = candidate.length;
var str;
if ( i == 0 ){
dfd.resolve( candidate.item(0).transcript );
return dfd.promise();
}
// 【FIXME】あれ? .maxAlternatives=3 が効いてない???
if( i > 5 ){ i = 5; }
// 候補を表示してユーザー入力を待つ。
str = ""; // 下記で作成済みのformへ追加するスタイル。
while( 0 < i-- ){
str += "<div><input type=\"radio\" name=\"candidate\" value=\"" + candidate.item(i).transcript + "\">";
str += candidate.item(i).transcript;
str += "</input></div>";
}
this.itsNoticeOverlayDiv.find("form").eq(0).append( str );
this.itsNoticeOverlayDiv.find( "form div" ).each( function(){
$(this).click( function(){
dfd.resolve( $(this).find("input").eq(0).val() );
});
});
this.itsNoticeOverlayDiv.find( "form input[type='button']" ).each( function(){
// 動作を変更する(stop()処理が不要になる。また投げる先のdfdが異なる)。
$(this).click( function(){
dfd.reject( null );
});
});
return dfd.promise();
};
SpeechInputWs.prototype.start = function() {
var dfd_sound = new $.Deferred;
var str = " <form>音声入力中・・・ <input type=\"button\" value=\"中止\"></input><br>";
str += "</form>";
// 音声入力の受付を開始
this.itsRecognition.start();
// ユーザー通知系の処理
this.itsNoticeOverlayDiv.empty();
this.itsNoticeOverlayDiv.append( str );
this.itsNoticeOverlayDiv.show();
this.itsNoticeOverlayDiv.find("form input[type='button']").each( function(){
$(this).click( function(){
self.itsRecognition.stop();
self.itsNoticeOverlayDiv.hide();
dfd_sound.reject( null );
});
});
// 録音終了時トリガーを設定
this.itsRecognition.addEventListener("result", function(event){
// この場面でのthisはグローバル扱いの可能性があるので、クロージャーのselfを経由しておく。
// ※音声入力は常にシングルスレッドで、またユーザー通知も単一、を前提。
var dfd = self._selectTextFromSpeechResult( event.results );
dfd.done( function( text ){
dfd_sound.resolve( text );
}).fail( function(){
dfd_sound.reject( null );
}).always( function(){
self.itsNoticeOverlayDiv.hide();
});
}, false);
return dfd_sound.promise();
};
|
|
JavaScriptのオブジェクト事始め (淡幻星流)
|
5月2日(月) 19:50
|
JavaScriptのオブジェクトの書き方が少しだけわかった気がしたのでメモ。
この処方箋が合うのは、以下の人。
- いわゆるC++やJavaでのクラスの書き方は知っている。
- 且つプライベート変数の隠ぺい(カプセル化)を重視する。
- 継承は出来て欲しい。
- 動作時のメモリ使用量などは気にする(Staticメソッドを意識)
- 「クラス」概念が無いのは知っているけど、「隠ぺい」の観点からはクラスの視点の方が分りやすいと感じる。
先ず、JavaScriptに「クラス」の概念を持ち込みたかったら、
「Google Closure 流のクラスの実現方法の概要」が一番わかりやすい。
http://www.yunabe.jp/docs/javascript_class_in_google.html#google-closure-
ただ、上記だと継承やメモリ使用量は解決できるが(※1)、
プライベート変数の隠ぺいが解決できくて不満。
まぁたぶん「諦めるしかない」が解なのはなんとなく分る。
でも、「そのクラスの中でしか参照されないStaticな定数」くらいは隠ぺいしたい。
※1:動的メンバ変数の初期化は「// クラスとコンストラクタは関数を使って定義します」で実施。
これにより、インスタンス間で独立になる。
「Parson = function( name, age) { 〜 } 」が、クラス視点での「Parsonクラス定義」に相当。
※2:動的メソッドは、prototype演算子を用いて定義する。
これによりメソッドの枠は「プロトタイプ」として1つのみ生成されるので、
メモリ使用量を抑えられる。
new Parson('Alice', 7) しても、メソッドの枠は再生成されない。
動的メソッドは、動的メンバにアクセスできないと意味が無いが、
そこは「this.naem」でアクセス可能。prototype無いのでthisは、呼び出し元の
インスタンスになるので、インスタンス間で区別可能。
※3:「動的メソッド」って言ったけど、その実装で「this」と使わなければ、
これは「静的メソッド」に等しい。そのオブジェクトから new されたすべての
インスタンスで完全に共通に利用されるメソッドだから。
「動的メソッド」はその動作の際に参照されるメンバを明示的な「this」で
切り替えているのが差。
さて、「Staticな定数くらいは隠ぺいしたい」をどうやって実現するか?
私の場合は「それを参照するStaticメソッド毎、即時関数内で定義してやってクロージャーで
隠ぺいを実現する」に落ち着いた。これが一番良いかは知らん。私には分りやすい、という話。
具体的には、以下のようなコーディング。
// 先ずは隠ぺいしたい内部メンバ変数を含むStaticメソッドを
// 即時関数で定義して1オブジェクト(⇒gMultiChoiceSheet_Static)に放り込む。
// ※これは「Static」なので再生成されない。
// したがってreturn時点でfunctionオブジェクト生成しても問題なし。
//
var gMultiChoiceSheet_Static = (function(){
var _CSS_DIV_RADIO_NORMAL = {"background-color": "white"};
// 〜Staticな内部メンバ変数を定義〜
return {
createChoiceHtmlStr :
function( markCharactorArray, numberOfQuestion ) {
var numberOfChoice = markCharactorArray.length;
// 〜中略〜
},
clearChoiceCheckedAll:
function( rootOfChoiceSelector ){
rootOfChoiceSelector.find( "div" ).css( _CSS_DIV_RADIO_NORMAL );
rootOfChoiceSelector.find( "input" ).attr( "checked", false );
rootOfChoiceSelector.find( "div > a > img" ).attr( "src", _IMG_UNCHEKCED );
}
// 〜Staticなメソッドを定義〜
// ※戻り値のオブジェクトのkey/value形式で、valueに関数を定義する。
// ※ここで定義したメソッドは、上記のメンバ変数を参照可能。
};
}())
// 続いて、非Staticなメソッドとメンバを、
// 通常のJavaScriptのプロトタイプ形式で定義する。
// ※この辺の考え方は、以下を参照
// Google Closure 流のクラスの実現方法の概要
// http://www.yunabe.jp/docs/javascript_class_in_google.html#google-closure-
//
var MultiChoiceSheet = function( targetDivSelector ){
this.itsTarget = targetDivSelector;
} // これが「クラス(のコンストラクタ)の定義」に相当。
// 以下、メソッドをprototypeで追加する。
MultiChoiceSheet.prototype
.drawChoice = function( markCharactorArray, numberOfQuestion ) {
var str = gMultiChoiceSheet_Static
.createChoiceHtmlStr( markCharactorArray, numberOfQuestion );
this.itsTarget.empty();
this.itsTarget.append( str );
gMultiChoiceSheet_Static.bindClickActionToChoice( this.itsTarget );
};
MultiChoiceSheet.prototype
.clearChoiceCheckedAll = function(){
gMultiChoiceSheet_Static.clearChoiceCheckedAll( this.itsTarget );
}
使うときは、以下のような感じになる。
var multiChoiceOperate = new MultiChoiceSheet( targetMultipleChoiceArea );
// この「new」操作によって、prototype で設定した2メソッドを思ったオブジェクトの
// インスタンスが生成される。
// 続いて、そのインスタンスの動的メンバ「itsTarget」に、コンスタラクタの引数が
// 設定されて初期化完了。それぞれの2メソッド内での「this」に有効な値が入った状態。
multiChoiceOperate.drawChoice( markerArray, numberOfQuestion );
// multiChoiceOperate インスタンスのdrawChoiceメソッドは、
// 別途定義済みの静的メソッド createChoiceHtmlStr を、必要に応じて、
// 動的なメンバ変数の値を引数に与えて呼び出して、機能を実現する。
静的な機能なのか、動的な機能なのか、を明確に分けてCodingするのが
ポイントなのかな、JavaScriptは?
- 静的な部分=Static機能の部分を、即時関数を用いてシングルトン扱いで1つオブジェクトを生成して提供。
- 動的な部分は、メンバ変数の初期化のみを受け持つコンストラクタ関数を定義して、メソッドはprototypeで定義。
- 実際に使う際には、(2)で定義した関数オブジェクトの「インスタンス」から「new」して、メンバだけ初期化&メソッドの枠は使い回し。
- 実際のメソッド実行時は、prototype定義のメソッドは、インスタンス間の差分のあるところを受け持って、それ以外のStaticに実現可能な機能は、(1)で定義した別メソッドへ委譲して動作させる。
参考:
[prototype図示とnewの挙動 - web newbie]
http://d.hatena.ne.jp/yupug/20070419/1177005839
[Google Closure 流のクラスの実現方法の概要]
http://www.yunabe.jp/docs/javascript_class_in_google.html#google-closure-
|
Android2.3端末ではGoogle Play不可
|
3月17日(木) 19:52
|
自己メモ。
「Android 2.3 端末に、Google Play 経由でアプリを入れるのは 2016年現在は不可」。
余っている古いスマホ/タブレットを、何かに流用できないかと考えているのだが、
その際には「Google Play経由でのAppインストが不可」っての、かなりハードル高い。
少なくとも、手持ちの2端末にて以下を試みて、ダメだった。
- インストール済みのGoogle Paly ⇒ 接続NG(OSが対象外?)
- com.android.vending_4.6.17.apk (2014-3-22) を適用 ⇒ 接続OKだけど、Appインストール時にエラー。
- com.android.vending_5.4.12.apk (2015-4-24) を適用 ⇒ 上同。
Google Play の apk ファイルは以下のブログを参照に入手。
http://www.sumaho-etc.net/?p=90
GoogleServicesFramework.apk、GoogleLoginService.apk、なども当ててみたけどNGだね。
残念。
GooglePlayを開くところまでは進む(この時、日付を正しく設定するのを忘れずに)。
その先のAppインストでNG。
Android 2.3 端末に新規Appを入れる場合は、目的のアプリのapkをどこかから取得してきて、直にインストールするしか無さ気。
このとき、Google Play から取得したapkの場合は、Android 4.x 以降向けに仕様変更されているらしく、インストールNGする確率が大変高いので注意。
少なくとも、当方の環境では、全部NGだった。
なので、Android 2.3 向けのapkをどこかから持ってこなきゃいけないわけだが、、、どこにあるのだ?
ネット上に転がっていると言えば転がっているが、そのファイルが正しいことの検証、どのバージョンなら動作するか?の検証が面倒。
参考までに、当方がapk取得したのは以下のサイト。
Androidのメジャーどころ?のアプリの過去バージョンapkを取得可能。
サンプリング的に、手持ちの別バージョンのapkとバイナリ一致検証して「正しいファイルだろう」って判断して使ったけど、
利用時の妥当性の判断は、自己責任でよろしく。
http://jp.uptodown.com/android
むしろ、以下のページの記事に従って、2.3 → 4.1 へAndroid OSをアップデートしたほうが話が早いかも???
http://macruby.info/android/galaxy-tab-sc01c-android4-upgrade.html
|
SSD, eMMC, HDDの速度比較
|
2月21日(日) 19:52
|
SSDとeMMCとHDDのストレージWrite/Read速度の実効値を比較してみた。
eMMCってのは、スマホやAtom系のWindowsタブレットで使われている、まぁ劣化版SSDみたいなものだ。
CPU性能その他が一致してないけど、まぁ凡その比較把握にはなるかと。
| シーケンシャルRead | ランダムRead |
SSD | ○ | ○ |
eMMC | △ | ○ |
HDD | △ | △ |
- SSD
シーケンシャルもランダムも高速。
- eMMC
シーケンシャルはそこまでじゃないが、ランダムは高速。
- HDD
※「高速」の比較は、このHDDに対して。
|
スマホが良い?ガラケーが良い?
|
1月28日(木) 12:37
|
スマホへ変更すべきか? ガラケーのままでよいか?
について、「これで判断したら?」が見えた気がしたので、書いてみる。
※なお、私は「あの料金払ってまでスマホは要らんだろ」派です。
(A) 群
|
(B) 群
|
-
GoogleMap
(無料で地図と道案内)
- 快適なWebブラウジング
-
SNSへの写真投稿
(FacebookやLINE他)
- 文字より画像
|
- 安い月額料金
-
物理的なキー操作
(指の感覚で操作の成功失敗が判断出来る、って快適)
|
上記の (A) と (B) で、
あなたにとって重要なのはどちらですか? より欲しいのはどちらの項目ですか?
(A) ならスマホがお勧め。
(B) ならガラケーがお勧め。
という場合分けが良い気がしたのだが、どうだろうか?
月額料金については、スマホはガラケーの大体2倍が基準かな。
「電話、メール、バッテリー駆動時間」という観点は、今となって大きくは変わらないので、判断要素に入らくなったと思う。
タブレット?あれはまた別の軸だろう。
「(A)も(B)も両方!代わりに、管理の手間暇は気にしない」という場合は、MVNOでスマホ、もしくは+ガラケーの2台持ち!かなー。
|
Win10へアップグレードした状態で リカバリUSBメモリ作成
|
1月17日(日) 15:21
|
あけまして おめでとう ございます
今年も本サイト「Fluorite」をよろしくお願いいたします。 m(_ _)m
さて。
Windows7/8.1は、Windows10へ無償アップグレードできるので、先日にWindows8.1端末をWindows10へアップグレードしてみました。
アップグレードは問題なく成功。そんで次に気になったのが「これ、OSが壊れたときはどうするの?」ということ。
通常はリカバリメディア他で「再インストール(工場出荷時に戻す)」すればOK。
しかし、手元にあるリカバリメディア他はアップグレード前の状態なわけで、無償アップグレード期間(〜2016/7/29)が終わった後にOS再インストールする羽目になった場合は、元々のWindows7/8.1にしか戻せなくなるわけです。はて?
どうやら、その対策としては「回復ドライブを作成しておく」になる様子。
USBメモリを準備して作成する。ブータブルで、その時点のOSイメージを取り込んでくれるみたい。
私の場合は4GB以上が必要、なので8GBのUSBメモリ(実効7GBちょっとの空き容量)で対応できた。念のため32GBを準備してたのだが、そうかー、そこまでは要らなかったかw
開始から、だいたい1hほどで作成完了。実効容量は2.7GB程度ー。 …あれ?「4GB以上必要」???
作成方法は以下。
-
「コンパネ>高度な回復ツール」を選択。
※スタートボタン?右横の検索ボックスに「回復」って入れて検索しても出てきます。
-
「回復ドライブの作成」を選択。
-
「システムファイルを回復ドライブにバックアップ」にチェック。
-
作成に必要なUSBメモリの容量が示されるので確認する。
-
作成先のUSBメモリに元々あるデータは削除される旨が表示される。「作成」を押すと削除&作成開始。
-
作成が完了するのをひたすら待つ。
私の場合、USB2.0 I/Fで1hくらいかった。
作成したUSBメモリは、USB Image Toolあたりでバックアップしておくと良いかもね〜。
USBメモリなんて、何時データがお亡くなりになってもおかしくないので。
もちろん「データ○年保全!」とか謳っているUSBメモリを買えば大丈夫でしょうけど、当方は格安USBメモリで作ってしまったのでw
なお最初、誤って「バックアップ>バックアップと復元」へ進んだら「16GB以上必要!」って言われた上に「USBメモリ上には作成できません(外付けHDDを用意しろ)」と言われてしまったのは秘密でw
↓こっちに進むのは間違い↓
|
|