かなりハマったのでappend()などを使って動的に追加したHTMLの要素にhoverイベントを追加する方法を残しておきます。説明は全部 coffee script で書いてるので生のJSが良い人は自動変換サービスでもをつかってください。
前提となる知識 まず基本として $('#foo').click -> console.log "押された!" のように #foo に対して click イベントが追加されているわけですが、このイベントの追加はページの読み込み時に行われるために append() などで後から動的に追加された要素にはイベントの登録がされません。
なのでそれを解決するために昔の delegate(), 今なら on() メソッドがあるわけです。簡単でわかり易い名前に統一されたので見た目はスッキリしたのですが、代わりにサンプルコードを探すのが大変になりました。 on って単語短すぎやしません…?
後から追加された要素に click イベントを追加 前置きが長くなりましたが
$('#foo').click -> console.log "押された!" を動的に追加された要素に適用させるには
$(document).on 'click', '#foo', -> console.log "押された!" とします。document 内部の要素がクリックされるたびにイベントが発火され、クリック対象が #foo ならメソッドが実行されます。もちろん document ではなくページ読み込み時に存在する #foo の親に当たる要素なら何でも構いません。無駄なイベントを発生させないためにできるだけ近い親が良いでしょう。
後から追加された要素に hover イベントを追加 同様に hover イベントも click イベントのように簡単に書き換えれたらいいのですが、hover イベントを on() を使って割り当てると hover は mouseenter と mouseleaveという複数のイベントを受け取っており、このように複数のイベントを受け取ってる関数を on メソッドで割り当てるためにはどのイベントを受け取ったのかを判別して処理する必要が出てきます。
記述が間違っていたので修正しました。
onイベントの引数として "hover"を使った場合、それは単なる "mouseenter mouseleave" の別名であって hover() 関数とは無関係であり、またこの記述方法は jQuery1.
jQuery で選択した要素が存在するかどうかの関数が何故か用意されてないようだったので追加しました。
CoffeeScriptで書いてるのでjavascriptとして使いたい場合は converter にかけてください。
$.fn.isExist = -> $(@).length != 0 $.fn.isNotExist = -> $(@).length == 0 参考 [How to tell if an element exists | jQuery for Designers – Tutorials and screencasts][1]
rails には 値の有無をチェックするときにタブやスペースなどの空白が入っていても「空」だと判断する便利な blank? 関数が用意されていますが、どうやら JavaScript や jQuery には用意されてないので追加してみました。
自分で書いた後にもっと良さそうなコードを見つけたのでそちらを紹介します。
JavaScript $.fn.isBlank = function() { return !$(this.html()) || $.trim($(this).html()) === ""; }; Coffee もちろん Rails 標準のCoffeeも。
$.fn.isBlank = - !$(@.html()) || $.trim($(@).html()) is "" 参考 [Checking for blank input with jQuery – Stack Overflow][1]
[jQuery isBlank() | LakTEK (Lakshan Perera)][2]
画面遷移無しでファイルのアップロードしようと思ったらiframeを使った技とかややこしい情報が色々出てきて、なかなかやりたいことに辿りつけなかったのでメモ。
やりたい事と条件 ・ajaxなテキストファイルのアップロード
・テキストをRubyで編集して返す
・画面遷移せずに結果を表示
・IEは諦める。
必要最低限のコード まずHTMLを用意
ajaxupload.html
`
<script type="text/javascript" src="ajaxupload.js" charset="utf8"></script><br>
textarea{height:80%;width:100%;}
` つぎにjavascript
ajaxupload.js
`
$(function(){ $("#upload").click(function(){ var file = $("#file")[0].files[0]; var reader = new FileReader(); reader.readAsText(file, 'UTF-8'); reader.onload = showFile; }); function showFile(event) { $.ajax({ type: "POST", url: "ajaxupload.rb", data: { filedata:event.target.result} }).done(function(msg) { $("#output").html(msg); }); } }); ` んで何か処理をするRubyのスクリプト。ここではファイルの中身をそのまま返してるだけ。(パス名は適宜変更してください。)
ajaxupload.rb
`
#!P:\Dropbox\bin\RailsPortable\App\Rails\bin\ruby.exe require "
jQuery を使って
「クリックされた時に左なら要素を消して、右なら何もしない。」
という動作をさせようと思ったら日本語だと検索してもすぐに答えが出てこなかったので、また stackoverflow から解説を紹介します。
実際のコードがこちら。
$('#element').mousedown(function(event) { switch (event.which) { case 1: alert('Left mouse button pressed'); break; case 2: alert('Middle mouse button pressed'); break; case 3: alert('Right mouse button pressed'); break; default: alert('You have a strange mouse'); } }); mousedown の時に渡されるイベントを確認して場合わけすればよい、と。
つまり左クリックで要素を隠すにはこうします。
//左クリックされると foo を隠す $(".foo").click(function(e){ if(e.which == 1){ //左クリック $(this).hide("fast"); } }); 他の方法 頻繁に使うのであれば jquery.detailclick.js を入れてこんな風に使えるようにしておくとよいかもしれません。やっぱりこちらの方が jQuery っぽくて見やすいですね。
$("target").rightClick(function()
{
$(this).text('右クリックされました!').css('background-color', '#ff3399');
});
参考 javascript - How to distinguish between left and right mouse click with jQuery?
$(window).width() と $(document).width() や
$(window).height() と $(document).height() がどういう時に違う値を返すかわからなかったので検索したら Stack Overflow に簡潔でわかりやすい説明がされてたので紹介します。
When you have a scrollbar on the webpage.
(スクロールバーが表示されてる時)
わかりやすいですね。一応念のために書いておくと window が「ブラウザの表示領域」で、document が「ページ全体」です。
参考 jquery – When can $(document).width() and $(window).width() show different values? – Stack Overflow
http://stackoverflow.com/questions/8134741/when-can-document-width-and-window-width-show-different-values
lispでmapに初めて触れた時は「何、このめんどくさい関数?」と感じ、正直な話あまり触れたくもなかったのですが慣れてくるとこいつはとても便利な賢いやつです。
さてjavascriptでもmapが使えるか調べてみたらjQueryで提供されてました。
mapを使えば配列全部に関数を適用させて、返り値を配列で受け取れます。for文なんて使わなくてもええんやっ!!
使い方の例 定番の累乗を求めるサンプル。
arr = [1,2,3]; arr = $.map(arr, function(n,i){return n*n;}); for(i=0;i<arr.length;i++){ alert(arr[i]); } サンプルには良く使われるけど、実際にプログラミングしてて累乗が必要になったことがないですね。まあサンプルなんで実用性よりも分かりやすさが重要だから当然といえば当然の話しですね。
とりあえずこんな感じの動作がmapはできます。
要素をまとめて取得 たとえばこんなhtmlがあって
<div>1</div> <div>2</div> <div>3</div> 配列で[1,2,3]が欲しいとする。
そんな時もこの map を使えば一発解決さ!(深夜の外人がやってる通販のノリで)
arr = $("div").map(function(){ return $(this).text(); }).get(); これでとれる。注意点は最後の get()。これがなくても配列っぽいのが返ってくるんだけども、これはjQuery-wrapped arrayというものらしく別物とのこと。
for文で実行したり arr[0] で要素のアクセスしたりはできるけどもjoinすると上手く行かない。このjoinがうまくできないのにはまってだいぶ時間を食われました。
arr.constructor でクラスを調べたら
function Array() { [native code] } となるべき所が
function (a, b) { return new e.fn.init(a, b, h); } になってました。この「get() すればよい」という情報を得るためにどれだけ遠回りしたことか…。
とはいえこれで安心してmapをjavascriptでも使えるようになったのでガシガシ使っていこうと思います。
参考 http://api.jquery.com/map/