jQuery - $(window).innerHeight();でウィンドウの高さを超えた値が戻る
小さなことでもいいから1記事/dayは何か書くぞお
今日のテーマ,やりたかったこと
jQuery, javascriptでウィンドウの高さを取得したい
(モーダル画像を画面中央に表示したい)
こまったこと
$(window).innerHeight();
とかだと想定通りの値が帰ってこない。
ウィンドウの高さを大きく超えた値が帰ってくる。
解決法
1,
window.innerHeight;
生js使うと想定通りの値を取ってこれた。
2,
<!DOCTYPE html>
DOCTYPE宣言忘れてた。付けたら想定通りの値を取ってこれた(びっくり)
詳細、経緯
ぼくのポートフォリオサイト作成にあたり、
画像クリックを起点としたモーダルを自前で実装してみた。
参考にした→https://syncer.jp/jquery-modal-window
その際、表示されるモーダルの座標をjsで取得したかったからこんな風にかいた。
function centeringModalImg() { // ウィンドウの高さ,幅を取得 let window_w = $(window).innerWidth(); let window_h = $(window).innerHeight(); // モーダル画像の高さ,幅を取得 let app_w = $(".modal-app-img").width(); let app_h = $(".modal-app-img").height(); // 足して2で割る let pxleft = ((window_w - app_w) / 2); let pxtop = ((window_h - app_h) / 2); // 予めposition: fixed;を指定してある要素にleft,topを追加。 // 画面中央に画像が表示されるように。 $(".js-modal-app").css({"left": pxleft + "px"}); $(".js-modal-app").css({"top": pxtop + "px"}); }
やったー!jQuery便利だなー!画像ぽちっ。
はい。
なにかがおかしい。console.log。
(1行目が$(window).innerHeight();
の値)
解決策1
おかしい。生jsで書いてみた。
function centeringModalImg() { // ウィンドウの高さ,幅を取得 let window_w = window.innerWidth; let window_h = window.innerHeight; (以下略)
わあい. 高さの値も上手く取ってこれた。
解決策2
<!DOCTYPE html>
をHTML側に宣言するの忘れてました…
参考→http://unguis.cre8or.jp/web/253
付けたら
$(window).innerHeight();
でも想定通りの値が戻ってきたよ(๑•̀ㅂ•́)و✧
DOCTYPE宣言、特に意識せずとも書いてて必要性に疑問を持ってたんだけど
まさかjQueryの挙動に影響を及ぼすなんて…。
重要性を痛みでもって実感したよ。
また今回、副次的にhtmlのviewportの概念を初めて知った。
これについてはcordgridに分かりやすく書いてあるから寝る前に読もう。
それと、こっちの解決策はこの記事書きながら調べてたらたどり着いたのだ。
早速ブログ書いてよかったー><!!
SQL サブセレクト(Rails Tutorial 14章)
またつらつらと書き始めますヽ(•̀ω•́ )ゝ✧ gvimのguifontwideをゆたぽんにしたのだ。かわいいぽん。
サブクエリ
- フォローしてるユーザの投稿(と,自分自身の投稿)を取得したい。
def feed Micropost.where("user_id IN (?) OR user_id = ?", following_ids, id) end
は遅い。 なぜなら
following_idsでフォローしているすべてのユーザーをデータベースに問い合わせし、さらに、フォローしているユーザーの完全な配列を作るために再度データベースに問い合わせしている
データが数千件あると死ぬ。
解決策
サブセレクトを使う。 集合のロジックをDB内に保存する。結果的に問い合わせ回数が減る。
- まずfollowing_idsをSQLに置き換える
# レシーバのユーザがフォローしてるユーザを全て選択 following_ids = "SELECT followed_id FROM relationships WHERE follower_id = :user_id"
- これを既存のSQLに内包させる
def feed following_ids = "SELECT followed_id FROM relationships WHERE follower_id = :user_id" Micropost.where("user_id IN (#{following_ids}) OR user_id = :user_id", user_id: id) end
そもそもサブセレクトって?
[SQL] 7. サブクエリ 1 | TECHSCORE(テックスコア)
入れ子にして内側のクエリが生成した値を外側のクエリが評価する。らしい。
イマイチピンとこないから実際に違いを観る
条件
- User.firstが999人のユーザをフォロー
- ひとりのユーザにつき50件のMicropost(投稿)を保持
# びふぉー def feed Micropost.where("user_id IN (?) OR user_id = ?", following_ids, id) end # ちょい冗長だけど勉強のためにSQL文も記録しとく。 User Load (2.9ms) SELECT "users".* FROM "users" ORDER BY "users"."id" ASC LIMIT ? [["LIMIT", 1]] (7.1ms) SELECT "users".id FROM "users" INNER JOIN "relationships" ON "users"."id" = "relationships"."followed_id" WHERE "relationships"."follower_id" = ? [["follower_id", 1]] Micropost Load (888.7ms) SELECT "microposts".* FROM "microposts" WHERE (user_id IN (3,4,5,6,7,8,... 2.9 + 7.1 + 888.7 = 898.7ms
# あふたー def feed following_ids = "SELECT followed_id FROM relationships WHERE follower_id = :user_id" Micropost.where("user_id IN (#{following_ids}) OR user_id = :user_id", user_id: id) end [1] pry(main)> User.first.feed User Load (2.7ms) SELECT "users".* FROM "users" ORDER BY "users"."id" ASC LIMIT ? [["LIMIT", 1]] Micropost Load (627.2ms) SELECT "microposts".* FROM "microposts" WHERE (user_id IN (SELECT followed_id FROM relationships WHERE follower_id = 1) OR user_id = 1) ORDER BY "microposts"."created_at" DESC 2.7 + 627.2= 629.9ms
ひえーこれだけでも3割程度違っちゃうのかー うーんすごい。 SQL周りの基本的なところ抑えないとだ・・・。
ActiveRecord#Base.includes
pry(main)> @books = Book.includes(:bookmarks, :reviews).order('updated_at DESC') Book Load (3.2ms) SELECT "books".* FROM "books" ORDER BY updated_at DESC Bookmark Load (4.9ms) SELECT "bookmarks".* FROM "bookmarks" WHERE "bookmarks"."book_id" IN (3, 2) Review Load (0.2ms) SELECT "reviews".* FROM "reviews" WHERE "reviews"."book_id" IN (3, 2)
@books.to_sql => "SELECT \"books\".* FROM \"books\" ORDER BY updated_at DESC"
?
request_referer
perfect_ruby 15章
p548
poti:todo user1$ be irb irb(main):001:0> require "todo" => true irb(main):002:0> cmd = Todo::Command.new => #<Todo::Command:0x007fbad7b10cf8> irb(main):003:0> cmd.execute => nil irb(main):004:0> cmd.create_task("create_name", "create_content") TypeError: Cannot visit Integer from /Users/user1/.rbenv/versions/2.4.0/lib/ruby/gems/2.4.0/gems/arel-3.0.3/lib/arel/visitors/visitor.rb:25:in `rescue in visit' from /Users/user1/.rbenv/versions/2.4.0/lib/ruby/gems/2.4.0/gems/arel-3.0.3/lib/arel/visitors/visitor.rb:19:in `visit' from /Users/user1/.rbenv/versions/2.4.0/lib/ruby/gems/2.4.0/gems/arel-3.0.3/lib/arel/visitors/to_sql.rb:241:in `visit_Arel_Nodes_Limit' from /Us... irb(main):005:0> Todo::Task.all => [#<Todo::Task id: 6, name: "create_name", content: "create_content", status: 0, created_at: "2017-02-07 00:30:44", updated_at: "2017-02-07 00:30:44">] #データ自体はできてる
データ自体はできてるからって無視してたら無理が出た.
(変数に格納できないとか…)
結果から書くとrubyのversonを
2.4.0 -> 2.0.0-p195
へ下げて解決.
写経時はversion合わせないと偉い目に合う。ことを学びました.
しくしく