+ JavaScript の質問用スレッド vol.117 +
リクエストを送っている間jsが止まるのが同期
innerHTMLとnodeValueの値が違うのですが2つは同じじゃないんですか?
>>530 すると非同期関数は、実行中に処理が戻ってくることがあるのですか?
遅延実行されるだけで、実行中はブロックされると思ってました
533 :
Name_Not_Found:2014/07/20(日) 08:46:45.00 ID:xYE3uywO
>>531 innerHTMLはHTMLパーサが正規化した後のHTML
nodeValueはノード毎の固有値(nodeTypeによって値が異なる)
DOMとHTML5の仕様書を読もう
シングルスレッドで動いているJSが
ノンブロッキング処理できるのは何故ですか?
innerHTMLだったりjqueryのhtmlだったりって非推奨なのですか?
documentに大量ノードがあって、あからさまにid=hogeのテキストだけ更新、みたいな場合なら
やらないほうがいいというのはわかるのですが
何が何でも部分的にappendやらremoveやらをちまちま更新した方が良いのでしょうか?
普通に使っていい
>>534 シングルスレッドで動くのは、JavaScriptの実行環境で動く
あなたが作ったスクリプトであって、
JavaScript実行環境自体はマルチスレッドだからです。
>>532 最後の行の認識で合ってる
10秒かかる関数なら同期だろうと非同期だろうと10秒ブロックされるのは一緒
その時点で実行される(同期)かされない(非同期)かってだけ
WebWorkerを使わない限りはシングルスレッド
jqueryで
プラグインで追加されたメソッドの一覧を知る方法ありますか?
540 :
Name_Not_Found:2014/07/20(日) 14:04:19.55 ID:6iUelLMD
>>535 innerHTMLの問題点がわかっているなら使ってもいい
innerHTMLの問題点なら、jQueryのparseHTMLメソッドで解決できるよ。
だから今更遅いappendやremoveなんかを使う理由がない。
innerHTMLの問題点って出力にそのまま使ったりしちゃ(攻撃者のコードが入るかもしれないから)ダメよってことであってる?
>>537 それは違うのでは?
仕様書にJavaScriptはマルチスレッドでなくてはいけないとか書かれてるんですか?
>>544 仕様書には特に何も書かれているだろう。
何も書かれていないということは自由だ。
だからマルチスレッドにしてもよい。
マルチスレッドじゃなくても実装できるなら
別に構わないが。
同期か非同期かって具体的にどんな場面で気にするのかわからん
パフォーマンスを無視できるのならブロッキングI/Oが自然
つまりパフォーマンスを気にする時にノンブロッキングI/Oが使われる
はい論破
ユーザー定義メゾットの対義語って何ですか?
組み込み関数以外でお願いします
>>547 何を論破してるのかわからんが、単なるパフォーマンスではないぞ
>>546 一般に、処理の中で
すぐにやらなくてもいい(画像の描画など)
すぐにやれない(他の処理の結果に依存するものなど)
終了時が予測できない(サーバのレスポンス待ちなど)
部分は非同期、すなわち後回しにする
GUI フロントエンドの場合は利用者を待たせないことが主な目的になる
>>550 その処理の中で、サーバ側じゃなくてクライアント側でやる必要のある例ってどんなのがある?
画像の描画については同期・非同期を気にするパターンがそもそも思いつかなかった
>>547 自前の重い処理があった場合は非同期にしてもパフォーマンスは向上しない
はい論破
>>554 そんな1+1=2みたいなこと言われても言葉に困るわ
そもそも同期/非同期っていう言葉がわかりにいんだよな
同期と言う言葉には調和やコントロールのイメージ、
非同期と言う言葉には不調和やアンコントロールのイメージがあるから。
しかし実態は逆で、同期的操作は時に不調和をもたらす
だからブロッキング/ノンブロッキングの方が適切だと思う
でもまあ、ブロックと言われても、
レゴ?って思うのが普通だろうな。
総合スレから飛んできました。現在、selectのidごとに関数を呼び出していますが、もっと
簡略化してどのオプションから選択されたかに変えることはできるでしょうか?
$(function(){
$("#f1").each(function(){
var pos;
function call_list(){省略}
$(this).each(function(){call_list();});
$("#sel1").change(function(){
pos = $("#sel1 option:selected").val();
call_list();
});
$("#sel2").change(function(){
pos = $("#sel2 option:selected").val();
call_list();
});
});
});
</script>
</head>
<body>
<form id="f1">
<select id="sel1">
</select>
<select id="sel2">
</select>
<select id="sel3">
</select>
</form>
</body>
省略部分
$.ajax({
url:"ajax_call.php" ,type:"post",data:{"send":pos}
}).done(function(ret){
//alert(ret);
$("#sel2").children().remove();
$("#sel3").children().remove();
var i;
var sels = new Array("#sel1","#sel2","#sel3");
var pack = ret.split(":");
for( var i=0 ; i < pack.length; i++){
var sep = pack[i].split("@");
for(j=0;j< sep.length -1;j++){
var option = $("<option>");
var opt = option.html(sep[j]);
option.val(sep[j]);
var sel = opt.appendTo(option);
sel.appendTo(sels[i]);
}
}
}).fail(function(){
alert("error");
>>558-559のリファクタリング後
$(function(){
function threeSelectFrom(element) {
function refresh(pos) {
$.post("ajax_call.php", {send: pos}, function(ret) {
$(".sel2, .sel3").empty();
$.each(ret.split(":"), function(i, item) {
var values = item.split("@");
values.pop();
var options = $.map(values, function(value) {
return $("<option>").html(value).val(value);
});
$(".sel"+(i+1)).append(options);
})
}).fail(function() {
alert("error");
}
}
$(".sel1, .sel2").change(function() {
var pos = $(this).find("option:selected").val();
refresh(pos);
});
refresh();
}
$("#f1").each(function() {
threeSelectFrom(this);
});
});
idを持たせずに
どのオプションから選択されたかを判定したいってこと?
別に、id持たせたらいいじゃん
何があかんねん
> 何があかんねん
そりゃ再利用しづらいからだろ?
同じものが2つ以上でたら使えない。
最近はIDを使うことって少なくなったな。
classやnameあたりで十分だよ。
>>553 >画像の描画
クライアントのブラウザ側が非同期にやってくれるので
クライアントのスクリプト側が気にする必要は普通無い
> クライアント側でやる必要のある例
一般論だが
API にイベントハンドラが用意されていない種類の処理で
非同期にやる必要があるもの、または、自前の重い処理は、
クライアントのスクリプト側で非同期処理を書くことになるだろう
(重い処理は Worker 利用するか、細分化して setInterval や requestAnimationFrame など)
JavaScriptで同期処理されるのって、
alertとconfirmぐらいなんだよな。
ブラウザ開発の初期に初期にこういう設計にしたの
凄いと思うわ。そのおかげでGUIとかアニメーションに
時間がかかるようなものでも、自然と非同期にプログラミング
するようになった。
リフロー
567 :
Name_Not_Found:2014/07/20(日) 23:40:33.20 ID:OP/8zzrX
>>542 XSSも問題点の一つだが、既存のDOMノードの参照が失われる問題の方が影響範囲が大きい
当然ながら
>>541は解決法にはなっていない
568 :
Name_Not_Found:2014/07/20(日) 23:41:12.74 ID:OP/8zzrX
>>542 XSSも問題点の一つだが、既存のDOMノードの参照が失われる問題の方が影響範囲が大きい
当然ながら
>>541は解決法にはなっていない
詳しく
javascriptを使ったゲームが、FireFoxとGoogleChromeでは見られるのですが、IE11では読み込み画面から進みません
IEのセキュリティのレベルのカスタマイズでスプリクトの項目は全て有効にしたのですが無理です
どうやったらIEで見られるようにできますか
確かに判定するためにDOMのidを使うのは無駄に消費するから駄目だな
data-idを使うべし
class使えって意見は意味わかんね
コマンド実行に一意性のあるidがいるのは当たり前
全部書き換えるから要素のポインタを持ってる時とかに問題になりやすいって意味じゃないの
要素にイベントハンドラ付けてたときとか
まとめると、XSSに十分気をつけていればinnerHTML使っても全く問題ないと
NO
innerHTMLのリスクとデメリットを分かっていたら問題ないでFA
578 :
Name_Not_Found:2014/07/21(月) 08:23:02.22 ID:zKuuycwC
既存のDOMの参照がなくなる・・・ってそれただの把握できてないアホ
どうせ前にDOMが壊れるって騒いでたやつだ
把握できてるからこそだと思うが・・・
想定していたものじゃなくなるって意味だろ
アクロバティックな解釈して頓珍漢な批判をする馬鹿が最近多いな
>>567 > XSSも問題点の一つだが、既存のDOMノードの参照が失われる問題の方が影響範囲が大きい
それは、ノードを入れ替える以上
何を使おうが絶対発生する。
そこでjQueryがでてくる。jQueryを使っていれば、
これは問題にならない。(適切に処理してくれる。
どのレスをみても「何故」がみえてこないな
サンプルコードを書いてみてくれんか
分からないなら多分問題ないよ
ある程度複雑な処理をしてないと問題出ないから
その複雑な処理が何かって話なんだが、
結局、問題が出るコードはだせないんだね。
ここまででみんな気づいたと思うけど、
問題は全くありません。
経験のある技術者には分かることだから
いちいち例を出すのが面倒なだけだろ
まぁ、思いたいように思えばいいんじゃね
コードひとつ書けないこの人はたぶん次はこれを見ろよと英文サイトを出してくる
でも内容的には的外れで突っ込まれて逃げる
俺は経験ある技術者だけど、
DOMの参照がどうたらいう問題は
今まで起きてないよ。
起きたか起きてないかじゃなくて
理解できるかできないか。
経験ある技術者は理解できる。
ん? 理解した上で起きないって言ってるんだけど。
ガベージコレクタって知ってる?
いやそんな話してないしw
分かってねーじゃん。
JSで、新しいウインドウを開き、
データを文字にしたものをそこに出力する
をしたいです
どうしたらいいですか?
>>592 意味が分からんがエスパーするとwindow.opener
ありがとうございます
>>591 じゃあ、おまえが何の話してるか言えよ。
わかってるんだろ?
それを言わないから、問題が起きたんだーっていっても
何の話だと思う?何の話かは言わねぇwww。ってなってるから
誰もおまえの言うことを信じてないんだぞ
>>593 逆じゃね?
>>592 window.openしたら、openしたwindowを返すから、
そのwindowに書き込めばいい。
>>595 だから分からないならいいんじゃねって言ってるだろ
分からないことは責めてないから。
頓珍漢な絡み方をしてくることを責めている
よくwindow.openって書かれますが、
windowいらなくないですか?
何でwindow書くのですか?
参照していたものが失われる可能性がある
↓
ガベージコレクタが回収するから問題ない
なんだこれ
「参照先」に訂正するわ
>>598 openでは汎用過ぎて、なんのopenなのか
わからないから。
コードというのは意図をわかりやすくするのが重要で、
コンピュータにとって問題ないからって省略した方がいいとは限らないんだよ。
コードを読むのは人間なんだから。
MS-Windowsじゃなくてもwindowってつかえるの?
603 :
Name_Not_Found:2014/07/21(月) 20:43:40.17 ID:8atMqUtx
>>582 innerHTML の本質は「上書き」であって「書き換え」ではない
書き換える必要のないDOMノードまで強制的に上書きするのがinnerHTMLの欠点であり、細心の注意を払う必要がある
http://jsfiddle.net/Pc87X/ 上記URLは明確に干渉するコードだが、仮にコーディング時に function runInnerHtml が存在しなかったとしても innerHTML は使わないほうが良い
そうすれば将来的に #Test を参照するコードを書いても問題は発生しないからだ
後々の事も考慮して出来るだけDOMの書き換え対象を小さくする方が安全なコードとなる
> jQueryを使っていれば、これは問題にならない。(適切に処理してくれる。
jQuery は DOM 書き換えにおいて innerHTML 系の処理に頼っており、この手の最小限の書き換えは不得手とする分野だと思うのだが…
例えば、テキストノードの値だけ変更する操作は jQuery には出来ないと思う
もし、jQueryで解決する方法があるのなら是非伺いたい
jQueryって要素の操作は得意だけど
nodeの操作はあんまりだね
あんまりっていうか全然じゃね
nodeTypeを数字で判定すると、
その数字が何だったのか後から見た時に分からないです
nodeTypeを定数として持ってるオブジェクトはないんですか?
>>607 Node.ATTRIBUTE_NODE とか、DOM Interface オブジェクトを利用しては?
なかったら自前で作る
609 :
608:2014/07/21(月) 21:23:32.94 ID:???
ああ、というか Node 使わなくても全てのノードで参照できるな
610 :
608:2014/07/21(月) 21:29:20.45 ID:???
IE8- をサポートするなら自前で作る必要があるか
>>603 初学者なりに見てみたんだけど確かに注意すべき問題だけど
addEventListenerが結果を保持するところとinnerHTMLが持ってくるところが違うから起きる現象に見える
// addEventListenerで追加しないで onClickで仕込むと
>>603のいう問題な動作は起きないところからそう見た
上書きか書き換えか、とか、壊れる、とかいうと予想外の期待されない動作みたいなニュアンスがあるけど
実際は「まー当然こうなるよね」というふうな動作に見えるのだけど、そうではないのかな?
612 :
Name_Not_Found:2014/07/21(月) 21:58:13.30 ID:8atMqUtx
>>611 確かにイベントが解除される問題は <strong id="Test" onclick="changeBackgroundColor(event);"> で回避できる
しかし、その場合も #Test の要素ノードをクロージャでキャッシュしていた場合は参照が切れる
重要なのは参照が切れてしまう事であってイベントの問題が回避できれば解決するわけではない
(他にも参照を利用したコードはあるだろう)
同様の問題は textContent にもある
テキストノードをキャッシュしていたら textContent で上書きすれば参照が切れる
Text#data で値を書き換えれば、参照は切れないので問題は発生しない
テキストノードの間に要素を挟んでテキストノードを分割するなら新しいテキストノードを作成すべきだが、既存のテキストノードを流用できるなら流用した上で値の書き換えにとどめたほうが良い
> 実際は「まー当然こうなるよね」というふうな動作に見えるのだけど、そうではないのかな?
「当然の事象」を理解した上で問題点の少ないコードを模索するのが良いプログラマだと思う
>>603 > innerHTML の本質は「上書き」であって「書き換え」ではない
> 書き換える必要のないDOMノードまで強制的に上書きするのが
は? 当たり前じゃん。 当たり前じゃん。
欠点でも何でもねーよ。
HTMLの中身を入れ替えるんだから変わるに決まってるじゃん。
びっくりした。あまりにも馬鹿すぎて。
当たり前の事を分かって無い奴がどんだけいるんだろうな
単なる$.html()でイベントが消える・・・というか
入れ替えるhtmlにイベント書いてないから当たり前なんだが、
それが嫌なら、$.clone()使えばいいだけ。
http://js.studio-kingdom.com/jquery/manipulation/clone [withDataAndEvents] boolean値で、マッチしている要素に付随している
イベントハンドラもコピーするかどうかを決定します。 jQuery1.4からは保持しているdataも同様にコピーの対象になります。
(初期値はfalseでしたが、jQuery1.5でtrueになり、jQuery1.5.1で再度falseにもどされました。)
[deepWithDataAndEvents] boolean値で、マッチしている要素の全ての子要素に対しても、
付随しているイベントハンドラとDataをコピーするかどうかを決定します。 この初期値は1つ目の引数と同じになります。
>>612 onClickの話は別に解決策を提示したわけではないよ
それで、あらためて
>>533をみてなるほどと思いかけたけど、となると
消えたように見えるリスナーはどこにいっちゃったのか、消滅したわけじゃなさそう
それと、innerHTMLとかinnerTextって書くの楽だし
jQueryをはじめいろんなところで使われまくってるから
使わないじゃなくて、問題点を理解して使っていくうえで賢いやり方とかあるかな?
今って参照を保持したり動的にイベント制御したりがどのくらい頻繁に出てくるのか知らないけど
> 「当然の事象」を理解した上で〜〜
いや、言葉の使い方の話
innerHTMLもhtmlも、「HTML文字列」から
新しいHTMLを生成するもので、イベントハンドラが
HTML文字列に書いてないから、イベントハンドラがないの当たり前だろ。
そういう風に動的に追加される要素にイベントハンドラを付けたいなら
個々に追加する(面倒な方法)か、親要素にイベントハンドラ設定するのが常識。
たとえば $(document).on('click', セレクタ, function() {・・・}) みたいに。
> 消えたように見えるリスナーはどこにいっちゃったのか、消滅したわけじゃなさそう
だから消滅するって。ガベージコレクションって書いただろ。
どこからも参照されなくなれば消える。
innerHTMLやjQueryのhtml()には欠点があるのではなく
注意点があるだけの話。いやはや馬鹿だった馬鹿だったw
619 :
Name_Not_Found:2014/07/22(火) 00:08:55.56 ID:HZZvAY0t
当たり前の事実を目にして、改善するか、何もしないか、の違いだな
やる必要がないことをやらないのは大事だ
やる必要をなくすことも大事だ
まる一日使って613でようやく飲み込むとか本当に馬鹿だな
>>602 別にwindowってWindows固有の用語じゃないしな…
例えばLinuxやUnixの世界にはX Window Systemってのがあるし
jsってgcあるんですね
>>621 理解した上でその判断なら君は本物の馬鹿だ
今年工業高校卒業予定なんですが愛知でインターンシップみたいなのって無いですか
>>621 参照を切らなければ、参照を保持している事を記憶する必要がない
やる必要をなくすことは大切だな
628 :
Name_Not_Found:2014/07/22(火) 08:14:24.14 ID:FatvFhxq
>>616 > 消えたように見えるリスナーはどこにいっちゃったのか
addEventListener に Listener は登録されているので消えているわけではないが、documentとの参照は切れる
もう一度、document にノードを appendChild すればイベントが発火するはず
> それと、innerHTMLとかinnerTextって書くの楽だし
innerText は IE の独自拡張で標準化されていない
使うなら textContent だ
> jQueryをはじめいろんなところで使われまくってるから
最も賢い方法は参照を切らない事だ
jQuery を使うなら olugin を書く必要がある
http://jsfiddle.net/Pc87X/1/ > 問題点を理解して使っていくうえで賢いやり方とかあるかな?
innerHTML を使うなら問題を回避できないので、以下に早く不具合を発見するか、が重要
いくつか考えられるが、今は時間がないので後で後述す
>>628 > addEventListener に Listener は登録されているので消えているわけではないが、documentとの参照は切れる
> もう一度、document にノードを appendChild すればイベントが発火するはず
ノードとそのノードのイベントハンドラが消えるタイミングを勘違いしてるよ。
まずイベントハンドラが消えるタイミングはノードが消えた時。
ここまではいいよね?
じゃあノードが消えるのはいつかというと、documentから消した時じゃない。
documentから消して、さらにJavaScripのどこからも参照がない時。
DOMからremoveChildしたりinnerHTMLで消して、かつ
JavaScriptのどこからも参照されなくなった時にイベントハンドラは削除される。
JavaScriptのどこからも参照がなくなった時だから、
これをJavaScript内で検知するのは不可能。
> innerHTML を使うなら問題を回避できないので、
だからなんの問題?
ということで、
>>628をjQueryとhtml()メソッドを使って、
イベントが解除されないという証拠です。
http://jsfiddle.net/Pc87X/2/ テキスト以外の部分も書き換える可能性があるから
全く同じじゃないが、今の本題はhtml()でメソッドが
解除されるかどうかだから。
ついでにここにもコピペしとく
(function () {
function changeBackgroundColor () {
this.style.backgroundColor = this.style.backgroundColor ? '' : 'orange';
}
function runInnerHtml () {
var str = $('body').html();
str = str.replace('テスト', 'JavaScript');
$('body').html(str);
}
$('#Test').on('click', changeBackgroundColor);
$('#ClickMe').on('click', runInnerHtml);
}());
>>630はhtml()使ってもイベントハンドラが消えないという証拠として書いたもので
しかもなるべくオリジナルに近い形にしたので俺的には気に入らないコードだった。
普通に書いたらこうかな。ってことでついでにちゃんと書いたよ。
http://jsfiddle.net/Pc87X/4/ 短いので、ここにもコピペしておく。
$(function () {
$('#Test').on('click', function () {
this.style.backgroundColor = this.style.backgroundColor ? '' : 'orange';
});
$('#ClickMe').on('click', function () {
$('*').contents().filter(function() {
return this.nodeType === 3;
}).each(function() {
this.textContent = this.textContent.replace('テスト', 'JavaScript');
});
});
});
あ、今気づいたが、getElementById('SampleText')で
対象を絞り込んでたのねw
まあ適当に補完しといてくれ。
いやー、悪い悪い
>>630は自分で書いててて
なんで動くんだって思ったんだw
間違えてたな。うん。動かない。
訂正した奴はこっち。もちろんhtml()は使ってるから安心してな。
やってることは
>>617で説明したとおり
http://jsfiddle.net/Pc87X/5/ (function () {
function changeBackgroundColor () {
this.style.backgroundColor = this.style.backgroundColor ? '' : 'orange';
}
function runInnerHtml () {
var str = $('#SampleText').html();
str = str.replace('テスト', 'JavaScript');
$('#SampleText').html(str);
}
$(document).on('click', '#Test', changeBackgroundColor);
$(document).on('click', '#ClickMe', runInnerHtml);
}());
>>633 html()でイベントが消えないのは分かったが
そのコードだと $('#SampleText')[0].innerHTML = str; でも動いちゃうけどな?
対象のノードの子にあたるノードに対して、スクリプト側で動的にイベントハンドラを設定したり参照を持ったりしていると
innerHTMLを使用したときに、子ノードに設定したイベントハンドラや持ってる参照が消えてしまいますよ
二行でええやん
>>635 っていうか、少し考えればわかることなんだが。
中身を入れ替えてるわけだから、当然新しいものになるわけで、
古い方に割り当てたイベントハンドラは、新しいものにはついてない。
これは別にinnerHTMLのバグでも問題でも何でもなく常識的な動き。
だから新しくイベントハンドラを割り当てるか、親要素にイベントハンドラを
割り当てるかすればいいだけ。
これはinnerHTMLを使うときは、これを見逃さないでねってだけで
innerHTMLを使っちゃいけない理由でもなんでもないよ。
っていうのは、最初っからみんな言ってる話なんだよ。
使っちゃいけない理由はないって。
>>634 何か問題あんの? html()は内部でinnerHTMLを
使ってるんだからあたりまえだと思うが。
ボックスからスクロールバーのサイズを引いたwidthを取得したいのですが
どうやればいいでしょうか?
639 :
Name_Not_Found:2014/07/22(火) 18:48:00.29 ID:7RqdhX7u
>>628 > documentから消して、さらにJavaScripのどこからも参照がない時。
この点では私とあなたで意見の相違はないと思うのだが…
>>633 バブリングで上位ノード監視の手法は知っているし、後述する予定だったが、参照が切れることに変わりはないはず
ようはイベントがはがれる事だけが問題ではないのだが
帰宅中なので詳細は後程
> 参照が切れることに変わりはないはず
参照が切れる切れるうざくね?
なんでそんなものに執着してるのか。
中身を新しいものに入れ替えてるんだから
別物になっただけだよ。全然難しい話じゃない。
そういう動きになるってだけでそれで問題ないなら、なにも問題ないだろ。
少し盲点になるかもねーってだけの話でしか無い。
古いものを無くしたいのなら(だからinnerHTML使ってるわけで)
むしろ消えてなくなった方がいい場合も多い。
たとえば、<select>要素の<option>をinnerHTMLで入れ替えるのに
ほとんどの場合なんの問題もねーよな?
あんたは、中身を少し書き換えることしか頭にないから参照参照とうざいけど
中身を完全に入れ替えて全く違うものにした時、前のデータが残っているほうが不自然だろ。
へんなやつと絡むから話がこじれるんだよ・・
分からなきゃ分からないでいい、で終わる話
何を言っても納得しないし意味ないよ
これ単なる初心者の質問でしかないから。
すごく丁寧に解説すると
【質問】
element.innerHTML = element.innerHTML.replace(テキスト修正);
って書いたら、element.innerHTMLの中に設定していた
イベントハンドラが動かなくなりました。どうしてですか?
【回答】
element.innerHTML の中身を新しいHTMLに入れ替えたのだから
当然中身は新しくHTML(DOM)になります。
たとえば
element.innerHTML の中に '<a href="hoge">link</a>'; があって
element.innerHTML ='<button>button</button>'; を実行したら
aが消えてなくなるのは当たり前だし、aに設定していたイベントハンドラ
などもなくなるのは当たり前です。
中身をちょっとだけ変えた、element.innerHTML ='<a href="hoge">link2</a>'; を
実行したとき、それを元のaと同じとみなすべきかはわかりません。
よってイベントハンドラを引き継ぐべきかどうかもわかりません。
代入したものは新しいHTMLなのですから、そこに書いているもの以外は初期状態です。
innerHTMLの中身を別物に入れ替えてるんだから
参照は切れるべきでしょ。むしろ残す方がおかしい。
常識を持ち出すならObject型が参照なのは常識
addEventListener 以外にも参照を保持するメソッドが定義されている事は十分に想像できるはずだがな
プリミディブ型のように文字列でゴリゴリ処理する方が不自然だって事が感覚としてわからないなら、その程度の実力って事なんだろうな
>>643 参照を切らなくて済むなら切らないほうが良いに決まってるでしょ
今日になっていきなり当然だろ当然だろ連呼しだしたやつも怪しいもんだな
innerHTMLを使わなければ参照が切れない状況ならinnerHTMLを使わないほうが良い
常識で考えればすぐ分かるはずだがな
むしろ逆に考えて
子ノードを持っているノードについて操作したい場面はどのくらいあるのか?
このとき子ノードに対して何かしているケースはどのくらいの割合か?
たいしたことしてない俺の経験上ではいずれもほとんど無かったがお前らどうよ
>>645 > 参照を切らなくて済むなら切らないほうが良いに決まってるでしょ
中身が別物になってるんだから、同じものを指すべきじゃない。
>>646 いや、やっとこの馬鹿が言ってる「問題」が判明したからだよ。
中身を違うものに入れ替えてるのに、前の情報を保持したい?
そんなアホなことを言ってるとは思わなかったよ。
>>647 > innerHTMLを使わなければ参照が切れない状況ならinnerHTMLを使わないほうが良い
考える順番がおかしい。
最初に考えるべきなのは、中身を新しいものに入れ替えたいのか、
中身は同じで、その属性を変えたいだけなのか。
これを最初に考えるべきでしょうが。
そしてやりたい事にあった命令を使うだけの話。
>>633 "この文章をクリックすると TEXT_NODE 値を置換する。" が大嘘すぎる
tagNameや属性値も置換対象に入ってる
TEXT_NODE のみを置換対象にすべき
>>637 html()はイベントとか切れないように色々工夫してるんだが?
問題点分かって無い奴はレスすんな
だらだら書いてるわりに実質ちょっと言い換えただけのありがたい説明文はいらねーよ
他の質問が流れるからモンスター質問者に関わるのも考え物
>>644 > プリミディブ型のように文字列でゴリゴリ処理する方が不自然だって事が感覚としてわからないなら、その程度の実力って事なんだろうな
これは文字列かどうかの問題じゃない。
innerHTMLに新しい文字列を代入するというのは、新しい文字列から生成したオブジェクトに入れ替えてるのと同じ。
obj = new Object;
obj.prop = 1;
obj = new Object;
console.log(obj.prop); // 1と表示されないじゃないか!
って言ってるのと同じ。
innerHTMLを新しいオブジェクトに入れ替えたのだから、その子オブジェクトも入れ替わる。
document.createElementを使った方法であっても、新しく作った要素に入れ替えたのなら、
古い要素のイベントハンドラは消える。
あと、HTMLを扱うときは、文字列で扱ったほうが速い。なぜなら単なる文字列は
メモリ内で終わる作業だから、重いDOMツリーの更新は必要ないし、
ブラウザの機能としてHTMLのパースは、もっともよく使う部分で、一番最適化されているから。
そういうこともわからない程度の実力かい?
>>653 innerHTMLは、中身を入れ替える命令。
中身を入れ替えたくないのなら、innerHTMLを使うのが馬鹿だし、
中身を入れ替えたいなら、innerHTMLを使うのが良い。
そんな使い分けもできないの?
君は、最初にやりたい事をはっきりさせてから、
プログラムしようね。目的に合わない命令を使って
わーわー騒ぐんじゃない。
>>652 > html()はイベントとか切れないように色々工夫してるんだが?
してません。
>>658 それは俺も思った
工夫しているのは .on() だよな
スレが質問こなさそうな状況だからいうが
質問と真っ当な回答を抜き出して検索性インデックス性をなんとか作り出してナレッジベース化したら役に立つだろうか
>>656 > あと、HTMLを扱うときは、文字列で扱ったほうが速い。なぜなら単なる文字列は
> メモリ内で終わる作業だから、重いDOMツリーの更新は必要ないし、
> ブラウザの機能としてHTMLのパースは、もっともよく使う部分で、一番最適化されているから。
そうなんだよね。俺も十数年ぐらい前は、たとえばテーブルを作るのに、
tableをcreateElementして、trをcreateElementして、tdをcreateElementして
appendChildを繰り返して・・・ってDOM操作で何行もかけて作っていた
時もあったけど、今は遅いし面倒なだけなので文字列で生成している。
innerHTML = '<table><tr><th>header</th><td>data</td></tr></table>';
これをDOM操作で作っても重いし面倒なだけ。何一つメリットがない。
さらに言えば、文字列の連結も一が多くなると見難くなるから、
少し複雑なのはlodashのtemplate機能を使ってるよ。
html()がやってるのは、中身を入れ替えた時に消える古いオブジェクトに対して
ブラウザの不具合によるメモリリークな問題に対応する処理で、
イベントハンドラは普通に切れる。
>>657 > 中身を入れ替えたくないのなら、innerHTMLを使うのが馬鹿だし、
>>649で「中身が別物になってるんだから、同じものを指すべきじゃない。」と発言しているのはなぜ?
別物にする必要がないでしょ?
665 :
Name_Not_Found:2014/07/22(火) 21:01:54.70 ID:9sE25qaT
>>664 まあ大抵はIDに対してイベントハンドラ付加したりしてるから、直感的にはそう思っても仕方ない
けどイベントハンドラの設定も参照の作成もIDが必須になっているわけではない
なので内部構造としてノード・ツリー構造があるわけで、IDは表面上の操作と内部の位置とを橋渡ししているに過ぎない
こういう状況の中で、.innerHTMLで要素の中身を入れ替えたり操作したりするとき、
入れ替える前と後で、中身が持っている子要素が同じであるかどうかを保証するわけにはいかない
だからイベントハンドラは消失するし参照も切れる、それが当然の動作になってしまう
(付加したイベントハンドラは理論上すぐ消えるはずだけど、個人的になぜかそうとは限らないように思う)
…と、自分はこういうふうに理解してるけど、間違いあるかな
>>664 > 別物にする必要がないでしょ?
なんで決め付けるの?
別物にしたいときは、別物。そうでない時は、そうでない。
別物にしたいときは、イベントが残っていたら大問題。
html()、innerHTMLを使うかどうかは、
どっちが目的かで変わるわけで、
なんで最初の目的を限定してから使えないって話するの?
意味がわからない。
>>655 > jQuery の .html() を使用すると参照が切れて、jQuery.data() が期待通りに動作しなくなる
だからさ、それは「問題」じゃないんだって、
html()の仕様として、要素を丸ごと入れ替えるものだから
data()は消えるのが仕様として正しい。
なんで、目的にあってないものを使ってるくせに
それが問題だっていうのさ。馬鹿じゃん?
669 :
665:2014/07/22(火) 21:08:01.79 ID:9sE25qaT
670 :
665:2014/07/22(火) 21:10:49.61 ID:9sE25qaT
>>668 > なんで、目的にあってないものを使ってるくせにそれが問題だっていうのさ。
>>633が問題ないと主張するから反論しているだけなのだが…
文句は
>>633にいってくれ
innerHTMLは要素オブジェクトをまるごと入れ替えるという
仕様なのだから、その要素に結びついたデータは消えるのが正しい動き。
それは正しいまともな仕様なので、バグではない。
>>670 >>633は問題ないでしょ?
あんた、dataも一緒でなければならないという
条件を最初に提示したかい?
innerHTMLやjQueryのhtml()もそれ自体に問題があるわけではなく、
要素を入れ替えるという仕様なんだからそれに付随するデータも消える。
この仕様で問題があるかどうかは要件によって変わるので、
一概に問題があると決め付けることは出来ない。
いい加減に理解しようぜ。
$obj.innerHTML += 'test';
とかしたとき、イベントハンドラが失効したり参照が切れたりするのは
JavaScriptのコード打っていると面倒に思うことがあるのは確かだろうけど
仕様作る側やブラウザの実装やる側に立って考えると
これを失効しないように参照が切れないように作るのってすごく大変そう
> 参照が切れる切れるうざくね?
> なんでそんなものに執着してるのか。
これが発端だろ
参照が切れる問題点が全く分かっていない奴に説明してるだけだろ
>>674 大変じゃなくて不可能
innerHTMLはHTMLを代入する命令なのだから
HTMLとして表現できるもの以外には対応できない。
そういう仕様。
>>671 バグとは誰も言ってない
仕様なのは皆分かってる
>>675 だから参照が切れるのは問題点じゃないんだって言ってるだろ。
第一、参照が切れてるんじゃない。
全く別のオブジェクトに入れ替えてるんだから、
そもそも参照が最初っから存在しないんだよ。
>>677 ”正しい”仕様な。
どうも正しい仕様なのに、
それが問題であるかのように
言ってる奴がいる。
> 全く別のオブジェクトに入れ替えてるんだから、
> そもそも参照が最初っから存在しないんだよ。
これは酷い
innerHTMLは、新しいHTMLオブジェクトに入れ替えたい時に
使うもので、新しいHTMLオブジェクトに入れ替えるのだから
イベントハンドラもdataも初期化された状態になってほしいね。
>>680 ?
ひどくないんだが?
element.innerHTML に代入するということは、
新しい要素オブジェクトをcreateElementして、
elementの子供を新しい要素に入れ替えることと
全く同じだよ。
擬似命令で書くなれば
element.innerHTMLObject = document.createElement('a');
みたいなもの。
document.createElement('a')した結果に
イベントハンドラがついているかい?
最初っからついてないだろ。
innerHTMLが内部で、文字列から新しい要素オブジェクト郡を作成して
それに入れ替えてるだけってのが、わかってない。
>>679 正しさの判断基準はどこにあるんだよ
逆に「間違った仕様」があるのか?
'a' が顔文字にみえる
>>684 正しい仕様っていうのは、
innerHTMLを取得した時にそれはHTML表現を取得するものであって
DOM要素をシリアライズしたものではないということ
つまりHTMLで表現でされているものだけが取得され
HTMLでない情報は存在しない。
だって、その名の通り inner "HTML" なのだから。
そこにHTMLで定義してない情報まで
シリアライズされるべきだと思ってるのが「間違った仕様」
>>638 Element.clientWidth,
Element.clientHeight
かな
それは正しい仕様ではなくただの「仕様」、間違った仕様ではなく「間違った認識」である
>>683 長文書いてるところすまんけど
> そもそも参照が最初っから存在しないんだよ。
こんなこと書いてるから「お前参照とか使ったことないだろ」って突っ込まれたんじゃないのかい
参照を作る→参照先が消滅(&別の新しい要素が生まれる)→作った参照が失われる
この流れを話してるのに「参照が最初っから存在しない」は無いわ、と
意地になってるだけの奴に何言っても無駄だろ
GCの原理が理解出来てないんだろうなあ
text-overflow: ellipsis;
で省略されているかされていないかを判定するにはどうしたらいいでしょうか?
出来ないなら、自前で同じことをするしかないと思いますが・・
>>689 innerHTMLに代入する値はただの文字列で、
代入した後に内部で処理されるまで
オブジェクトの参照は存在しませんが?
元々の参照とは全くの別なんだ?
それをわかっていて代入してるんだが?
innderHTMLに代入するということは
別のオブジェクトを作ろうとしてるんだよ。
イベントハンドラとかdataとかリセットされるべきじゃないか。
ほんと何言っても無駄だな
>>692 > 出来ないなら、自前で同じことをするしかない
なんで?
696 :
Name_Not_Found:2014/07/22(火) 22:18:47.08 ID:9sE25qaT
>>616 遅くなってすまなかった
> 問題点を理解して使っていくうえで賢いやり方とかあるかな?
最も確実なのは「全てのノードを置換しなければ実現できない状況でのみ innerHTML を使う」になる
http://jsfiddle.net/Pc87X/1/ や
http://jsfiddle.net/Pc87X/7/ のようにノードを置換しなくて良いケースでは innerHTML は使わない、ということだ
これなら innerHTML を使わなくても全てのノードを置換しなければいけないのだから問題はない
addEventListener の参照エラーのみに対応するならバブルするイベントは document で定義し、バブルしないイベントは useCapture を利用して document で定義すれば回避できる
ちなみに、jQueryでは useCaptuer を使えないのでバブルしないイベントには対応できない
また、
http://jsfiddle.net/Pc87X/9/ のように jQuery.data() に対応できない等、完全な対策にはなっていない
---
ただし、「innerHTML が楽だ」という人は大抵、「ノードを置換しなくて良いケース」や「部分的な置換でよいケース」でもらくだからという理由で全体を置換しようとすることが多い
正直、お勧めはしないが、その場合は下記対策が考えられる
1. チームで参照を保持しているノード情報を共有する
2. 参照が切れてはいけないノードでinnerHTMLを使用した際に例外を投げる仕組みを作る(問題の早期発見)
1. はまあ、当然だな
2. は例えば、下記URLのようにする
http://jsfiddle.net/Pc87X/10/ 欠点としては要素ノードの参照にしか対応できていない事か
また、addEventListener のように参照を保持するタイプのメソッドは全てユーザ定義関数でwrapする必要があるので少し手間はかかる
---
ところで、jQuery.data() のように全DOMノードにオブジェクトを格納できる DOM 仕様があって廃案になったと記憶しているのだが、該当仕様をどうしても思い出せない
どなたかご存知の方がいたら教えて頂けないだろうか?
廃案後、代替仕様が出来たかも気になっている
全ノードに js-refered フラグを付けられれば、
http://jsfiddle.net/Pc87X/10/ でテキストノードの参照エラーにも対応できるのだが…
そもそも「省略されているかされていないかを判定する」必要性がわからん
勝手に分からなけりゃいいだろ
馬鹿じゃねえの
700 :
696:2014/07/22(火) 22:48:40.48 ID:9sE25qaT
701 :
Name_Not_Found:2014/07/22(火) 22:59:10.78 ID:9sE25qaT
>>696 ありがとう、むしろ手間をかけさせて申し訳ない
> 全ノードに js-refered フラグを付けられれば
まさにこういう類のことを考えてたんだけど
やっぱり地道な対応しかないか…
>>701 なるほどrangeですか・・
たしかになんとかなるかもしれません
ありがとうございました
まだやってんの? いま来た人用にわかりやすい例え思いついたわw
innerHTMLには根本的な問題がある
代入演算子=には根本的な問題がある
innerHTMLに代入したら古い値が消えることだ
代入演算子=で代入したら古い値が消えることだ
前の値を残しておきたいときはDOM操作をしなければならない
前の値を残しておきたいときは足し算をしなければいけない
だからinnerHTMLを使ってはならない
だから代入演算子を使ってはならない
★普通の人が考えること
前の値が要らない時はinnerHTMLでいいんじゃねーの?
前の値が要らない時は代入演算子でいいんじゃねーの?
そもそも前の値を捨てて新しい値を入れる時にinnerHTMLを使うんじゃねーの?
そもそも前の値を捨てて新しい値を入れる時に代入演算子を使うんじゃねーの?
>>696 > ただし、「innerHTML が楽だ」という人は大抵、「ノードを置換しなくて良いケース」や
> 「部分的な置換でよいケース」でもらくだからという理由で全体を置換しようとすることが多い
その前提がおかしいんだろ。
なんで置換ありきなんだ?
innerHTMLを使う時に一番多いのは、文字列で新しくHTMLを
生成するときだろ。置換なんかしねぇよ。
706 :
sage:2014/07/22(火) 23:28:21.56 ID:???
タブレットでスクロール可能なエリアでスワイプすると、横スクロールするだけでスワイプの動作が取得できません。
どのようなコードを記載すべきでしょうか。下記のようなコードを記載しました。
<html>
<head>
<title>My Page</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="
http://code.jquery.com/mobile/1.1.0/jquery.mobile-1.1.0.min.css" />
<script type="text/javascript" src="
http://code.jquery.com/jquery-1.7.1.min.js"></script>
<script type="text/javascript" src="
http://code.jquery.com/mobile/1.1.0/jquery.mobile-1.1.0.min.js"></script>
<script type="text/javascript">
$(function(){
$('#scrollswipe').bind('swipe', function(){
alert("swipe");
});
});
</script>
</head>
<body>
<div id="scrollswipe" style="width:200px; height:200px; overflow:scroll;">
<h1>aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa</h1>
<h1>bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</h1>
<h1>cccccccccccccccccccccccccccccccccccccccccccc</h1>
<h1>aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa</h1>
<h1>bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</h1>
</div>
</body>
</html>
ってjQuery Mobile使ってるのかw
すまんすまん。
709 :
696:2014/07/22(火) 23:50:55.84 ID:9sE25qaT
>>630 これは innerHTML の最も酷いパターンだな
$('body').html(str); には驚いた
>>633も使わなくていい場面でinnerHTMLを使ってるので五十歩百歩
ノードを置換しなくてもいいのにinnerHTMLを使ってる時点で使い方がなってない
innerHTML使って無いジャン
1 delete objA;
2 new objB;
結局、innerHTMLは、古いオブジェクトを削除して、
新しいオブジェクトを作っただけかね?
xmlHttpRequestでphpを指定した時そのphpはどこで実行されるんですか?
サーバー側かクライアント側にphpごと来るのか
>>712 .html() は内部的に innerHTML を利用しているから innerHTML を使用しているのと同義
>>714 サーバに決まってるじゃん
phpってのはサーバで実行されてHTMLやXMLを出力するもので
サーバの外に出てくることはない
>>692 この件ですが、コンテナdivのscrollWidthには省略される前の数値が入るので
これで判定できると分かりました
ありがとうございました
>>717 シリアライズが何を言っているのかわからないが、
innerHTMLはDOMオブジェクトをシリアライズするのではない。
HTML要素とDOMオブジェクトの違いがわかってない人が多いんだよな。
これ理解するのに、jQueryのdata()メソッドの挙動を勉強するのがいい。
たとえばこんなHTMLがあるとする。
<span id="id" data-value="123">test</span>
これを $('#id').data('value') で参照すると123が返ってくる。
そのあと $('#id').data('value', 456) を実行し、参照したら456が返ってくる。
当たり前の動作に見えるが、ここで$('#id').attr('data-value')を参照すると、返ってくるのは123。
つまり、dataはDOMオブジェクトの値をかえるが、HTML要素は書き換えないということ。
DOMオブジェクトの状態とHTMLは全くの別もの。DOMオブジェクトをシリアライズしたものがHTMLなのではない。
HTML要素を書き換えるとDOMオブジェクトに反映されるが、DOMオブジェクトを書き換えても
HTML要素には反映されない。それがDOMオブジェクトに割り当てるイベントハンドラなど。
jQueryのattr()メソッド(DOMでいえばsetAttribute)は "HTML要素を書き換える" メソッド
on(DOMで言えばaddEventListener)はDOMオブジェクトにイベントハンドラを設定するメソッド
それぞれのメソッドで、影響をあたえるものが、HTML要素だったり、DOMオブジェクトだったりする。
innerHTMLが行うのは、HTML要素の取得と設定で、DOMオブジェクト操作用ではない。
>>720 JQueryのdataはDOMと関係無く値を収納してるんだが?
お前が一番違い分かって無いだろ…何長々と馬鹿な事言ってるんだ
そもそも例えに何の前提もなく$(id)を使うのは
>>721 えらいえらい。よく気づいたね。
じゃあ、DOMの話だけでするならば、
フォームのvalueが全く同じ挙動をする。
ページが表示されてからinputの内容を入力した時、
valueプロパティ、つまりDOMオブジェクトの値は最新の値だが、
value属性はページが表示された時のまま。
DOMオブジェクトの内容と、属性は関係してそうで関係していない。
jQueryのdataはこの動作を参考にして作られていると考えれば良い。
実装依存は困るよな…
っていうかHTMLもCSSもJavaScriptも全ブラウザ全部仕様通り全部動作完全に一緒だったらと思うと
>>724 それはネットスケープが悪いんだよ。JavaScriptを初めて搭載したブラウザ。
標準化しないで勝手に言語を作った。
まずいきなり実装しないで、標準団体を設立して標準化するべきだった。
>>725 今更何を…
むしろマイクロソフトに言うべきだろ
msは話しにならん