tacamy--blog

JavaScriptを勉強中の人のブログです。

CSSではみ出した文字を省略する「text-overflow: ellipsis;」がいつの間にかPCでも使えるようになってた!

領域をはみ出したときに三点リーダー(…)で省略するtext-overflow: ellipsis;は、スマホサイトでは普通に使っていたけど、PCでは数年前に使おうとしてなんかのブラウザでダメだった記憶があって、使えないものとばかり思い込んでいた。

でも、ふとCan I use CSS3 Text-overflowをみたら、めっちゃ対応してた!IEなんて6から対応してるし、Firefoxも7から使えるようになってた。

実際に書いてみたら、いつものこんな感じのコードで普通に使えました。

overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;

昔、JSでなんとかそれっぽくできないかみたいに、誰かががんばっていたのはなんだったのか。

わたしみたいに使えないと思い込んでて、意外としらない人いるかもしれないので、ブログに書いてみました。

楽天カンタン送料表示(Chrome拡張)を公開したよ!

今週の月曜に突如Chrome拡張機能に興味をもって、火曜に勉強を始めて、木曜の今日Chromeウェブストアに公開しました!(∩´∀`)∩ワーイ

f:id:tacamy:20140123143708p:plain

ウェブストアに出てる!!!感慨深い!!!Developer感アル。

どういう機能かというと、楽天の商品ページにいくと、画面左下に送料をすぐに見られるためのボタンが表示されるというものです。

楽天の送料ページは、http://www.rakuten.co.jp/shopName/info2.htmlで見られるのですが、いろいろ面倒です。

  • 送料を見るために、商品ページから画面遷移が必要
  • 送料以外の情報も一緒に書かれている
  • 長すぎてどこを見ればいいのかぱっと見で分からない
  • ショップによって送料ページへのリンクの位置がバラバラ

これらのことを解決したくて、送料の部分のHTMLだけをスクレイピングして取得してきて、商品ページ内で送料をすぐに見られる機能がほしかったのでつくりました。

オススメの勉強方法

Chrome拡張機能についての勉強は実質2時間くらいしかしてないけど、すごくお手軽につくれてしまった。

事前知識ゼロからだったので、まずはドットインストールで勉強しました。1時間くらい。

これだけでかなり概要がわかって、私が作りたいものはカンタンそうだったので、勉強とかいいからとりあえずすぐにつくろうと思って、ほかにはとくに勉強してないです。

公式サイトには、マニフェストの書き方とか、パーミッションの与え方とか、APIの使い方とかぜんぶここに書いてあるのですが、英語なので困ったら見る程度しか使ってない・・。

技術的なこと

ソースコードGitHub上で公開してます。

jQuery使ってるし、とくに大したことは何もしてないのでアレですけど、次のようなことをしています。

パーミッションの設定

楽天の商品ページのURLはhttp://item.rakuten.co.jp/*なのですが、送料ページはhttp://www.rakuten.co.jp/*ドメインが異なるので、manifestにpermissionsの指定が必要でした。

"permissions": [
  "http://www.rakuten.co.jp/*"
],

スクレイピング

送料部分のHTMLにクラス名なりID名がついてればカンタンだったのですが、案の定テーブルレイアウトでそんなものなかったので、下記のような感じで、見出しにあたる部分の文字列を拾ってきて、そこから次のhrまでの部分をとってくるみたいなことしてます・・。

var $data = $(data)
  .find('font:contains("配送について")')
  .parent()
  .nextUntil('hr');

ショップによって、なぜか微妙にこのへんが違う場合があって、たまにこれで取得できない場合もあります。その場合は、ボタン自体出ないようにしました。

われながらめちゃ便利だと思うので、ぜひ使ってみてください!

手っ取り早く Mac でローカルサーバーを立てる方法

ローカルサーバーを立てると、同じネットワークにつながってる別の端末から簡単にアクセスできるようになるから、スマホの表示確認とかに便利。でもいちいち httpd.conf とかいじるのはダルい。このやり方なら一瞬でできるからちょう楽ちん。

ターミナルでサーバー起動

サーバーのルートにしたいディレクトリまで cd コマンドで移動したら、下記コマンドを実行。

$ python -m SimpleHTTPServer 8888

最後の数字はポート番号で、他に使われていなさそうな番号に適当に変えれば、複数のサーバーを同時に起動できる。

ブラウザで表示確認

localhost で確認

ブラウザのアドレスバーに http://localhost:8888/{ファイル名} と入力して表示確認。

表示できてるなら、ローカルサーバーを立てるのが成功してる。表示できなかったら、ターミナルを見て、さっきのサーバー起動時になんかエラー出てないか確認してググろう。

IP アドレスで確認

localhost だと他の端末からアクセスできないので、IP アドレスを使ってアクセスします。

  1. ターミナルで ifconfig と打つか、ネットワーク環境設定の画面を見て、自分の IP アドレスを調べる。
  2. ブラウザのアドレスバーに http://{IP アドレス}:8888/{ファイル名} と入力して表示確認。

これで見れてれば、同じネットワークにいる別の端末から、IP アドレス経由でアクセスできます。

CTO に教えてもろた。

input type=”email” のバリデーションチェックを止めたい

input type=”email” とすると、対応ブラウザの場合、ブラウザ側でバリデーションチェックをして、Email の形式じゃなかった場合はエラーメッセージを表示してくれる。

でもこれがジャマになって止めたいときもある。その場合は form タグに novalidate 属性をつければ抑止できるらしい。

<form>
<input type="email">
</form>

これを、

<form novalidate>
<input type="email">
</form>

こうするだけ。

Chrome のみで確認。

thx @yomotsu 先生

ssh の公開鍵認証のいろは

CTO が分かりやすく教えてくれたので、メモ。

公開鍵の基本

公開鍵とは、github や beanstalk、Heroku などの git を使うサービスを利用するときに必要な、~/.ssh 以下につくられるファイル。

公開鍵と秘密鍵

ファイル名の最後に .pub がついている方が公開鍵、ついていない方が秘密鍵。

公開鍵とは、例えるなら家の鍵穴みたいなもので、誰でも見ることができる。 秘密鍵とは、例えるなら家の鍵で、自分しか持ってないもの。 公開鍵(鍵穴)と秘密鍵(鍵)が一致することで認証される仕組み。 だから、秘密鍵は絶対に公開してはいけない。

rsa と dsa

rsa と dsa の違いは、暗号化方式の違い。

利用するサービスの公開キー登録方法の説明を読んでみて、書いてある方を使えばOK。

公開鍵の使い回し

サービス間での使い回し

サービスごとに別々に鍵を用意して分けてもいいけれど、使いまわすこともできる。

そのサービスで登録しているメールアドレスとは違うメールアドレスが記述されている鍵でも関係なく使い回しができる。サービスの説明ページで、ssh-keygen コマンドで鍵を作成するように書いてあったとしても、すでに別のサービスで作成済みであれば新たに作成する必要はない。

マシン間での使い回し

普通、鍵はマシン固有のものなので、複数のマシンを使うなら、それぞれで鍵をつくらないといけない。 その場合はマシンを買い換えたときも、鍵を新たに作りなおす必要がある。

複数のマシンで鍵を使い回す場合は、~/.ssh 以下のファイルをごっそり別マシンにコピーして、鍵照合すれば使える(?)。

感想

鍵穴と鍵の説明わかりやすくて、CTO さすが CTO。もうこれで怖くない!

gem update --system したら gem update bundler もね!

Sass やら Compass やらの普及で、フロントエンドな人も Ruby や gem に触れることが増えたけど、こないだ調子こいて gem をアップデートしたら、rails server でエラーが出て、rails で作られたシステムが起動できなくなってしまった・・。

エラーの内容はこんな感じだけど、bundler のバージョンはちょっと違ったかも(メモしてなかった)。

/usr/local/rvm/gems/ruby-1.9.3-p385@global/gems/bundler-1.1.5/lib/bundler/rubygems_integration.rb:187:in `stub_source_index170': uninitialized constant Gem::SourceIndex (NameError)

ぜんぜん分からなくて泣いていたら、ほ神ら先生が助けてくれたので、忘れないようにメモします。

やったこと

gem のバージョン確認

$ gem -v
2.0.3

gem のバージョンは、2.0.3 で新しい。むしろエラー出てない人より新しい。これのせい?

bundler もアップデート

$ gem update bundler

いろいろインストールされました。

bundler のバージョン確認

$ bundle -v
Bundler version 1.3.4

新しくなった。そして rails server できるようになりました!

解説

gem の bundler が何かを、Node.js に例えて分かりやすく教えてもらえました。

  1. Ruby の gem は、パッケージ管理ツールで、Node.js だと npm みたいなもの。
  2. npm の場合はプロジェクトごとに管理できるし、-g でグローバルにもできる。
  3. でも gem はグローバルしかできない(Node.js で言う -g だけ)。
  4. プロジェクトごとの管理は、bundler が行う。
  5. gem と bundler の 2 つを合わせて、Node.js の npm みたいに使える。

分かりやすい・・!ほかちゃんは説明の天才か。

まとめ

gem update --system

したら、

gem update bundler

もした方が安全。特に gem がメジャーアップデートとかしてたら、やった方がいいかも。

JavaScript で日付のフォーマットを整形する

Movable Type で日付のフォーマットをいじりたいときには、% を使って簡単に設定できます。 例えば、「2013年03月14日 (月)」と表示したいときは、次のように指定します。

<$MTDate format="%Y年%m月%d日 (%a)"$>

詳しくは、日付に関するテンプレートタグのモディファイアリファレンス を参照。

その感覚で、JavaScript でも同じようなことできると思っていたら、そういうものは無いらしい。 なので、自分でフォーマットを整形したいときは、次のように指定します。

// 今日の日付で Date オブジェクトを作成
var now = new Date();

// 「年」「月」「日」「曜日」を Date オブジェクトから取り出してそれぞれに代入
var y = now.getFullYear();
var m = now.getMonth() + 1;
var d = now.getDate();
var w = now.getDay();

// 曜日の表記を文字列の配列で指定
var wNames = ['日', '月', '火', '水', '木', '金', '土'];

// 「月」と「日」で1桁だったときに頭に 0 をつける
if (m < 10) {
  m = '0' + m;
}
if (d < 10) {
  d = '0' + d;
}

// フォーマットを整形してコンソールに出力
console.log(y + '年' + m + '月' + d + '日 (' + wNames[w] + ')');

コードの解説

「年」「月」「日」「曜日」を Date オブジェクトから取り出してそれぞれに代入

var y = now.getFullYear();
var m = now.getMonth() + 1;
var d = now.getDate();
var w = now.getDay();

date オブジェクトには、getFullYear() getMonth() getDate() getDay() というメソッドが用意されているので、取り出したらそれぞれ別の変数に格納しています。

なぜか getMonth() だけは、実際の月から -1 された数字が入るので、 +1 しています。

date オブジェクトのメソッドの詳細は Dateオブジェクト / JavaScriptリファレンス を参照しました。

曜日の表記を文字列の配列で指定

var wNames = ['日', '月', '火', '水', '木', '金', '土'];

曜日を取り出す getDay() では、0 から 6 の数字が取得できます。 0 が日曜日、1 が月曜・・・6 が土曜日という対応になっているので、曜日をどのように表記するかかを文字列の配列で持っておきます。

「月」と「日」で1桁だったときに頭に 0 をつける

if (m < 10) {
  m = '0' + m;
}
if (d < 10) {
  d = '0' + d;
}

「3月」を「03月」と 0 詰めして表記したい場合は、自分で処理しなければなりません。 入っている値が 1 〜 9 の場合は、頭に '0' という文字を追加することで、自動的に型変換されて 3 という数値が '03' という文字列になります。

フォーマットを整形してコンソールに出力

console.log(y + '年' + m + '月' + d + '日 (' + wNames[w] + ')');

あとは、それぞれ処理済みの変数を、好きなように整形して表示させるだけです。

関数化する

同じサイトの中では、日付の表記は普通は統一させると思います。でも、日付を扱う場所で都度上記の処理を行うのは面倒なので、フォーマットを整形する部分を関数化して、どこからでも呼び出せるようにしておくと便利です。

// Date オブジェクトを作成
var now = new Date();

// dateFormat 関数の実行
console.log(dateFormat(now));

// dateFormat 関数の定義
function dateFormat(date) {
  var y = date.getFullYear();
  var m = date.getMonth() + 1;
  var d = date.getDate();
  var w = date.getDay();
  var wNames = ['日', '月', '火', '水', '木', '金', '土'];

  if (m < 10) {
    m = '0' + m;
  }
  if (d < 10) {
    d = '0' + d;
  }

  // フォーマット整形済みの文字列を戻り値にする
  return y + '年' + m + '月' + d + '日 (' + wNames[w] + ')';
}

date オブジェクトを引数で渡して、整形済みの文字列を戻り値で受け取る関数にしてみました。

ゼロ埋めの方法を改善(2013-03-21 追記)

コメント欄で、ゼロパディング(ゼロ埋め)は .slice() メソッドを使えばできると教えてもらったので、dateFormat 関数を修正してみました。

// Date オブジェクトを作成
var now = new Date();

// dateFormat 関数の実行
console.log(dateFormat(now));

// dateFormat 関数の定義
function dateFormat(date) {
  var y = date.getFullYear();
  var m = date.getMonth() + 1;
  var d = date.getDate();
  var w = date.getDay();
  var wNames = ['日', '月', '火', '水', '木', '金', '土'];

  m = ('0' + m).slice(-2);
  d = ('0' + d).slice(-2);

  // フォーマット整形済みの文字列を戻り値にする
  return y + '年' + m + '月' + d + '日 (' + wNames[w] + ')';
}

if が取れてスッキリしました。うれしい。GAVAScript さん、吉田さん、どうもありがとうございます。

ライブラリを使う(2013-03-21 追記)

自分で書かずにライブラリを使うのが便利らしいです。教えてくれてあざます!

参考サイト Thx ♡