#jquery

@IT連載:jQuery逆引きリファレンスの第二回のテーマは属性&コンテンツです。

目次は以下になります。

* 属性値を取得するには?

* 属性値を設定するには?

* 複数の属性値をまとめて設定するには?

* 関数の結果によって動的に属性値を設定するには?

* 属性値を削除するには?

* スタイル・クラスを追加/削除するには?

* スタイル・クラスが適用されているかを判定するには?

* スタイル・クラスの適用/解除を交互に行うには?

* 要素に適用されたスタイル情報を取得するには?

* 要素に特定のスタイルを適用するには?

* 複数のスタイル・プロパティをまとめて設定するには?

* 要素の表示位置を取得するには?

* ページのスクロール位置を取得/設定するには?

* 要素の高さや幅を取得するには?

* 要素の高さや幅を設定するには?

* 要素のテキストを取得するには?

* 要素のテキストを設定するには?

* フォーム要素の値を取得/設定するには?

勉強メモ

text()とhtml()の違い

(1)取得する対象

 要素セット(jQueryオブジェクト)が複数の要素を含んでいる場合、htmlメソッドは先頭要素の内容だけを取得しますが、textメソッドはすべての要素の内容を結合したものを取得します。

(2)取得する内容

 名前のとおり、htmlメソッドは要素の内容をHTML文字列として取得しますが、textメソッドは純粋なテキストだけを取得します。

(3)対応する形式

 textメソッドはHTML/XMLいずれの形式でも動作しますが、htmlメソッドはHTML(XHTMLを含む)形式でしか動作しません。このサンプルでは扱っていませんが、textメソッドをXML形式で利用する方法については、あらためてAjax編で紹介する予定です。

https://www.atmarkit.co.jp/fdotnet/jqueryref/02attribute/attribute_16.html
height(val)、width(val)

引数valには数値、もしくは「em」や「%」などの単位付きの数値を指定できます(単なる数値の場合はピクセル値として認識します)。

要素の高さや幅を取得するには?

- height()、width()、innerHeight()、innerWidth()、outerHeight()、outerWidth()

関数paddingborder-widthmargin
height、widthxxx
innerHeight、innerWidthoxx
outerHeight、outerWidthoox
outerHeight、outerWidth(trueooo

関数の結果によって動的に属性値を設定するには?

- attr(name, fnc) -

コールバック関数の戻り値を用いて設定。

```javascript $(function() { $('li > img').attr( 'src', function(index) { return "http://www.wings.msn.to/books/" + this.id + "/" + this.id + "_logo.jpg"; }); }); ```

#jquery

今までjQueryを使ってきたtipsをメモします。

Tipsの定義とおり知っていればちょっと便利になるけど、

知らなくても特に問題ないですね。

ただしlive関数においてはすべてのイベントに有効じゃないのは

知っておいてほしいです。

live関数

liveはすべてのイベントに対応していない。

サポート

click, dblclick, mousedown, mouseup, mousemove, mouseover, mouseout, keydown, keypress, keyup

非サポート

blur, focus, mouseenter, mouseleave, change, submit


ajax関数のurlパラメータ

AJAXのURLではセレクタも併用できる。セレクタによりあるページの一部だけを読み込むことができる。

こんな形です:"url #some > selector"

デフォルトは"body>*"のセレクタが適用されていますよ。

```js $("#links").load("/Main_Page #jq-p-Getting-Started li"); ```

:has(selector)フィルタ

:has(selector)は持ってるすべての子要素に対して動作してる

divい対して:hasフィルタを使うと、p要素までフィルタが走る

```html
span ...

p..

```

属性フィルタの組み合わせ

[filter][filter]……のように複数を連続して記述することもできます。この場合、すべての属性フィルタに合致する要素だけが取り出されます。

htmlの組み立て

ハードコードで書く
```js $(select).append(""); ```
jQueryの関数を用いて書く
```js $(select).append($('
#jquery

jQueryのfocus()はデフォルトのフォーカス動作とそのエレメントにバインドされたイベントが実行されます。

しかしIE8とFirefoxではこのfocus()の動作が多少違います。

現象

例えば複数のinput要素があって、それぞれfocusイベントとblurイベントがバインドされたとします。

focus()を実行する前はelem1にフォーカスしていて、要素$(‘elem2’).focus()を実行すると

  • Firefox 3.5.5ではelem1のblurイベントが実行した後に、elem2のfocusイベントが実行する
  • IE8ではelem1のblurイベントは実行されますが、elem2には2回フォーカスするように動作します。

つまり下記の動きです。

  1. elem1のblurイベント
  2. elem2のfocusイベント
  3. elem2のblurイベント
  4. elem2のfocusイベント

普通に考えたらFirefoxの動きが正しいはずですよね。 上記の3と4は余計な処理になります。

サンプルコード

$("form :input").bind("focus", function() {
  $(this).css("background-color", "gray");
  // ログを出力
    $("#result").append($(this).get(0).id + " focus event triggered.<br>");
  }).bind("blur", function() {
  $(this).css("background-color", "");
  // ログを出力
    $("#result").append($(this).get(0).id + " blur event triggered.<br>");
  });
$("#foo").focus();
setTimeout(focusBar, 3000);
function focusBar() {
  $("#" + document.activeElement.id).trigger('blur');
  $("#bar").focus();
};
Foo<input id="foo" type="text" />
Bar<input id="bar" type="text" />
<div id="result"></div>

先にfooテキストエリアにフォーカスしてくささい。 3秒後にbarテキストエリアにfocus()メソッドでフォーカスします。 その時の出力ログを見てください。

回避策

まだいい方法はつかんでません。

Googleで検索すると似たようなものはありましたが、

回避策はまだないようです。

[jQuery] Focus event firing twice in Internet Explorer

#webservice

前回の記事の続きとしてJSONPを勉強しました。

XMLHttpRequestはセキュリティ上の制限により、

クロスドメインの通信ができないです。

でもウェブサービスのようなどうしてもクロスドメインで通信したい場合があります。

その時の手段してあげられるのがこのScriptタグです。

(他の手段としてiframeやflashとリバースプロキシがあるそうです)

JSONPとは

JSON with paddingの略

Javascriptの非同期通信でよく使われるXMLHttpRequestオブジェクトにはSame-Originポリシーが存在し、クロスドメインアクセスができない。

一方,scriptタグを用いると,ドメインの異なるサーバに置いているスクリプトファイルを読み込むことができる。この仕組みを利用し、scriptタグのsrcに、データを取得できるAPIのURLを指定し,ドメインの異なるサーバからデータを取得する仕組みの総称として、JSOPという言葉が使われる。JSONP用のAPIでは、関数名+取得データをjson形式で表記して引数とした形式(例.callbackFunc({id:1000,name:aaa}))のレスポンスが一般的で、APIから返されるコールバック関数と同じ名前の関数(callbackFunc(jsonData))をクライアント側で定義しておけば、データを読み込んだ際にそのコールバック関数が実行される。動的にscriptのDOMを生成することで、非同期でデータが取得できるようになる。

ただし、Same-Originポリシーが存在しないため、機密情報をAPIに含める際には十分な注意が必要である。

動作原理

やはりソースコードで読むほうが早いだと思います。

以下gihyo.netからのサンプルコードです。

<html>
  <body>
    <script>
      function callback(x) {
        // コールバック関数を定義
        alert(x["name"]);
      }
    </script>
    <script src="http://mail.example.com/json.dat"></script>
  </body>
</html>

データ提供サーバ側が用意したJSON

json.datの中身

callback( { "name" : "Fukumori" } );

簡単まとめ

要はクライアント側で先にデータを扱うコールバック関数を定義

その名はデータの提供側とのコールバック関数名と一致する必要がある

scriptタグでデータ提供サーバのデータをインポート

すると先に用意したコールバック関数が走ってデータを処理する

もっと詳しい動作原理とセキュリティはgihyoの特集を参照してください。 とても分かりやすいです。おすすめ!

第3回 JSONPでのクロスドメインアクセス:ここが危ない!Web2.0のセキュリティ|gihyo.jp … 技術評論社

jQueryでJSONPを使う

jQueryのAjaxメソッドには$.getJSONがあります。

このメソッドはjQuery1.2からJSONPも対応したようです。

As of jQuery 1.2, you can load JSON data located on another domain if you specify a JSONP callback.

利用方法はurlの最後に”?”付きのコールバックパラメータを追加することです。

例えば”example.com?callback=?”こんな感じです。

callbackの値は指定しなくてもよいみたい、

jQueryが自動で変換してくれます。

ただしコールバックのパラメータ名はデータ提供側によって異なるかもしれません。

例えばヤフーPipesは”_callback=?”を要求してるそうです。

#movie

</param></param></embed> D

If you are a Man, no matter you are lonely now, or married.

You should watch this, trust me.

It's about freedom, wild, excited.

I think English is more powerful than Japanese this moment,

I really love it.

You, should watch this, seriously.

And if you like it, you should check the soundtrack CD below too.

It's really cool.

The Hangover

The Hangover

#ie javascript

経緯

iframeで動的に画面を読み込む際URL不正などによる通信エラーが起こした場合の

エラーハンドラを追加したかったので判断するロジックが必要でした。

わざと誤ったURLを渡して検証しましたが、以下のコードはだめでした。

// documentがnullかと思ってそれで判断しようとしたんです。
if (this.contentWindow.document) {}

現象

あるプロパティは存在しているのに、アクセスができない。コードで書くと

// プロパティがオブジェクトに存在するかを判断
// ここはアラーとが出した、つまり存在したってこと
if ("aProperty" in obj) alert('obj has aProperty');
// 次にそのオブジェクトにアクセスしようとすると
// エラーになった
obj.aProperty

IE8の開発ツールで見たら「アクセスが拒否されました」と書いてある。

エラーをcatch

判断のロジックをtry-catch文に書けばいいです。

try {
  this.contentWindow.document;
} catch (e) {
  if (e.number == -2147024891) {
    //アクセスが拒否されました。
    alert(e.message);
  } else {
    alert("別のメッセージ");
  }
}

参考サイト:http://sei.qee.jp/docs/freetalk/2009/02.html

#ie

開発においてローカルでいろいろテストすることが多いでしょう。

その時ブラウザを開くと「セキュリティ保護のため、このコンピューターにアクセスする可能性のあるスクリプトやActiveXコントロールを実行しないよう、IEで制限されています。オプションを表示するには、ここをクリックしてください」という警告がそのたびに出て、気分が悪くなっちゃいます。IEの[セキュリティ]タブをいじってもファイルはローカルなので、効きません。


解決方法

  • [マイコンピュータ内のファイルでのアクティブコンテンツの実行を許可する*]をチェックしIEを再起動(*がついてるので再起動は絶対必要とされている)

f:id:kinopyo:20091117012539j:image:right

f:id:kinopyo:20091117012540j:image

  • 「スクリプトを実行しても安全とマークされているActiveXコントロールのスクリプトの許可」をチェック

f:id:kinopyo:20091117012541j:image

バージョン情報

  • OS: Windows XP
  • IE: IE8

参考サイト:How to disable "ActiveX Control May Be Unsafe" popup - Stack Overflow