query: tag:js

jQueryで append すると、追加したDOM中のscript タグが実行されます。

js>>
$('#target').append(what);
<<--

script タグを実行せずに append したい場合、あらかじめ
script タグを取り除いておけば ok

js>>
what.find('script').remove();
$('#target').append(what);
<<--

posted by genki genki on Sun 6 Jul 2014 at 18:05 with 0 comments

Rails 2.0 以降から導入されたCSRF対策のAuthenticityTokenですが、
JavaScriptからこれを取得する方法のメモ。

js>>
$$('input[name="authenticity_token"]')[0].value
<<--

Ajax.Request等で呼び出す場合のお供に。

posted by genki genki on Sat 19 Apr 2008 at 09:43 with 0 comments

急に必要になったので作りました。

js>>
javascript:void(alert(document.getElementById('wys_frame').contentDocument.body.innerHTML.replace(/<.*?>|\s+/g, '').length))
<<--

自分が使えれば十分だったのでFirefoxのみ動作確認。
こういうとき、FlashではないAjaxアプリの便利さを実感しますね。

追記

やっぱり毎回Bookmarkletを起動するのが面倒になったので、
document.titleに2秒間隔で文字数を表示するバージョンを作りました。

js>>
javascript:void(clearInterval(window.gdocs_counter),window.gdocs_counter = setInterval(function(){var s=document.getElementById('wys_frame').contentDocument.body.innerHTML.replace(/<.?>|\s+/g, '');document.title = document.title.replace(/\s([.*?])?$/, [' [', s.length, ' chars]'].join(''));}, 2000))
<<--

posted by genki genki on Sun 23 Mar 2008 at 22:10 with 1 comment

なんだかA要素の直後の空白が無くなってしまいますね。

Windows用Safariのバグかと思ったら、Macでも同じ挙動でした。
とりあえず、
以下のように無理やりA要素の後にテキストノードを詰め込むことで対処。

js>>
var spacer = document.createTextNode(' ');
element.parentNode.insertBefore(spacer, element.nextSibling);
<<--

posted by genki genki on Mon 10 Mar 2008 at 13:23 with 0 comments

ちょっと必要になったので、
タグや空白を無視して、ある文字列の中から、
指定した文字列がマッチする範囲を計算するJavaScript
を書いてみました。

js>>
/* (C) Genki Takiuchi. New BSD License */
var findSelection = function(html, sel){
var chars = html.split(''), sels = sel.split('');
var start = 0, end = 0, step = 0, tag = false;
var cur = function(){return chars[end]};
var parse = function(){
switch(cur()){
case '>': if(tag) tag = false; return go();
case '<': if(!tag) tag = true; return go();
case '\n': return go();
case ' ': return go();
case '\t': return go();
default: return tag ? in_tag() : out_tag();
}
};
var go = function(){return(chars[end++] ? parse:reject)()};
var in_tag = function(){return go()};
var out_tag = function(){
return(cur() == go_sel() ? match:not_match)()
};
var not_match = function(){step = 0; return go()};
var match = function(){
if(step == 1) start = end;
return(sels[step] ? go:accept)()
};
var accept = function(){return [start, end + 1]}
var reject = function(){return [0, 0]};
var go_sel = function(){
var s = sels[step++];
return white_space(s) ? go_sel() : s
};
var white_space = function(c){
return c && c.match(/[\s\n]/)
};
return parse();
};
<<js

使い方は、こんな感じ。

js>>

findSelection('hello, world!', 'llo, world')
[2, 15]
<<js

選択範囲を取得して、選択している領域をRangeを求めるために作りました。
selに指定した文字列にマッチする箇所が複数ある場合は、
最初にマッチした場所のRangeを返します。

posted by genki genki on Sun 9 Mar 2008 at 10:54 with 0 comments

jRails
プラグインは、RailsアプリケーションのデフォルトJavaScriptライブラリである
prototype.js
+
script.aculo.us
の環境から、
jQuery
を使うようにするためのRailsプラグインです。

プラグインをインストールする方法は、通常のRailsプラグインと同様です。

sh>>
% ./script/plugin install http://ennerchi.googlecode.com/svn/trunk/plugins/jrails
<<sh

インストールすると、jQuery関係のJavaScriptファイル郡が
public/javascripts以下にコピーされます。

あとは、jRailsプラグインがRailsのJavaScriptヘルパーをjQuery対応に
してくれるので、そのままRailsアプリケーションを開発することができます。

当然ながら、prototype.jsやScript.aculo.us固有の関数は
利用できないので、既存のRailsアプリケーションをjQuery対応にする場合は、
そのあたりに注意が必要です。

See Also

posted by genki genki on Sat 1 Mar 2008 at 10:51 with 0 comments

In prototype.js, Event.observe method is very useful.
But it is a bit inconvenient if you want to handle events only once such as an initialization.
I have often encountered such situation, so I wrote a small utility function being as follows.

js>>
Event.observeOnce = function(element, event, observer){
var handler = function(){
Event.stopObserving(element, event, handler);
return observer.apply(null, $A(arguments));
};
Event.observe(element, event, handler);
};
<<--

The usage is same to Event.observe.

js>>
Event.observeOnce(document, 'dom:loaded', function(){
/* some code goes here */
});
<<--

It may be useful if you copy this into public/javascripts/application.js for Rails applications.

posted by takiuchi takiuchi on Thu 28 Feb 2008 at 17:23 with 0 comments

prototype.jsのEvent.observeは非常に便利なのですが、
初期化処理など、一度だけイベントの処理したい場合にはちょっと不便です。
度々そのような処理を行う機会があったので、以下のような
一度だけイベントをハンドルする関数を作ってみました。

js>>
Event.observeOnce = function(element, event, observer){
var handler = function(){
Event.stopObserving(element, event, handler);
return observer.apply(null, $A(arguments));
};
Event.observe(element, event, handler);
};
<<--

使い方は、通常のEvent.observeと同様です。

js>>
Event.observeOnce(document, 'dom:loaded', function(){
/* some code goes here */
});
<<--

Railsアプリケーションであれば、public/javascripts/application.js
あたりに置いておくと便利かもしれません。

posted by genki genki on Thu 28 Feb 2008 at 17:04 with 0 comments

少し前になりますが、このブログでHatenaStarを使えるようにしました。
記事の右下の署名のところに表示されています。

このブログシステムでは、デフォルトの挙動だと、タイトルの右側に出てしまうので、以下のようなカスタムローダを使っています。

js>>
document.observe('dom:loaded', function(){
Hatena.Star.EntryLoader.loadEntries = function(){
return #{entries.to_json}.map(function(entry){
var star = $(['article_star_', entry[2]].join(''));
return {uri: entry[0], title: entry[1],
star_container: star, comment_container: star};
});
};
});
<<--

loadEntriesはElementオブジェクト含む配列のリストを返す
必要があるのですが、これはPrototype.jsの$()関数のように、
ElementでもElement IDの文字列でも両方
受け取れるようにしたら、もっと便利かも。

posted by genki genki on Fri 22 Feb 2008 at 03:43 with 0 comments

SafariかFirefoxで閲覧することが多いので気がつくのが遅れましたが、
この記事
をPostして以降、IE6でレンダリングが乱れる状態になっていたようです。

原因は、はっきりとはわかっていないのですが、
埋め込まれていたSWF(現在はリンクだけになっています)の初期化と、
JavaScriptの実行が干渉していた模様。
JavaScriptの実行とFlash Playerの実行の順序やタイミングについては、
ブラウザごとに微妙に違ったりしているようで、なかなか良くわかりにくい
ところですね。

何も考えずに
SWFObject
などを使って、JavaScript側から明示的にタイミングを指定して
SWFを初期化するのが良いのかも。

posted by genki genki on Sun 17 Feb 2008 at 05:14 with 0 comments

This is a memo of an idea that I'd wanted to do for about a year since my starting to write some codes for a comet server.

By using Comet, JavaScript tests by various browsers can be automated. It's sure to be able to do even by any browsers to say nothing of the Firefox with MozRepl.

I've said in each place about this, but it has been hard to make a time to touch it, because too many exciting ideas struggled in my brain to make my hands type them out.

I wrote this entry with a hope that it might be going to be done by someone else.

posted by genki genki on Sat 16 Feb 2008 at 06:11 with 0 comments

前からやりたかったアイディアのメモ。
Cometを使えばMozReplみたいなのをFirefox以外のブラウザでもできるはず。
それを使って各種ブラウザでのテストを自動化する。

結構各所で言ってるんだけど、なかなか手がつけられない。
最近手がつけられないアイディアが多くなってきたので、
誰かが作ってくれるかもしれない希望を込めて書いておきます。

posted by genki genki on Fri 15 Feb 2008 at 17:38 with 0 comments
JavaScriptレベルでSafeな実行環境(Sandbox)を作る方法について、 調べたものをメモ。 [**自由にアクセス制御可能なJavaScriptサンドボックスを作る**](http://blog.tkmr.org/tatsuya/show/407-javascript)
自サイト上でユーザにJavaScriptを(限定的に)許可したい
例えば、はてなダイアリー等でユーザがブログパーツを張れるよう許可するとか。但し
  • document.cookie等、危険な機能は操作不能にする
  • あくまでサイト上でJSを許可する(iframeは不可)
やはり動機に関してはこのへんですね。 [**[Facebook] FBJSでFacebookアプリ内でJavaScriptを利用**](http://kawa.at.webry.info/200708/article_3.html) >Facebook では、FBML という HTML サブセットの独自言語でサードパーティの開発者が誰でもアプリケーションを作成できる。FBML では当初は
posted by genki genki on Thu 14 Feb 2008 at 02:31 with 0 comments

javascript_include_tagstylesheets_link_tag
:cache => trueオプションは、複数のassetsファイルを
ひとつのファイルにまとめる事で、サーバへのリクエスト
数を減らすことができる機能です。

何度か実験してみたところ、生成されたキャッシュファイルを
削除して更新するためには、単純にファイルを削除するだけ
ではだめで、APサーバのプロセスを再起動する必要があるようです。

このためには、./script/process/reaper -a graceful
を使う必要があります。タイプするのが面倒なので、
Rakeタスクを作ってみました。

lib/tasks/cache.rake

rails>>
namespace :tmp do
namespace :cache do
desc 'Delete cached asset files'
task :update do
patterns = [
'public/stylesheets/cached_*.css',
'public/javascripts/cached_*.js']
Dir.glob(patterns).each do |path|
rm_rf path
puts "deleted: #{path}"
end
./script/process/reaper -a graceful 2>&1 > /dev/null
puts "script/process/reaper -a graceful"
end
end
end
<<--

生成されるキャッシュファイルの名前を
:cache => "cached_#{controller.controller_name}"
と指定しているため、こんな感じになります。
デフォルトでは、all.cssall.jsとなりますので
適宜読みかえてください。

posted by genki genki on Sat 12 Jan 2008 at 23:09 with 0 comments

RJSテンプレートは、RubyコードからJavaScriptコードを生成
するための仕組みです。
今回は、RJSテンプレートの中でJavaScriptの条件分岐を
簡潔に記述するために、PrototypeHelperを拡張する方法を紹介します。

以下のようなファイルを作成して、config/initializersの下に
設置します(Rails 2.0以降の場合)

prototype_helper_ext.rb

rails>>
module ActionView
module Helpers
module PrototypeHelper
class JavaScriptGenerator
def if(condition, &block)
page << "if(#{condition}){"
block.call if block
page << '}'
end

    def elsif(condition, &block)
      page << "else if(#{condition}){"
      block.call if block
      page << '}'
    end

    def else(&block)
      page << "else{"
      block.call if block
      page << '}'
    end
  end
end

end
end
<<--

これによって、こんな感じに条件分岐を記述できるようになります。

rails>>
render :update do |page|
page.if "$$('#posts .post').length == 0" do
page.remove 'posts'
end
end
<<--

最初から用意されててもいい気がする。

posted by genki genki on Sat 5 Jan 2008 at 16:49 with 0 comments

うーむ、この挙動の変更には驚いた。

今までなら、

js>>

a = $H()
Object _object=Object

a.test = 'foo'
"foo"

a.inspect()
"#<Hash:{'test': 'foo'}>"
<<--

という挙動だったのだけれど、version 1.6以降、最後の結果が

js>>

a.test = 'foo'
"foo"

a.inspect()
"#Hash:{}"
<<--

と、空っぽのままになってしまう。
Hashへの要素の追加は、以下のようにgetsetを使わなくては
ならないようだ。

js>>

a.set('test', 'foo')
"foo"

a.inspect()
"#<Hash:{'test': 'foo'}>"
<<--

これは結構影響が大きな変更なんじゃないかな・・・。

####追記

Rails 2.0からprototype.js 1.6が使われるようになったから、
今頃気がついたわけですね。

JavaScriptライブラリ「Prototype.js 1.6.0」正式版リリース(ライブラリ)

Elementsは「new Element(...)」というシンタックスで生成できるようになり、Element#insert、Element#select、 Element#wrapといったAPIが提供された。また、Hashに関するAPIが変更され、Hash#get、Hash#setを使う必要がある。

posted by genki genki on Wed 26 Dec 2007 at 17:49 with 0 comments

いろんな環境でよく使うので、指に覚えさせています。

javascript>>
javascript:void(window.resizeTo(1024,768))
<<--

それはさておき、アドレスバーからJavaScriptを実行する
時に、画面遷移しないように使ったりする、このvoid
が気になったので、ちょっと調べてみました。

voidはメソッドではなく演算子

一見メソッドを呼び出しているように見えますが、typeof
等と一緒で演算子です。

Core JavaScript 1.5 Guide:Operators:Special Operators#void

void 演算子は値を返さずに評価する式を指定します。expression は評価する JavaScript の式です。式の周りの括弧はあってもなくてもかまいませんが、使用したほうが見た目はいいです。

したがって、

javascript>>
void window.resizeTo(1024, 768)
<<--

と書いても良いわけですね。

posted by genki genki on Fri 14 Dec 2007 at 10:11 with 4 comments

ドメイン境界を越えてjsで通信する方法。

Introducing CrossFrame, a Safe Communication Mechanism Across Documents and Across Domains

たぶんShootingStarで使ってる方法と同じものだと思う。

posted by genki genki on Wed 28 Nov 2007 at 16:11 with 0 comments