+ JavaScript の質問用スレッド vol.66 +

このエントリーをはてなブックマークに追加
939Name_Not_Found:2008/10/06(月) 11:30:23 ID:???
バグなら回避しようが無いんじゃないかなぁ
940Name_Not_Found:2008/10/06(月) 11:46:45 ID:???
>>937
そういうことだけどこうじゃないの?
.replace(new RegExp(escBackSlash, "g"), "\\\\");
.replace(new RegExp(escVariable, "g"), "\\%");

こういう方法でやる以上、どこまでユニークにしてもスマートじゃないしなによりキリが無いから
好きな文字を使えばいいよ
ただあんまり長いと遅くなるから。
941931:2008/10/06(月) 13:20:54 ID:???
>>940
他にも間違いがあったのでとりあえず現在のコードを貼ります。
function conv(str){
    var list = {HOGE:"foo",FOO:"bar"};
    var escBackSlash = "\x02";
    var escVariable = "\x03";
    return str
        .replace(/\\\\/g,escBackSlash)
        .replace(/\\%/g,escVariable)
        .replace(/%(\w+)%/g,function(whole,p1){return list[p1]})
        .replace(new RegExp(escBackSlash,"g"),"\\")
        .replace(new RegExp(escVariable,"g"),"%");
}
var str = "c:\\hoge\\\\%HOGE%\\\\%FOO%.txt";
alert(conv(str)); //c:\hoge\foo\bar.txt

var str = "c:\\hoge\\\\\\%HOGE%\\\\%FOO%.txt";
alert(conv(str)); //c:\hoge\%HOGE%\bar.txt

正直すごく混乱してきました。整理します。
\\%HOGE% の \\ は %HOGE% をエスケープするためのもの。
%HOGE%を変換したい場合はエスケープしていない %HOGE% が必要。
しかしセパレータの \\ をつけて \\%HOGE% とするとエスケープされるので
セパレータの \\ をエスケープする \\ をつけて \\\\%HOGE% とする。
つまり \\\\ はパスセパレータだから最終的に \\ にならなければならない。
%HOGE% をエスケープした \\%HOGE% の \\% は %HOGE% をそのまま表示するためのものだから
最終的には \\%HOGE% ではなく %HOGE% を出力しなければならない。

という理由で↓こうなったんですが・・・
        .replace(new RegExp(escBackSlash,"g"),"\\")
        .replace(new RegExp(escVariable,"g"),"%");
942931:2008/10/06(月) 13:40:41 ID:???
さらに、
c:\\hoge\\\\%HOGE%\\\\%FOO%.txt の
\\\\がセパレータなのだとしたらc:\\hogeの\\はなんなのか?
エスケープに関して二つのルールを同時に適用している状態?
統一してc:\\\\hogeとするべきなのかとも思うけどそれもおかしな話な気がする。

%HOGE%のエスケープに\\を使うのがそもそもの間違い?
それとも%HOGE%はエスケープできないという仕様にすべきか?
でもフォルダ名、ファイル名に%は使える。

・・・すいません誰か整理してくださいw
943Name_Not_Found:2008/10/06(月) 13:54:07 ID:???
とりあえずセパレータとしての \ はエスケープ文字じゃないから
>%HOGE%のエスケープに\\を使うのがそもそもの間違い?
ということ

今回の質問内容は戻り読みに代わる処理方法だったわけだから
退避させるために置換した文字たちは同じように元に戻さないと駄目
944Name_Not_Found:2008/10/06(月) 15:15:44 ID:???
クックブックのp52ですが、「あるエンティティに関連したデータがグローバル領域にあり、何度も参照する必要がある場合はオブジェクトを使うべきでしょう」
というのはどういう意味ですか?
前の文章ではオブジェクト指向の経験をjavascriptに持ち込み過ぎることの弊害が書かれていました。
945Name_Not_Found:2008/10/06(月) 15:45:13 ID:???
イベントデリゲーションについて質問です。

<div id="images">
<img id="img1" (略)>
<img id="img2" (略)>
(略)
<img id="img10" (略)>
</div>

に対して、onloadで次のようにイベントを設定しています。
for(i=1; i<=10; i++) {
img=document.getElementById('img'+i);
img.onclick=function(){ hoge(this) };
}

これを個々のimgではなく、その親の<div id="images">でイベントを監視する
方法があるようですが、具体的なやり方がわかりません。
どのようにすればいいのか、教えてください。

それと、テンプレ >>4 のQ14の意味が理解できません。
上の
img.onclick=function(){ hoge(this) };
は問題があるのでしょうか?

以上、よろしくお願いします。
946931:2008/10/06(月) 18:30:48 ID:???
>>943
>今回の質問内容は戻り読みに代わる処理方法だったわけだから
>退避させるために置換した文字たちは同じように元に戻さないと駄目
確かにそうですね。

ということで仕切り直します。
戻り読みに代わる処理方法としては問題ないようなので後は
「%HOGE% のエスケープに \\ 以外の文字を使う」
ということになると思いますが、
どの文字を使うのが一番問題が少なそうですか?

または根本的に違うアプローチにしたほうがいいのでしょうか
947928:2008/10/06(月) 19:21:21 ID:???
>>932
わかりました。ありがとうございます。m(_ _)m
948Name_Not_Found:2008/10/06(月) 20:32:19 ID:???
>>945
>イベントデリゲーション
アホ外人氏の出番ですな

>テンプレ >>4 のQ14の意味が理解できません。
解り難いねこれ。
「thisを含めたい」だけじゃ目的が解らないし、
回答も var x = this; とするだけで済む所をややこしい書き方して余計に難解にしてる。
とりあえず>>945のコードとは関係無いし問題も無いかと。
949Name_Not_Found:2008/10/06(月) 21:20:28 ID:???
>>945
document.getElementById('images').onclick = function(evt) {
evt = evt || event; // バカIEをfixして
var tgt = evt.target || evt.srcElement; // バカIEはsrcElementだっけ?
if (tgt.tagName.toLowerCase() != 'img') return;
// tgtはimg要素
hoge(tgt);
};
950Name_Not_Found:2008/10/06(月) 21:46:25 ID:???
上書き可能なonclickプロパティでデリゲーションしても危険なだけだろjk
951Name_Not_Found:2008/10/06(月) 21:50:04 ID:???
>>950
attachEvent/detachEvent
addEventListener/removeEventListener
てこと?
952923:2008/10/06(月) 22:47:31 ID:???
>>935
ごめんね。ほんとごめん。
953Name_Not_Found:2008/10/06(月) 23:15:09 ID:???
>>923
なんで罵られてんの?
954Name_Not_Found:2008/10/06(月) 23:17:43 ID:???
故意犯だから
955Name_Not_Found:2008/10/07(火) 08:28:42 ID:???
新スレは975超えたら。FAQのQ14を手直ししたいなら大体案を。
旧道場訓に戻したいという人は現れなかったようだね。
956945:2008/10/07(火) 10:46:34 ID:???
>>948-951
レスありがとうございます。

>>949
丁寧にありがとうございます。
event target srcElement でググってきます。
957Name_Not_Found:2008/10/07(火) 12:24:51 ID:???
質問です。例えば、
var object = document.all('hoge')とかおいて、後で
object.value見たいにして呼び出すようにすると動作が遅くなった
り、コード読み取りに負担を掛けたりしますか。1つ2つならいいと思う
としても、たくさんあるとやはり問題でしょうか。
958Name_Not_Found:2008/10/07(火) 12:33:34 ID:???
>>957
必要なら書けばいい
それよりメル欄自重w
959Name_Not_Found:2008/10/07(火) 13:21:53 ID:???
沢山て数十万個とか?
960Name_Not_Found:2008/10/07(火) 17:05:46 ID:???
動的に要素が追加されたり削除されたりすることがないことが保障されてるんなら
静的キャッシュでも作れば少しは軽くなるんじゃないの
961957:2008/10/07(火) 23:19:40 ID:???
>>958~960さん
貴重なアドバイスありがとうございました。
962Name_Not_Found:2008/10/08(水) 16:01:02 ID:???
js文字列にマッチする正規表現をRegExpコンストラクタで作る例なんですが、
new RegExp("\"(?:\\.|[^\\\\\\\"])*\"", 'g')

\\.
の部分がなぜ必要なのか分かりません。
new RegExp("\"[^\\\\\\\"]*\"", 'g')
では駄目ですか?
963962:2008/10/08(水) 16:03:23 ID:???
あっ自己解決しました。エスケープシーケンスにマッチするためですね。
なんで分からなかったのか不思議です。
964Name_Not_Found:2008/10/08(水) 16:16:47 ID:???
よく調べていると>>963は間違いだと分かりました。
"\19800"のような文字列にマッチさせるために必要、の間違いでした。訂正します。

あと、>>962の例は間違いでした。
new RegExp("\"(?:\\.|[^\\\\\\\"])*\"", 'g')
では"\19800"にマッチしないので
new RegExp("\"(?:\\\\.|[^\\\\\\\"])*\"", 'g')
が正解でした。

これで正しいでしょうか?間違いがあれば指摘お願いします。
965962:2008/10/08(水) 16:18:36 ID:???
>>964は"\19800"ではなくて"\\19800"でした。頭混乱してました。すみません。
966Name_Not_Found:2008/10/08(水) 16:30:56 ID:???
new RegExp('"(?:[^"]|\\\\")*"', 'g')
/"(?:[^"]|\\")*"/g
967Name_Not_Found:2008/10/08(水) 16:41:20 ID:???
正確にはjavascriptの質問ではないですが。

Canvasタグに関しての質問で
function a(){
       Canvasタグの処理(以下略)
      }
function b(){
Canvasタグの処理(以下略)
      }
と二つの図形をCanvasで描画してそれぞれのidを別とした場合、
それを同時に画面に出したいのですが、どうすれば良いのでしょうか?
968Name_Not_Found:2008/10/08(水) 16:58:35 ID:???
関数実行中は画面の再描画がされないから、一つの関数にまとめれば見た目的には同時に出力されるんじゃない?
試してないからわかんないので報告お願い

(function(){})(a();
);
969Name_Not_Found:2008/10/08(水) 17:02:25 ID:???
ごめん 編集途中で書き込まれた

(function(){
a();
b();
})();
970962:2008/10/08(水) 17:35:51 ID:???
>>966
簡潔ですね。ただし、その場合だと'\\\'のように不正なリテラルにもマッチします。
971Name_Not_Found:2008/10/08(水) 18:44:10 ID:???
/"(?:[^"\\]|\\.)*"/
972962:2008/10/08(水) 19:16:51 ID:???
>>971
>>964と同じですね。
973967:2008/10/08(水) 22:09:59 ID:???
>>968
ありがとうございます。
少しこちらの説明が抜けていましたので訂正します、手間かけさせてすいません。
Canvasタグを使う際、描画した関数にIDをつけて

<body onload="関数名">
<canvas id="描画した図のID" width=〜 height=〜>
</canvas>
</body>

のようにすれば出力されるのですが。
これをaとbで分けると、両方を出したいのにどちらか一方しか出せないという事態になります。
ここで、新しい関数を作ってそこにaとbを出し、IDを指定してやれば出るのでは?と思い実行してみましたが。
結果は出ませんでした。やはりこのような方法では無理なんでしょうか?
974Name_Not_Found:2008/10/09(木) 01:35:41 ID:???
ごめん何いってんのか分からん
975Name_Not_Found:2008/10/10(金) 14:28:24 ID:???
IEのfilterについて質問です。

■CSS
div.test{
filter : progid:DXImageTransform.Microsoft.AlphaImageLoader(sizingMethod=crop,src="foo.png");
/* foo.png は透過png */
}

■JS
var div = document.createElement("div");
div.className = "test";
document.body.appendChild(div);
var cs = div.currentStyle || document.defaultView.getComputedStyle(div,"");
div.onclick = function(){
div.style.filter = cs.filter + "¥n" + "alpha(opacity=100)"
}

上記のようにAlphaImageLoaderで透過pngを貼った要素に対して、
alphaで透明度を100にすると、手元のXPSP2/IE7ではpngが透過では
なくなってしまうようです(黒ベタ塗り60%透過のpngで試しました)。

これは仕様ですかね?
976Name_Not_Found:2008/10/10(金) 14:33:01 ID:olgLrLH/
CGIに埋め込んでるんですが
document.write("<input type=\\"text\\" size=\\"18\\" name=\\"name"+(i+1)+"\\" value=\\"$name"+(i+1)+"\\">");

この$name と数字を連結する方法ないですか?
$nameしか反映しない
977Name_Not_Found:2008/10/10(金) 14:42:12 ID:???
>>976
どうなって欲しいのがどうなってしまうのかよくわからないんだけど。
978Name_Not_Found:2008/10/10(金) 14:58:03 ID:olgLrLH/
>>977
$nameに入るべき数字が「あ」だった場合
valueに「あ1」とか「あ2」とか、$nameに入ってるものの語尾に(i+1)の数字そのものが一緒に出てくる
979Name_Not_Found:2008/10/10(金) 15:13:20 ID:???
>>975
仕様です
980Name_Not_Found:2008/10/10(金) 15:16:31 ID:???
>>976
エスパーになったつもりで答えると、

$nameの中身が数字で、valueに「$name+i+1」の値を入れたいなら↓

document.write("<input type=\\"text\\" size=\\"18\\" name=\\"name"+(i+1)+"\\" value=\\""+($name+i+1)+"\\">");

valueに「$name(i+1)」という名前の変数の中身を入れたいならCGI側のプログラム言語の問題でスレ違い。
981Name_Not_Found:2008/10/10(金) 15:16:53 ID:???
>>978
で、今はどのようにうまくないって?
「document.write("<」を削除して画面に表示させ
どのようになってるか見て確認したらいいかも。
982Name_Not_Found:2008/10/10(金) 15:18:06 ID:???
>>975
そですか。ありがとう。
>>976
回答まちのあいだにエスパー発動
1.実際に出力したいのはこう
<input type="text" size="18" name="%%%%%%" value="###%%%">
2.JSでdocument.writeに文字列として渡す為にクォートをエスケープ、%%%%%%は変数なので切り離す
document.write("<input type=¥"text¥" size=¥"18¥" name=¥"" + "%%%%%%" + "¥" value=¥"###" + "%%%" + "¥">");
3."%%%%%%"をJSの変数に置き換える
document.write("<input type=¥"text¥" size=¥"18¥" name=¥"" + name+(i+1) + "¥" value=¥"###" + (i+1) + "¥">");
4.とりあえずエスケープされたクォートを仮に★に置き換え
document.write("<input type=★text★ size=★18★ name=★" + name+(i+1) + "★ value=★###" + (i+1) + "★>");
5.echoに文字列として渡す為にクォートをエスケープ
echo "document.write(¥"<input type=★text★ size=★18★ name=★¥" + name+(i+1) + ¥"★ value=★###¥" + (i+1) + ¥"★>¥");";
6.エスケープ文字もエスケープして★を元に戻す(★ => ¥¥")、######は変数なので切り離す
echo "document.write(¥"<input type=¥¥"text¥¥" size=¥¥"18¥¥" name=¥¥"¥" + name+(i+1) + ¥"¥¥" value=¥¥"" + "###" + "¥" + (i+1) + ¥"¥¥">¥");";
7."######"をCGIの変数に置き換える
echo "document.write(¥"<input type=¥¥"text¥¥" size=¥¥"18¥¥" name=¥¥"¥" + name+(i+1) + ¥"¥¥" value=¥¥"" + $name + "¥" + (i+1) + ¥"¥¥">¥");";
983Name_Not_Found:2008/10/10(金) 15:19:55 ID:???
984982:2008/10/10(金) 15:21:05 ID:???
つか、CGIの言語がわからん。
echoの引数を+でつなげる言語ってなんだ?
985982:2008/10/10(金) 15:24:20 ID:VFYbeZHW
phpだと.でつなぐ。

6.エスケープ文字もエスケープして★を元に戻す(★ => ¥¥")、######は変数に置き換える
echo "document.write(¥"<input type=¥¥"text¥¥" size=¥¥"18¥¥" name=¥¥"¥" + name+(i+1) + ¥"¥¥" value=¥¥"".$name."¥" + (i+1) + ¥"¥¥">¥");";
7.おしまい。
986Name_Not_Found:2008/10/10(金) 15:36:58 ID:???
>>980
スレ違いの方でした
ジャバで連結できるのかと思っていました
ごめんなさい
>>981
今は出力するはずの物が「あ」だったら
あ1
あ2
あ3
あ4
あ5
こうなってる

>>982−985
分かりやすくありがとうございました

頑張ります
987Name_Not_Found:2008/10/10(金) 16:42:35 ID:???
988Name_Not_Found
GreaseMonkeyのスクリプトとして書いたのですが、これを一つのスクリプトにしたいんです。
そのまま一つのファイルにしたら上のスクリプトしか動かないし、if文の条件で出来るのでしょうか。
どなたか改善方法をおねがいします。
// ==UserScript==

// @name 1yen_bid_units

// @namespace
// @description 入札価格を1円
// @include https://sa.step.rakuten.co.jp/*

// ==/UserScript==

document.getElementsByName("bid_units")[0].value = "1";
document.forms[num].bid_units.value = "1";
document.forms[num].childNodes[1].value = "1";


// ==UserScript==

// @name 1yen_bid_price

// @namespace
// @description 入札個数を1個
// @include https://sa.step.rakuten.co.jp/*

// ==/UserScript==


document.getElementsByName("bid_price")[0].value = "1";
document.forms[num].bid_price.value = "1";
document.forms[num].childNodes[1].value = "1";