DOCTYPE宣言するとheight:100%が期待通りの動作をしない

tanukikawaii.hatenadiary.jp

この記事、実はPingendoで作ったページに自前で機能を追加していった際に起こった現象なのです。

で、html側のソースに

<!DOCTYPE html>

がなかったのでなんとなく追加。
すると、height:100%;なdiv(bodyの子要素)がviewportの縦全体に表示されなくなった。

  • html
    • body
      • div (height: 100%) ← ここ
      • なんちゃら
      • かんちゃら

stackoverflow.com

ほえー。記述の通り

html,
body {
  height :100%;
}

を指定してあげると期待通りの画面縦いっぱいに表示してくれた。

(html5の)DOCTYPE宣言のはたらき

<!DOCTYPE html>

すると

  • ブラウザのレイアウトエンジンが利用するモードを完全準拠モードにする

developer.mozilla.org

モード3つ

  • 後方互換(Quirks)モード
    • レイアウトは、古いブラウザのような非標準の動作をエミュレート
  • 完全標準(Full Standards)モード
    • HTMLやCSSの仕様書で書かれてる通り動作する
  • ほぼ標準(Almost Standards)モード

違いの詳細とか -> 互換モード

てことは後方互換モードにおいて、jQueryが一部期待した動作をしないことがあるのかな。
後方互換モードを想定してるソースに対しては、無理にDOCTYPE宣言追加しないほうがいいのかも(推測)

いままではー
とりあえずDOCTYPE宣言しとこう!で書いてたけど。
これの有無で動作が変わってしまうこと多々ありそうで、意識しといたほうがいいなーっておもいました。

jQuery - height / innerHeight / outerHightの違い

さっきの記事書いたついでにメモっておく。
このさき結構使いそう(なきがする)
すっごい参考にした→http://www.buildinsider.net/web/jqueryref/009

項目 padding border-width margin
height
innerHeight
outerHeight
outerHeight(true)

○ = 含む
✗ = 含まない

s/height/width/i
の場合も同様。

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便利だなー!画像ぽちっ。 f:id:tanukikawaii:20170505014202p:plain

はい。
なにかがおかしい。console.log。
f:id:tanukikawaii:20170505014353p:plain
(1行目が$(window).innerHeight(); の値)

解決策1

おかしい。生jsで書いてみた。

function centeringModalImg() {
    // ウィンドウの高さ,幅を取得
    let window_w = window.innerWidth;
    let window_h = window.innerHeight;
(以下略)

f:id:tanukikawaii:20170505015823p:plain f:id:tanukikawaii:20170505015842p:plain

わあい. 高さの値も上手く取ってこれた。

解決策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

request_refererって?
redirect_to request_referer

なにそれ定義してない。

ぐぐった。

リファラを呼ぶ。らしい… まんまですね。 リファラって?

ぐぐった。

e-words.jp

ほえー。 戻るボタン的なやつなのかな(ふんわり)

rspec assigns(:var)がnilになる問題.

今日からまた書きます(ふらぐ

今日詰まったとこ

Q, RSpec controllerのテストにおいて

assigns(:instance_var) 

nilになる.全てがnilになる。

A,

authenticate_user! 掛けてるコントローラの場合, ログインが必要。 今回はexceptがexpectになってた( ˘•ω•˘ ).。oஇ( ˘•ω•˘ ).。oஇ

それとcontrollerに定義してあるローカル変数は見えないっぽい。 スコープの問題?