jQuery 質問スレッド vol.8
レス数が900を超えています。1000を超えると表示できなくなるよ。
JavaScriptでDOM用ライブラリであるjQueryのスレです。
次スレは>>950が>>2のテンプレ案(本スレで改善案があれば考慮)を元に立ててください
このスレはjQueryやjQuery UIの使い方やjQueryプラグインの作り方を質問するスレです。
jQueryを使って作る側のスレであって、こんなプラグインありませんか?と聞くスレではありません。
そういうのは自分で探してください。
ろくにサポートもされてなさそうな野良プラグインの使用はおすすめしません。
JavaScriptの質問は関連スレで質問して下さい。
■前スレ
jQuery 質問スレッド vol.7
https://mevius.5ch.net/test/read.cgi/hp/1478055094/
■関連スレ
JavaScript の質問用スレッド vol.130
https://mevius.5ch.net/test/read.cgi/hp/1501503056/
ECMAScript デス 6
https://mevius.5ch.net/test/read.cgi/tech/1483332914/
JavaScript ライブラリ総合質問所 vol.5
https://echo.5ch.net/test/read.cgi/hp/1465399470/ >同じjQueryオブジェクトを使う時には
とあるのに何入れ替えてるんだよw 変数に入れても、
・DOM要素の内容は変わる
・DOMの構造も変わる
・DOM要素の参照は残ってる
って所かな?
jQueryとか関係なく
var elm = document.getElementById('id'),
って書いてるのと同じ。
ID=idをdocumentのDOMツリーからremove()しても、
elmという参照は残ったまま
逆に言えば、参照は残ったままだけど、
DOM要素への変更は反映される。jQueryでも同じ >>838
めんどくせーな。
これでお前でも理解できるだろ?
変数に入れてもDOMは変化するんだって
例1
function exp1() {
var $ul = $('ul')
console.log($ul.children().length) // 5
$ul.children().remove();
console.log($ul.children().length) // 0
}
例2
function exp2() {
var $ul = $('ul')
console.log($ul.children().length) // 5
$ul.append('<li>')
console.log($ul.children().length) // 6
}
例3
function exp3() {
var $ul = $('ul')
console.log($ul.parent().attr('id')); // undefined
$('#id').append($ul)
console.log($ul.parent().attr('id')); // id
} 変数に入れておけば、異なる参照を指すことはない。
このリストが、別のリストに変わったりしない
変化する場合でも、その要素・コンテキスト以下・子孫要素しか変わらない
祖先の要素が変わって、別の要素を指すようになったりしないから、
意図がわかりやすい >>841
よく考えてほしいんだけどさ、
一行目、私は○○にデータを書き換えます。
二行目、○○にデータが書き換わった状態であってほしい
これの方が直感的だよね? >>840
そんなことは書かれる前からわかっとるわ、基本だろ
そういうことでなくて質問と>>838はDOMを変化させない前提だろうよ
パフォーマンス云々言ってるのだし だから変数に入れてもDOMは変化しますよって言ってるんだが?
変数に入れることで、どういう勘違いを
あなたはしてるのですか?っていう話 順を追って説明しないと理解できてなさそう
1. DOMを変化させない前提
2. 変数に入れないと、DOMが変化するように見える
3. 変数に入れると、DOMは変化しないように見える
4. でも変数に入れても実際はDOMは変化する
5. つまり3は勘違い。変数に入れてるのをみてDOMが変化しないように見えたら、それは目が悪い。 久しぶりに除いたが「変数使わないべき、それ以外認めん」の人がまた勘違いで話捻じ曲げて強引に押し通そうとしてるのか その話は知らんけど、>>845に何か物申すこと有る? × 変数に入れずに、2回書いたら、その間にDOM に何か変化があるのかも、と思ってしまう
○ 変数に入れても、2回書いた時、その間にDOMに何か変化があることがある。
× 変数に入れるとDOMは変化しない
○ 変数に入れるとDOMを変化させてもDOM要素への参照は残っている
なんで正しい説明ができないんだろう? >>844
問題文をもう一度読もうか
先ずはそこからだ そして、これを踏まえて説明すると、
jQueryではメソッドチェーンでつなぐことで
変数に入れなくても、変数に入れたのと同じ状態を作ることができる。 >>850
問題文ってこれ?
> 804 名前:Name_Not_Found[sage] 投稿日:2018/04/09(月) 12:47:31.90 ID:???
> 何度も同じjQueryオブジェクトを使う時には
> 今でも一旦変数に代入した方がいいのでしょうか?
> $document = $(document)
> のように。
> パフォーマンスから言えば代入した方がいいはずですが、
> もう気にしなくていいような気もします
じゃああんたはその次のレスを読もうか?
そのレスが間違ってるって話をしてるんだから 変数に入れたらDOMに変化がないと思うだろ!
いや、思わんね(笑)
これだけの話 ちなみの最初の話をすると
$document = $(document)
変数に代入しなくても、document変数に参照が残ってる。
$element = $(this)
変数に代入しなくても、this変数に参照が残ってる
element = document.getElementById('id')
$element = $(element)
変数に代入しなくても、element変数に参照が残ってる
わけで、毎回 $(documet)、$(this)、$(element) を実行しても
(DOMではなく参照が)変わらないことは保証される 一般的にイベントのデレゲーションは負荷軽減に繋がると言われていますが
$(document).on('click','.hoge a',fn)
のようにセレクタで指定している場合、
クリックのたびにイベントが起きた要素がセレクタと一致するかを調べるので
結構負荷が高くなるのではないかと思いました
$('.hoge a').on('click',fn)
のように要素に直接リスナを登録した場合、セレクタの解釈はリスナの登録時だけなので、負荷は小さくなるのでは?
ただデレゲーションの場合、リスナ登録時に存在しないDOMのイベントも捕捉できるという意味もあるので
簡単に置き換えることはできませんが 表に、100セルがある場合、
各セルに、イベントハンドラーを付けると、100個になる
これらの処理が似ている場合には、
表に、1つのイベントハンドラーだけを付けて、
各セルの座標値を、計算した方がよい >>855
負荷とひとまとめにしてるけど、
典型的な速度を取るかメモリを取るか問題やね
デレゲーションを使うと、
1. イベントハンドラの設定が1回ですむ(速い)
2. イベントハンドラが一つで済む(メモリ少ない)
3. イベント発生ごとに発生した要素のチェックが必要(遅い)
4. 要素を増やしてもイベントハンドラの設定は不要(速い)
要素ごとにイベントハンドラをつけると
1. イベントハンドラの設定が要素の数だけ必要(遅い)
2. イベントハンドラが複数必要(メモリ多い)
3. イベント発生しても発生した要素のチェックが不要(速い)
4. 要素を増やす時イベントハンドラの設定が必要(遅い)
イベントハンドラの分メモリが必要と言っても関数の中身自体は共通化できるので
イベントハンドラを持っていますよーという情報のメモリ
またセレクタに一致しているかどうかは、比較的最近のブラウザなら
Element.matchesメソッドがDOM APIに追加されてるのでさほど遅くないはず
で結局の所トレードオフ問題でどちらが良いかはやってみないとわからないし
環境によって変わるし、DOMの構造によっても変わるだろうし、
俺なら気にせずデレゲーション使うだろうな >>826
の、上の程度ならもちろん変数使わないが
実際複雑になったり長くなったりすると下に近くするな
好みだが深くするのが嫌なので >>857
コードまで書いて一生懸命答えてても元文読み違えてたら全て無駄
の典型的パターンだよな >>859
同じく。↓とか
$('#hoge').children('li').eq(計算).children('span').text(なんたら).attr('hage', かんたら); $('#hoge')
.children('li').eq(計算)
.children('span').text(なんたら).attr('hage', かんたら);
って書けば良い
改行できない病かなにかか? >>864
むしろ流れ的にどうやったら改行の問題と読んだのかそのプロセスが知りたい
学生のテスト対策のヒントになるかもw いや改行の問題なんて言ってないだろw
改行を入れることで、読みやすくできるという話だよ
変数に入れればいいって言ってるやつだって
メソッド実行のたびに変数にだって入れないだろ?
「わかりやすい単位で変数に入れる」というはずだ。
だからそのわかりやすい単位で改行をいれればいいだけ >>859
ライブラリなどのサンプル見るとほとんどvarにセットしてる >>867
もういいよ、無理すんなって
益々墓穴掘ってる $('#hoge').children('li').eq(計算).children('span').text(なんたら).attr('hage', かんたら);
を変数に入れるってどうするつもりだったんだろうか?
var $li = $('#hoge').children('li')
var $span = $li.eq(計算).children('span')
$span.text(なんたら).attr('hage', かんたら);
こうか?
$('#hoge').children('li')
.eq(計算).children('span')
.text(なんたら).attr('hage', かんたら);
ならこれで良い気がするな。
変数に入れるバージョンから、変数を取り除いただけ
それよりも>>863の方がわかりやすい気がするのは
行の最初に対象とするターゲットが来てるからかな eq: function( i ) {
var len = this.length,
j = +i + ( i < 0 ? len : 0 );
return this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] );
これは、jQuery のeq のソースコードだが、
これぐらい少なくても、this.length を2回使わない
同じものなら、変数に入れる。
その方が保守しやすく、最適化しやすく、少し速いかも ここは相変わらず、jQuery君が他人に噛みつき、荒らし回ってるんだな >>875
スレタイのどこに「他人に噛みつき、荒らし回る」と書いてある? >>873
>>826の話とずれてる。
>>826は処理対象を変数に入れるって話
設定値を変数に入れるって話じゃない そもそも>>804 >>820に対して(それを無視して)値を入れ替えてることがズレてる
誤解のもとという忠告もわかる
速度に関してはどっちでも変わらんから好みでやればいいだけ
>>859の変数使う好みに対して改行で解決しようとしてることがずれてる
これも好みでやればいいだけ blurメソッドを呼ぶと、
その要素に実際にフォーカスがあるかどうかに関わらずfocusoutが発生すると気づきました
これおかしくないですか?フォーカスがないんですから。
結果、二度focusoutが発生してしまい、変な嵌まり方をしてしまいました 「blurする前にはfocusする」と覚えていればいいですね? あとキーボード系イベントをtriggerする時も、
条件を手動操作と同じにするためにfocusした方がいいと思います
そうですね? if (!$('セレクタ').children().length) {
$('セレクタ').remove();
}
みたいな処理をもっとスマートに書けないでしょうか?
メソッドチェーンで繋いだ一文で書けたらいいと思うのですが >>888
> if (!$('セレクタ').children().length) {
典型的な手続き型的なコードだねw
通常は「lengthみて要素があるかどうかを確認する」というコードはまるまる省ける。
状況にもよるだろうけど、俺はこれが必要な場合を思いつかない
で、回答だけど、まずCSSを使って、セレクタ:empty { display: none; } じゃいかんの?
わざわざremoveしなくても、画面上見えなくていいのであればコレでいける
ただしセレクタの中にはスペースなども含めて完全に空になってないといけないけど
次に実際に消す方法として、:has疑似クラスを使ったもの
$('セレクタ:not(:has(*))').remove();
:has擬似クラスはCSS4相当のものでブラウザネイティブでは実装されていないが、
jQueryは独自で実装しているので使える。IE11でも動いた。
https://api.jquery.com/has-selector/
こっちは完全に空じゃなくてもいいけど、タグなしで直接テキストが書かれていても
消えてしまう。といってもそれは>>888も同じだから問題ないだろう
あとはjQueryの.not や .has メソッドを使って
これと同じような結果になるコードをかけばできると思うけど
ちょっと面倒そうだな >>889
ありがとうございます
フィルタで絞り込むという発想がなかったので、学びが大きかったです
:hasとか:notとかはじめて使いました
ありがとうございました hasフィルタ/メソッドの対象は子要素ではなく子孫要素なんですね
子要素と書いているサイトが大量にありますが・・
対象を子要素に限りたい場合はどう書くのがいいのでしょうか? >>891
え?
子要素がない時はremoveする
ただし子要素が無くて子孫要素がある場合はremoveしたくない
ってこと?
子供がいないなら孫もいないでしょ? >>892
いえ、それはもう解決したので
別の話としてです >>893
試してみましたが子孫も含まれるようです >>896
すみません
書こうと思って見直していたら、
要素セレクタ部分が深い階層の要素にマッチしていたための勘違いと分かりました
要素セレクタ部分を第一階層にしかマッチしないようにしたら、たしかに子要素だけに限定出来ました!
ありがとうございます
ですが、「>」を最初に置く書き方はどんな意味になるのでしょうか?
jQueryを結構長く使ってきたつもりですが、こういう書き方を今まで見たことがありません > ですが、「>」を最初に置く書き方はどんな意味になるのでしょうか?
CSSの基本だから調べて
:hasはjQueryによって先行してサポートされた疑似セレクタだが
文法自体はjQueryが決めたものじゃないし
基本的なものはCSSのセレクタとまったく同じ CSSの親子関係の>と同じなのですね
>.hoge
は
*>.hoge
つまり
「何らかの要素の子要素の.hoge」
という意味になって、
これをhasと組み合わせることで子要素だけが選択できているのですね
親子セレクタの>は知っていましたが
特定数の階層を示す未知の記法なのかと思って混乱してしまいました
ありがとうございました 高速で安全なjQueryを書くために今できること
http://dresscording.com/blog/jquery_performance.html
$('#myContainer a');
と書くより
$('#myContainer').find('a');
と書く方が速いとあります
2013年の記事ですが、今でもそうした方がいいですか? >>901
やってみなければわからない。
ほらよ「jquery selector vs find https://jsperf.com 」で検索して
探してきてやったぜ。
https://jsperf.com/jquery-children-vs-find/37
Chromeだと、$('#formElem fieldset'); の方が速くて
Edge、IE、Firefox だと $('#formElem').find('fieldset') の方が速いんだな
理想的な結果だ。ブラウザによって違う。そんなの気にしたってしょうがない。
実用上問題ないなら気にすんな
どうでもいいが、EdgeだとChrome 58.0.3029と判定されるのな
Microsoft Edgeのユーザーエージェントがカオスなので注意
https://qiita.com/tonkotsuboy_com/items/7b36bdfc3a9a0970d23b
> Mozilla/5.0 (Windows NT 10.0; Win64; x64; ServiceUI 11)
> AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36 Edge/16.16299 あー、よくみりゃこれjQueryのバージョン低いな jsperf、githubアカウントが必要になったから面倒なんだよな
でもまあ1系でもquerySelectorAll使われてるし結果に大差はないだろ >>902
気にすることでもないのですね
ありがとうございました えー、何今みんなセレクタ使ってるんか?
速度差気にするほどでないのはもっともだが統一性からもメソッド使ってるわ $('#myContainer a');
じゃなくて
$('#myContainer').find('a');
こう書くってことだろ?
でも、 '#myContainer' も 'a' もセレクタなんだよねw
統一性をもたせるならむしろセレクタにしたほうが良い >>908
最初のセレクタは減らしてその後絞った方がいい
で統一ってことだろ
以前から書籍やブログで書かれている でも
Chromeだと、$('#formElem fieldset'); の方が速くて
Edge、IE、Firefox だと $('#formElem').find('fieldset') の方が速いんだな 以前から書籍やブログで書かれているからって
あてにならないですねーw 全部JSで書かれているならセレクタのパースの方が遅くなるはずですが
querySelectorはネイティブコードなので速くなってるのでしょうね >>910
それは 高速化のため? 可読性のため?
場合によるけど、ほとんどの場合セレクタに書いた方が
可読性が高まって良いと思うよ
場合によるけど、時代や環境・実装によって変わる高速化より
可読性を優先した方が良いと思うよ 速度でメソッド使ってるわ
もっとも3になってからは速度面では知らん
可読性ではどっちも変わらん
:has/has()、:first/first()、:eq/eq()など、またチェーンメソッドではどうなんだろ >>915
jQueryは1でも後半のはquerySelectorAllとか使ってる。
そもそも1と2は、1の方が対応している(古い)ブラウザが多いという
違いなので2でやってることは全て実装されていると考えるべき
3は統合版なので言うまでも無くだな 1系はIE6以降対応で、2系はIE6〜8を切り捨てたもの。
(当時の)最新ブラウザには1系も2系も対応していた。
だから2系の方がファイルサイズは小さいが、
対応ブラウザは1系の方が多い状況だった
1系と2系は機能的には一緒でともに機能追加・メンテナンスも続いた。
通常であれば1系は古いバージョンで新機能は2系のみというのが
一般的なバージョンの分け方なのに、jQueryはそうなっておらず
混乱をもたらすということで、3系として合流することになった。
この時、通常のjQuery 3.0とは別に古いブラウザ対応のjQuery compat 3.0
というのが作られる予定だったが、IE8のサポート終了が早まったために
IE9以降対応のjQuery 3.0はに一本化された code.jquery.comの証明書が死んで、そこらじゅうのサイトが余波で崩壊してるね
とりあえずセキュリティ例外にぶっこめば動くには動くが・・・セキュリティ面でもサイト利用者にそれを求めるのかって点でもマズイな 最近書き始めた者です。
jQuery用の入力候補とかインテリセンスを使っている人いますか? VSCodeを使っていますが、jQueryのメソッドも補完されますね
標準機能によるものなのか拡張機能によるものなのかは分かりませんが >>919
そんな基本的なこと長文書かなくてもわかってるから大丈夫
なぜ1と2の違いという全然関係ない話題に持って行こうとしてるのかということ >>925
それはそれとして、じゃあなんで1と2になってるんだ? jQuery公式のCDNの証明書切れは
NHKで放送されるレベルだぞ >>930
なに言ってるんじゃなかくて、
なんで1と2になってるんだ?って
聞いてるんだが? さすがニュースは違うな。jQueryのCDNでトラブルがあった時、
jQuery使うなとかCDNを使うなという話ではなく
HTML標準ににフォールバック機能がないことが問題という話になってる サーバーが落ちるなんてことは普通に想定しておかなければ駄目なのでは?
CDNを使う限りあり得る問題なのでjQueryガーとか言ってる連中はアホですね? サーバが落ちることを想定してるからCDN使うんだが >>935
CDNとjQueryが何の関係があるの?
自分のサーバーで配信すればいいだけでしょ?
HTML標準にないだけで、CDNが落ちたら自分のサーバーに
置いたjQueryを使うという手法も有るしさ まずjQuery公式チュートリアルからcdn からロードしてる記述駆逐しようぜ!
個人の技術ブログとかのコードにもcdnからロードしてる箇所あったら取り締まって吊し上げよう。
cdn使うことで速度ガーとかキャッシュガーとか書いてる無責任サイトも潰そう。 レス数が900を超えています。1000を超えると表示できなくなるよ。