自分にはどういう支援ができるのだろうか?
今回の震災と津波の映像をTVで見ましたが、想像を絶するものでした。
たくさんの方々が亡くなったり被災され、心が痛みますといえばもしかすると失礼かもしれません。「被災地にいないのに何がわかるのか?」とも自分で思います。
ですが、自分が何か役に立ちたいという思いがあるのは事実です。
自分の生活や安全は自分で守らなければという思いが、自分が役に立とうとする勇気に対して見て見ぬふりをする言い訳にしてはいけないと思います。とりあえず、貯金を少し切り崩して、募金は明日してこようかと思います。
ただ、多くの人に、特に関西より西の方々にも、それと、ちょっと勇気から逃げてしまう人にも、協力しやすいようチャリティが増えるといいなと思います。募金付きの商品やサービス、特に娯楽系に増やしてほしいと思います。
セレクトボックスの選択肢を連動させる(改)
以前の[id:Mug:20060414#1145023696]において作成していたスクリプトを改造しました。
デフォルト選択について、次のようなロジックを入れました。
- 指定された値をデフォルト選択可能にした。
- 指定が無い場合は、現在の値をなるだけ引き継ぐようにした。
Select.js(Shift_JIS)
/**
* 選択肢クラス
* @param parentValue 親の値(null:いつでも表示)
* @param text 表示テキスト
* @param value 値
* @param style CSS(省略可)
*/
function SelectOption(parentValue, text, value, style) {
this.parentValue = parentValue;
this.setOption = function() {
this.text = text;
this.value = value;
if(style) {
this.style.cssText = style;
}
};
return this;
}/**
* セレクトボックスクラス
* @param id セレクトボックスID
*/
function SelectBox(id) {
/**
* IDに対応オブジェクトを取得
* @return オブジェクトorNULL
*/
function getObject() {
var obj = document.getElementById(id);
if(!obj.options && ( (typeof obj.length) == "number") ) {
if(obj.length > 0) {
obj = obj[0];
} else {
obj = null;
}
}
return obj;
}
// オプションのリスト
var options = [];
/**
* オプション登録
* @param condition 表示条件
*/
this.registOption = function(option) {
options[options.length] = option;
};
// 子のオブジェクト
var child = null;
/**
* 子のオブジェクトを設定する
* @param childObj 子のオブジェクト
*/
this.setChild = function(childObj) {
child = childObj;
};
/**
* オプション反映
* @param parentValue 親の値(null:全部表示)
* ※比較に==を使っているのでundefinedもnullと等しく扱われる。
* @params [defaultValues] 自身以下のデフォルト値(配列または可変数引数)
* 例えば自身から孫までの値を設定するならば、
* xxx.make(null, ["自身の値", "子の値", "孫の値"]); でもよいし、
* xxx.make(null, "自身の値", "子の値", "孫の値" ); でもよい。
*/
this.make = function(parentValue, defaultValues) {
var obj = getObject();
if(obj) {
// デフォルト値調整
var defVals;
switch(arguments.length) {
case 0:
case 1:
defVals = [];
break;
case 2:
if(defaultValues instanceof Array) {
defVals = defaultValues;
} else if(defaultValues && ( (typeof defaultValues) == "object") && ( (typeof defaultValues.length) == "number") ) {
defVals = defaultValues;
} else {
defVals = [defaultValues];
}
break;
default:
defVals = Function.prototype.call.apply(function() { return arguments; }, arguments);
}
// 選択すべき値
var vals = {};
if(defVals.length > 0) {
vals[ defVals[0] ] = true;
defVals = Function.prototype.call.apply(function() { return arguments; }, defVals);
} else {
for(var i = 0; i < obj.options.length; i++) {
if(obj.options[i].selected) {
vals[obj.options[i].value] = true;
}
}
}
// 選択肢削除
obj.options.length = 0;
// 表示すべき選択肢抽出
var opt = (parentValue != null) ? [] : options;
if(parentValue != null) {
for(var i = 0; i < options.length; i++) {
if( (options[i].parentValue == null) || (options[i].parentValue == parentValue) ) {
opt[opt.length] = options[i];
}
}
}
// 選択肢反映
obj.options.length = opt.length;
for(var i = 0; i < opt.length; i++) {
opt[i].setOption.call(obj.options[i]);
obj.options[i].selected = (vals.hasOwnProperty(obj.options[i].value) && vals[obj.options[i].value]);
}
// 子のオブジェクトにも連鎖反映
if(child) {
child.make(obj.value, defVals);
}
}
};
return this;
}
HTMLファイル(使用例)
<html>
<head>
<title>セレクトボックス親子関係</title>
<script type="text/javascript" src="Select.js" charset="Shift_JIS"></script>
<script type="text/javascript"><!--var box1 = new SelectBox("sb1");
box1.registOption(new SelectOption(null, "都道府県", "0", "color:gray;"));
box1.registOption(new SelectOption(null, "東京都" , "1"));
box1.registOption(new SelectOption(null, "神奈川県", "2"));
box1.registOption(new SelectOption(null, "埼玉県" , "3"));
box1.registOption(new SelectOption(null, "千葉県" , "4"));
var box2 = new SelectBox("sb2");
box2.registOption(new SelectOption(null, "区市町村", "0", "color:gray;"));
box2.registOption(new SelectOption("1" , "千代田区", "1"));
box2.registOption(new SelectOption("1" , "中央区" , "2"));
box2.registOption(new SelectOption("2" , "横浜市" , "3"));
box2.registOption(new SelectOption("2" , "川崎市" , "4"));
box2.registOption(new SelectOption("3" , "与野市" , "5"));
box2.registOption(new SelectOption("4" , "千葉市" , "6"));
var box3 = new SelectBox("sb3");
box3.registOption(new SelectOption(null, "詳細" , "0", "color:gray;"));
box3.registOption(new SelectOption("1" , "一番町" , "1"));
box3.registOption(new SelectOption("3" , "みなとみらい", "2"));
box3.registOption(new SelectOption("6" , "マリンスタジアム", "3"));
box1.setChild(box2);
box2.setChild(box3);
window.onload = function() {
box1.make(null, "2", "3");
};
//--></script>
</head>
<body>
<form>
<select id="sb1" onchange="box2.make(this.value);"></select>
<select id="sb2" onchange="box3.make(this.value);"></select>
<select id="sb3"></select>
</form>
</body>
</html>
このように、boxObj.make(親の値, 自身の値, 子の値, 孫の値, ...);とすることで、デフォルト値を設定可能としました。
ディレクトリのビジター関数
ディレクトリ(フォルダ)のビジター関数があると便利だなぁ・・・と思いまして、しばらく前に作ってみました。
他への依存はありません。
var dir = (function()
{
var SHL = new ActiveXObject("WScript.Shell");
var FSO = new ActiveXObject("Scripting.FileSystemObject");
/**
* ディレクトリの直下のオブジェクトに対してビジターを動作させる
* @param visiter Function ビジター関数(第1引数にディレクトリ(フォルダ)またはファイルを受ける)
* @param base [String|Folder] ディレクトリパスまたはフォルダオブジェクト
* @param withDir [Boolean] 子のディレクトリに対してビジターを実行するかどうか(省略時はtrue)
* @param withFile [Boolean] 子のファイルに対してビジターを実行するかどうか(省略時はtrue)
*/
function dir(visiter, base, withDir, withFile)
{
if(!base)
{
base = SHL.CurrentDirectory;
}
if((typeof base) == "string")
{
base = FSO.GetFolder(base);
}
if(arguments.length <= 2)
{
withDir = true;
}
if(arguments.length <= 3)
{
withFile = true;
}
if(withDir)
{
var dirs = base.SubFolders;
if(dirs)
{
for(dirs = new Enumerator(dirs); !dirs.atEnd(); dirs.moveNext())
{
visiter(dirs.item(0));
}
}
}
if(withFile)
{
var files = base.Files;
if(files)
{
for(files = new Enumerator(files); !files.atEnd(); files.moveNext())
{
visiter(files.item(0));
}
}
}
}
return dir;
}
)();
var nest = (function(dir)
{
/**
* ルートディレクトリ以下のネストされたオブジェクトに対してビジターを動作させる
* @param visiter Function ビジター関数(第1引数にディレクトリ(フォルダ)またはファイルを受ける)
* @param root [String|Folder] ルートとするディレクトリパスまたはフォルダオブジェクト
* @param withDir [Boolean] 子のディレクトリに対してビジターを実行するかどうか(省略時はtrue)
* @param withFile [Boolean] 子のファイルに対してビジターを実行するかどうか(省略時はtrue)
*/
function nest(visiter, root, withDir, withFile)
{
if(arguments.length <= 2)
{
withDir = true;
}
if(arguments.length <= 3)
{
withFile = true;
}
dir(visiter, root, withDir, withFile);
dir(function(dir) { nest(visiter, dir, withDir, withFile); }, root, true, false);
}
return nest;
}
)(dir);
また、(上記はファイルにまとめるとして、そのファイルを)使う側でもう一度ラップするともう少しだけ便利になります。
私は引数を省略した場合はファイル名orディレクトリ名を文字列化するようにし、WSHコンソールに組み込んでみました。
dir = (function(dirV) {
return function() {
if(arguments.length <= 0) {
dirV.apply(this, [文字列化関数]);
} else {
dirV.apply(this, arguments);
}
};
})(dir);
nest = (function(nestV) {
return function() {
if(arguments.length <= 0) {
nestV.apply(this, [文字列化関数]);
} else {
nestV.apply(this, arguments);
}
};
})(nest);
JSDのサンプルを更新
JavaScriptのソースコードからドキュメントを自動生成できるJSDコンパイラ*1。最近はJSDコンパイラを改良するのは中断して、ECMAScriptネイティブのJSDを生成させるためのソースを作っていました。
現在、手元に存在するクラス全てを一度にコンパイルした結果のXML(XSLTあり)を載せます。*2
※IE6.0,Firefox2.0で表示確認しています。(Operaは最新版(9.24)でも変な部分あり)
JSD(=JavaScriptDocument)をコンパイルしたXMLのサンプル
これら全てをコンパイルすると、約70分近くかかっていました。一度にコンパイルする量を2倍にすると、相互リンクは2倍以上に増えるため、かかる時間は2倍以上になるようです。(逆に10個くらいだと1分かからないのですが…)