+ JavaScript の質問用スレッド vol.135 +
■ このスレッドは過去ログ倉庫に格納されています
JavaScript を自ら学ぶ人のための質問スレッドです。
次スレは>>950が(本スレで改善案があれば考慮して)立ててください
■規則/推奨ルール
・メール欄を空欄にし、名前にレス番を入れることを強く推奨(なりすまし防止)
・質問内容は具体的に。言葉だけでなく、出来る限り再現性を確認したサンプルコードの掲示。
・質問テンプレートの利用推奨。
・質問への「答え」だけでなく「意見」を出しても良い。
■禁止行為
・丸投げ質問
・迷惑スクリプトの質問
・オレオレ用語の使用(一般的な用語を使用する事)
・煽り、批判等の他人を不快にさせる行為(批判の代わりに「AよりBが良い」のような代案を出す事)
■質問テンプレート
【環境】OS, ブラウザをバージョンと共に記入してください。
【条件】期待する回答の条件を書いてください。
【何をしたのか】何をしたら問題の現象が発生するのか。再現手順を具体的に書いてください。
【エラーメッセージ】エラーメッセージがあれば正確に書き写してください。
【期待する結果】最終的にどういう結果を望んでいるのか、を書いてください。
【サンプルコード】現象を再現可能な最小限のコードを書いてください。
1レスに収まらないならコード投稿サイトを利用してください。
http://jsdo.it/ http://jsbin.com/ http://jsfiddle.net/ http://ideone.com/
■回答者へ
・回答には多様性があります。他人の回答を尊重してください
・動作ブラウザや環境が限られる場合は、それを明記してください
・他人の回答を批判する代わりに、自分ならこう書くという例を示してください
・質問者がJavaScriptでなければ実現できないと勘違いしてるなら、その否定としてHTMLとCSSで実装しても良い
・他人の回答を見たくないのであれば、文句をつける代わりにNGにして見えないようにしてください。文句をつける=荒らしです 下のコードでaddEventListenerが実行されないのが良く分かりません。
window.onload = function () {
window.addEventListener('load', function () {
・・・ // 実行されなかった
});
};
なぜですか?
なお
window.onload = function () {
ではなく、
jQuery(function ($) {
でも実行されませんでした。そう言う仕様ですか? >>330
ロードイベントが起こった後にロードイベントを監視しても、もう起こった後だから起こらない。 >>330
そりゃ二重にロードイベントに紐付けしたら起動するわけが無い
どっちかだけにしろ Life is a series of choices.(人生とは選択の連続である)- William Shakespeare(ウィリアム・シェイクスピア) >>330
おかしいな? jQueryの場合は動くはずだけど?
jQueryのloadはPromise的な処理になっていて
あとからつけても発動するように考慮されてある
jQueryの古いバージョンは違ったかな?って思って1.9.1にしたけど動く
それよりも古いバージョンはしらないけど
https://jsfiddle.net/6q4whbty/ あ、逆か。
外側をjQueryにして、中をDOM APIにするわけね。
そりゃDOM APIじゃむりだ。中もjQueryにしなきゃ
ってか、外側でjQuery使っていてjQueryでやれることを
DOM APIを使ってやる必要ないでしょw 必要かどうかは私が決めることです
分からないのなら解答しなくていいので黙っててください >jQueryのloadはPromise的な処理になっていて
>あとからつけても発動する
どういう経緯でこうなってるんですか
pure-js側はそんなことないですよね
デバッグの妨げになるようにも思えるんですけど どういう経緯って言われても、何度も発生するイベントと
resolve(またはreject)状態になってから変わらないものは
そもそも性質が異なるからですよ。
Promiseもいまやpure-jsですが、昔はそんなものがなかったからイベントで代用していましたが、
他のイベントと違い発生したタイミングが重要なのではなくロードは発生したタイミングが知りたいというより、
「現在ロードされているか?されていなければされるまで待つ」という処理を行うのが普通なので
現在の状態を判断するという処理が必要になります。
結構複雑ですよ?まずjQueryのloadはブラウザのloadイベントではなく
それよりも早い段階で発生する、DOM構築が完了した直後の
DOMContentLoadedを捉えるものだというのは知っていますか?
DOMContentLoadedはHTML5で標準化されましたが、それまでは非標準で
https://qiita.com/mamosan/items/ff336b5cc0a1a95e03a7
Firefox 2 (2006年)、Safari 3.1(2008年)、Chrome 4(2010年)、IE 9(2011年)で
予約サポートされたものです。jQueryは2006年なので普及しておらず当時は
使えない人が大半だったってのがわかりますね?
jQueryのloadはこのDOMContentLoadedをシミュレートする形で実装されました。
詳細は省きますがドキュメントのとあるプロパティをsetTimeoutで監視して読み取れれば
イベント発生扱いとしています。この部分のコードだけでも面倒なのですが、今は
DOMContentLoadedが使えるし、シミュレートが完璧に動作すると信じて
DOMContentLoadedの話にすすみましょう。
DOMContentLoadedが発生するのはDOM構築が完了した直後です。ここで問題になるのは
パフォーマンスアップのために使われる非同期で実行されるJavaScriptの存在です。
同期的に実行されるJavaScriptはDOM構築完了前に実行されますが、非同期で実行される場合
DOM構築完了後に実行されます。つまりDOMContentLoadedが発生した後に
DOMContentLoadedを監視することになるわけです。つまりイベントはすでに発生しているので
捉えることはできません。>>330と似たような状況になりますね。 ではどうするのかというと、イベントを監視する前にすでにDOMContentLoadedが発生したかを
document.readyStateを使ってチェックするわけです。
ですが単純には行かず、document.readyStateを使ってチェックしてまだloading中であれば、
addEventListenerでDOMContentLoadedを監視すると書いてしまうと、チェックした段階では
loadingだったが、addEventListenerするまでに間にDOMContentLoadedが発生してしまって
イベントが捉えられない可能性があります。
なので逆に実装し、addEventListenerでDOMContentLoadedを捉えるようにしてから、
document.readyStateを監視して、すでにreadyStatusがinteractiveにだったら
ずっと前にDOMContentLoadedが発生していたと判断するわけですが、
実はaddEventListenerを設定した直後にDOMContentLoadedが発生した可能性があるため
この場合は2回イベントが発生する可能性があります。それを避けるために状態管理で
1回しか発動しないようにするわけです。
これらの動きはDOM読み込みとJavaScriptの実行タイミングによるものなので
毎回発生するものではなく、まちまちで見つけづらいバグとなってしまいます。
ローカルでは問題ないのにサーバーにアップした発生する。
でも2回目以降はキャッシュが効いて速いので発生しないとかですね。
このように完璧に対応するのは複雑なのです。DOMの非同期読み込みをやめれば
解決するのですがパフォーマンスアップのためにブラウザに搭載された機能を
使うなというのは、ライブラリとしてありえませんね。
他のイベントでは必要ないのにloadに関してこれらが必要になるのは
DOM構築が完了したあとに何度も発生するイベントと、そもそもDOM構築完了を監視する
DOMContentLoadでは性質が異なるからなのです。
そして実際のユースケースを考えたら「ロード済みかロード完了時にイベント発生」して
欲しいため、APIもそのようになっているのが望ましいわけです。
開発者が上で書いたようなな複雑な処理を書くことなく、単純なAPIで判断できるため
それが原因で起きるマイナーなバグから逃れることができます。 >パフォーマンスアップのために使われる非同期で実行されるJavaScriptの存在です。
>同期的に実行されるJavaScriptはDOM構築完了前に実行されますが、非同期で実行される場合
>DOM構築完了後に実行されます。つまりDOMContentLoadedが発生した後に
>DOMContentLoadedを監視することになるわけです。つまりイベントはすでに発生しているので
>捉えることはできません。
これどゆこと
ブラウザにおけるjavascriptの実行ってのは
今も昔も非同期な関数(呼び出し)があるだけで、原則は全部同期実行なんじゃないのけ
setTimeoutやXHRのcallbackの中でwindow.addEventListener('load', ... )なんてしないし 「なんでonloadではなくDOMContentLoadedなのか」は?
つか化石IE対応のための負の遺産的挙動じゃないん >>344
scriptタグのasync属性のことだよ。
HTMLの読み込みとJavaScriptの実行が非同期で行われる。
つまりaddEventListenerでDOMContentLoadedを監視する前に
HTMLの読み込みが完了してしまうことがある
参考 https://iwb.jp/domcontentloaded-javascript-async-forbidden/ >>345
IEは9の時代からDOMContentLoadedに対応してる。
対応してないブラウザのためというのなら、別にIEだけじゃなくて
その他のブラウザも非標準のDOMContentLoadedには対応していなかった
DOMContentLoadedが標準化されたのはHTML5になってからだ。 それはわざと。レスする気なくするでしょ?それが狙い
不正にjQueryを貶めようとする奴らに反論する気をなさせる asyncは「DOM構築完了後に実行」される、ではなく
「DOM構築完了後に終了する場合がある」というべきでは
つかasyncしてもwindow.onload使えばいい話じゃないのか この件は良く知らんのだけど
・>>337いわく1.9.1の時点からそういう挙動
・scriptのasyncはHTML5から
・jq 1.9.1リリース 2013年02月04日
・HTML5勧告 2014年10月28日
順番おかしくね >>351
jQのpromise的動作とjsタグのasync的動作はまったく別物 >>352
>>346
JQueryの良く分からん挙動がscriptのasyncと関係ないということになると
>>342-343の大長編レスの前提が崩れるんじゃないか? >>351
> ・>>337いわく1.9.1の時点からそういう挙動
どこにも1.9.1の時点からなんて書いてない。
少なくとも1.9.1ではそういう挙動だったってだけ。
おそらく最初からそうだろう >>352
何を持って別物と言ってるのかは知らないが、
PromiseオブジェクトにはPromise.resolve()とPromise.reject()という
メソッドがあって、それぞれ解決済み、リジェクト済みのオブジェクトを返す。
このオブジェクトにあとからthenメソッドでコールバック関数を
くっつけてもちゃんとコールバックが呼ばれるんだよ。 > jQのpromise的動作とjsタグのasync的動作はまったく別物
jsタグってなに?HTMLタグっていいたいの?
HTMLタグのasyncはJavaScriptの実行を遅らせることで
見た目上のパフォーマンスを上げる技術で
その弊害として、DOMContentLoadedが先に呼ばれてしまうから
JavaScriptの発動が起きないってものなんだけど
jQueryはそのことも考慮されてるから、普通に書くだけで
非同期でJavaScriptが読み込まれても大丈夫って話をしてるんだよ
Promise的動作っていうのは、コールバックを後から追加しても
発動するって話。あんた全く別物の話をしてるよ >asyncはJavaScriptの実行を遅らせることで
遅らせてるのか?
htmlの解析処理と当該jsファイルのダウンロード・実行処理とを
切り離して並行処理させることで、htmlのパース・文章や画像の配置等が妨げられないようにしているだけでは?
DOMContentLoadedより後に処理が開始されるのではなく
DOMContentLoadedの前に終わるとは限らないというだけの話では? > DOMContentLoadedより後に処理が開始されるのではなく
> DOMContentLoadedの前に終わるとは限らないというだけの話では?
今はそういう細かい話はどうでも良くて、
需要なのはscriptタグのasyncを使われてると、DOMContentLoadedが
先に発生してしまうことがあるってことですよ
他にもRequireJSのような非同期でJavaScriptモジュールを読み込む仕組みを
使ったときにも発生しましたね。 たとえ細かい話でも虚偽が含まれてる人の話は信用できないからなあ はは、信用出来ないっていうだけで、間違ってるとは言えない
あわれよのうw まあ間違ってるわけじゃないからね。信用出来ないってだけ >>354>>357>>358
ごめん訂正するね
言葉足らずだった
「別物」ではなく「実装箇所が別物」
動作としては似たようなものだ
一番最初の気持ちとしてただ>>351の言ってることが的外れだったので意図としてはそれを訂正したかった window.addEventListener('load', ... )ではどうしてもダメなケースを聞きたい
>>330のような無能サンプルコードは除外するものとする >>367
ページ内にある画像全てが読み込まれないと
JavaScriptが動かないのでダメ >>368
操作性悪くなって遅くても動くからダメじゃないんですって主張は禁止なw
その理屈だと電気がなくても生きていけるって回答になる。 asyncで読ませたい
どうしても早いタイミングDOMContentLoadedで動かしたい
asyncするとDOMContentLoadedに間に合わないリスクが怖い・・・
jQueryなら専用のコード書かなくてもすぐに実現!! ←今ココ
ざっくり書くとこんな感じかね?
DOM APIでもできないわけではないし
jQueryならといっても最初からそれを狙った実装ではないようだが
現実として便利に転用できますよ、という具合 >>370
どっちにしてもwindow.onloadだとロードイベントに一個しか関数を紐付けできないから不便極まるんだよなぁ
一個だけしか使わないってんなら関係ないけどさぁ… >>374
たまにはaddEventListenerのことも思い出してあげてください そんなことよりお前らremoveEventListenerとか使ったことある?
使う機会がまったくないよなアレ >>377
そもそも今この瞬間までそいつの存在すら知らなかったぞ >>377
使ったことはないが
disableにできない類のもののイベントリスナを切りたいとか
起動する関数を切り替えたいとか
使える機会はいろいろ思いつくぞ
呼び出される関数側でチェックして即returnとかの別手段でだいたい十分だけど >>379
> 呼び出される関数側でチェックして即returnとかの別手段でだいたい十分だけど
そういうのはクラス名で制御すべきだよ。
例えばこんな感じにしてると、spanのクラスが
それぞれmode1 or mode2 の場合のみ、該当のものだけ発動してくれる
$('span.mode1').click(function() { alert('click1'); })
$('span.mode2').click(function() { alert('click2'); }) >>377
普通に使うけどなあ
来れなかったら、addしたイベントをどうやって剥がしたら良いのかわからん addしたイベントを剥がす機会がないということでは? 要素が増減するならばデリゲート使って親要素でイベントを捉えれば良いし
その方が効率なわけで、わざわざイベントハンドラを外すことはないね >>383
なるほどー
>>384
増減しない時は? >>386
つけっぱなしで良いこともあるし外さにゃならんこともあるな
この辺は経験というか、やったことあるかどうかの差だからしゃーないわな だからその外さなきゃならない場合ってのが無いんだっていう話をしてるんだが
経験があるというのなら、その経験を語れよ webページ作るのに外さないといけないユースケースは確かにめったに無さそうだ。
実はコンソールで色々いじくって実験する用なんじゃないのか。console.logみたいに 使った経験は無いが、想像するに一つのボタンに複数の機能を持たせるときには使えそう >>390
>>380を見てね
ロジックで処理を分けるのは古いやり方だよ。今は状態ごとの処理を定義する。
こうすることがバグも減らせるんだよ。ちゃんと外せたか?二重に登録してないか?
なんて考える必要がない。
こういうものこそ経験っていうんだけどな >>391
ますますremoveEventListenerの使い道ないじゃないか…(憤慨) >>388
色々あるけどなあ
フレームワークっぽいもの作ってたときとかよく使ったよ 一個のサイト作る場合ではなく
複数のサイトで汎用的に使うコンポーネントなんかを作るケースだと
CSSまで自由に出来なくてJSでやらにゃならんこともあって
そんな時には必要になるなあ
みんなも自分のサイトに組み込んでるフレームワークやライブラリのコードをのぞいてみると
案外使われてるのに遭遇すると思うよ いちいち重複イベントチェックなんて面倒だ
まとめてごっそり総入れ替えだ リフレクションAPIやプロキシーAPIと同じでフレームワークとか作る人用か。使うだけの人には洋ナシ体型 phpよりjavascriptを勉強すべき、という理由を教えてください 私は頭が悪いので分かりやすく頼みます PHPを作ってるところは一つ
JavaScriptはMS、Google、Apple、Mozillaと大企業が力を注いている javascriptも、もはやc++やその他言語を呼び出すだけのものになりつつある >>402
なるほど、ありがとうございます
本当に死ぬ気で毎日勉強した場合、
理解できるようになるまでどれくらい掛かりますか C++はもはやJavaScriptから呼び出すライブラリに成り下がったんだな 呼び出されることすらできなかった状態から成り上がったんやぞ。 (javascriptの実行速度が遅すぎて使えないからこういう方法が生まれたんだけど…)ボソッ でファミコンエミュレータwasmにしてみたらjsより遅かったんでしょワロスwwwww >>410
ブラウザ /JS版 /Wasm版
Chrome 63/4.36ms/5.68ms
Firefox 58/5.76ms/3.98ms
Safari 11/9.98ms/4.21ms
これ?要はchromeの実装がクソ雑魚だったってだけでしょ
firefoxとsafariはjs版を大きく超えてる >>411
え?たったそんだけしか違わないの?msって
人間が知覚できるレベルじゃないじゃん なんでchromeで遅くなってるの?
chrome、前はjsの最適化で最速とか言ってたけど
sandboxとかセキュリティ絡み? >>411
ご覧くださいwww「javascriptの実行速度が 遅 す ぎ て 使 え な い」とまでイキッておいてコレwwwww cとphpやpyの差みたいに10倍かそれ以上速くなるもんだとばっかり思ってた
カスだな コンパイルの手間かけてまでこの程度かよw
時間は有効に使えよ?みんなお前に付き合うほどヒマじゃねーんだw これでセキュリティに穴が見つかろうものならまるで利用価値なしのゴミ屑扱いになってしまう エロゲー廃人速報改
http://erogehaijin.com/
・生活保護の不正受給カミングアウトして自慢
・DMMからステマ脅迫工作で雇われる
・アフィで稼ぎまくり
・DLsiteはじめ各流通やメーカーへの脅迫
・ステマ工作で金貰ってるのは言うに及ばず
・風俗通い・焼肉ざんまい
エロゲー廃人速報改
http://erogehaijin.com/
∧_∧
ピュー ( ^^ ) <これからもエロゲー廃人速報改(ナマポ不正受給)を応援して下さいね(^^)v
=〔~∪ ̄ ̄〕
= ◎――◎ 👀
Rock54: Caution(BBR-MD5:1341adc37120578f18dba9451e6c8c3b) >>405
どういうところに行きたいかによるから何とも…試しにこういうのでもやってみれば?
https://prog-8.com/languages/es6 wasm使うならもはやjs発である必要性ないと思うんだが
js使いたいだけっていう
違うコンパイル言語開発しろって >>402-405
プログラマーが、クソ言語のPHP を使う理由がない
Ruby on Rails などのフレームワークを使うけど、
画面は、Vue.js など、JavaScript(JS) になるので必須
初心者は、Ruby, JS を数年やればよい。
それ以外の言語は難しいから、数年後に始める wasm, wasmってまあ良く聞くけど
・wasmの性能って「元の言語/コードの効率性」と「wasm形式にしてくれるコンパイラの(最適化)性能」と
「ブラウザの方のwasm動作環境の性能」の全部に左右されんだよね?
・「wasmはロード時間短縮にはなるけど動作速度は変わらない」って主張が今でもいくらか見られるけど
jsで動かしてたものをc-wasmに変えれば動作速度は劇的に改善される可能性もまあ普通にあるよね?
・jsと違って低次元なメモリ管理できちゃうけど、
wasmが個々のwasmに割り当てられたメモリ領域以外を読み書きできちゃって
セキュリティ的に大問題になる、ってことは生じ得ないの?
activexで脆弱性突いてウィルス散布、みたいな現象はノーサンキューなんだけど そもそもwasmっていうのは既存のサイト速くするものではないからな
既存のサイトは、サーバー側でバッチ処理をさせるという設計
クライアントでやることが少ないから、いくらwasmでクライアントが
速くなったとしても効果は殆ど無い。
ぶっちゃけるとwsamの主な用途はゲームだよ
ゲームは反応速度が重要なのでバッチ処理でさせると成り立たない
あとはせいぜいグラフィックソフトぐらいだろう ユーザに気付かれないようにクライアントに高処理効率でマイニングさせるとかな ■ このスレッドは過去ログ倉庫に格納されています