2011年11月29日火曜日

[JavaScript]要素のスタイル情報を取得する (window.getComputedStyle)

styleオブジェクトのプロパティ


インラインまたは動的に設定されるすべてのスタイルには、要素のstyleオブジェクトのプロパティからアクセスできます。
var position = elem.style.position

注意点としては、backgcounr-color のように、ハイフンが名前に含まれるプロパティについては、キャメルケースを使う必要があることです。('-' が減算演算子と解釈されてしまうため。)
var bgcolor = elem.style.backgroundColor;

また、上記の方法で取得できるのは、インラインで設定されたか、JavaScriptを使って動的に設定されたスタイル値だけなので、スタイルシートを使って設定されたスタイルにはアクセスできません。


スタイルの設定方法に関係なく、スタイルにアクセスする方法


スタイルシートを使って設定されたスタイルにアクセスするには、window.getComputedStyle()メソッドを使います。
このメソッドが返すのは、CSSStyleDeclaration オブジェクトで、オブジェクトのプロパティには、getPropertyValue()メソッドにプロパティ名を渡してアクセスします。このメソッドに渡すプロパティ名は、cssのプロパティと同じで、キャメルケースに変換する必要はありません。

※ getComputedStyle()メソッド古いIE(IE8よりも前)には実装されていないので、クロスブラウザ対応が必要になります。
var style = window.getComputedStyle(elem, null);
var bgcolor = style.getPropertyValue("background-color");

なお、getComputedStyle()メソッドは、document.defaultView からも呼び出せます。
var style = document.defaultView.getComputedStyle()


IE8では、要素のcurrentSytyle プロパティにアクセスしてスタイル値を取得します。
var style = elem.currentStyle

currentStyle オブジェクトのプロパティには、キャメルケースでアクセスします。
var bgcolor =  style["backgroundColor"];


サンプル(要素elemにスタイルシートで適用されているbackground-colorの値を取得する)


var style;
var bgcolor;
if (elem.currentStyle) { //クロスブラウザ対応
    style = elem.currentStyle;
    bgcolor =  style["backgroundColor"];

} else if (window.getComputedStyle) {
    style = window.getComputedStyle(elem, null)
    bgcolor = style.getPropertyValue('background-color');
}


取得されるスタイル値の優先順位


スタイルがインラインとスタイルシートを通じて設定されている場合は、インラインのスタイルが優先されます。
動的に設定されるスタイルは、インラインとスタイルシートで設定された値に関係なく、動的に設定されたスタイルが優先されます。


スタイルの設定


window.getComputedStyle()で取得できるオブジェクトは読み込み専用のため、JavaScriptでスタイルを動的に設定する場合は、要素のstyleオブジェクトのプロパティに直接セットします。(しつこいけどスタイル名はキャメルケース!!)
elem.style.backgroundColor = "#CCC";


まとめ


  • 要素のstyleプロパティからは、インラインまたは動的に設定されたスタイルのみアクセスできる。
  • 名前にハイフンが含まれるスタイルのプロパティ名は、キャメルケースに置き換えてアクセスする。
  • 設定方法に関係なく要素のスタイルを取得するには、window.getComputedStyle()メソッドを使う。(IE8以前はelement.currentStyle)
  • getComputedStyle() で取得したオブジェクトのプロパティには、getPropertyValue()メソッドを使ってアクセスする。

参照URL
window.getComputedStyle - MDN https://developer.mozilla.org/en/DOM/window.getComputedStyle
CSSStyleDeclaration - MDN https://developer.mozilla.org/en/DOM/CSSStyleDeclaration

参考文献
Javascript クックブック p252
JavaScriptクックブック
JavaScriptクックブック

2011年11月25日金曜日

[JavaScript] ブラウザで選択した文字列を取得

javascrpt を使って、ブラウザで現在選択されている文字列を取得する方法について確認してみます。

window.getSelection()で選択範囲を取得


windowオブジェクトのgetSelection() メソッドで、ブラウザで現在選択されている範囲をあらわす、Selectionオブジェクトが取得できます。

var selection = window.getSelection();


Selectionオブジェクトから選択された文字列を取り出すには、toString() メソッドを使います。

var selected_str = window.getSelection().toString();


なお、getSelection()メソッドはdocumentオブジェクトにも実装されているので、document.getSelection() としてもokです。


IE での対応(IE6 で確認)


IE ではwindow.getSelection()が実装されていないため、document.selectionプロパティを使います。このオブジェクトから文字列を取り出すには、createRange()メソッドを呼び出して返されるTextRange オブジェクトのtext プロパティにアクセスすればok です。


var selected_str = document.selection.createRange().text;


クロスブラウザ対応


クロスブラウザ対応としては、window.getSelection の有無で処理を分岐すればOK.

if (window.getSelection) {
    //IE 以外
} else {
    //IE
}

以上を踏まえて、「Shift key が押されたときに、選択されている文字列を表示する」プログラムを作成してみました。(動作はfirefox3.6, IE6 で確認しました。)

サンプルコード
<script type="text/javascript">
var win = window,
    doc = document; //グローバルオブジェクトをキャッシュ

win.onload = function(){
    var selected_str = '',
        SHIFT_KEY_CODE = 16;

    doc.onkeydown = function(evt){
        if (typeof evt === 'undefined') { //IE用にevent再設定
            evt = win.event;
        }

        if (evt.keyCode === SHIFT_KEY_CODE) {
            if (win.getSelection) {//クロスブラウザ対応
                selected_str = win.getSelection().toString(); //IE以外
            } else {
                selected_str = doc.selection.createRange().text; // IE
            }

            if (typeof selected_str !== 'undefined' && selected_str != '') {
                alert(selected_str);
            }
        }
    }
}
</script>

ここからさらに取得した選択文字列を 翻訳系 web API に渡すようにすれば、簡単な翻訳アプリなどに応用できそう!

まとめ


ブラウザの選択範囲の文字列を取得するには、

window.getSelection() メソッドを使う

IE ではdocument.selection.createRange().text でok

参照URL

window.getSelection - MDN https://developer.mozilla.org/en/DOM/window.getSelection

Selection - MDN https://developer.mozilla.org/en/DOM/Selection

selection Object http://msdn.microsoft.com/en-us/library/ms535869%28v=vs.85%29.aspx

TextRange Object http://msdn.microsoft.com/en-us/library/ms535872%28v=vs.85%29.aspx

2011年11月21日月曜日

[JavaScript] で要素の属性を取得する

基本はgetAttribute() / setAttribute() メソッド


setAttribute() / getAttribute() メソッドは、DOM標準、非標準を問わずすべての属性にアクセスできるため、要素の属性をset/get する時は常にこのメソッドを使うようにする。
var foo_id = document.getElementById("foo").getAttribute("id");

document.getElementById("foo").setAttribute("id", “new_id”);

class を扱う時の注意


例えばclass名を取得したい場合は、getAttribute("class") とすればよさそうだが、 IE7 ではgetAttribute("className") としないと、null が返されてしまう。(class属性はJavaScriptでアクセスするときの名前が変更されている属性のため)

ブラウザを問わず確実にclass名を取得するには、オブジェクトのclassNameプロパティに直接アクセスすればok。

//get
var foo_class = document.getElementById("foo").className;
//set
document.getElementById("foo").className = "newClass";

input要素の状態を表す属性


form のinput要素の状態を表す属性(disabled, checked など)についても、直接オブジェクトのプロパティにアクセスして設定,取得する。

var textbox = document.getElementById("textbox");
textbox.disabled = false;


jQueryの場合


jQuery では jQuery.attr() メソッドですべての属性にアクセスできる。
//get
var className = $("#foo").attr("class");
//set
$("#foo").attr("id", "newId");

class名をsetするときは、jQuery.addClass() メソッドを使う。
$("#foo").addClass("new_class" "other class");

まとめ


・要素の属性のget/setには、基本的に getAttribute() / setAttribute() メソッドを使う。

・例外的にclass名, formのinput要素の状態をget/setする際は、オブジェクトのプロパティに直接アクセスする。

・jQuery では、jQuery.attr() メソッドで要素の属性にアクセスする

参考文献:JavaScrip クックブック p251
JavaScriptクックブック
JavaScriptクックブック

2011年11月17日木曜日

[JavaScript] フォームの入力フィールドにオートフォーカスする

ページがロードされた時に、ユーザーIDや検索ワードなどの入力フィールドに自動的にフォーカスさせる方法について、javascriptとhtml5を使って確認してみます。
以下のサンプルhtmlについて、input id="focus_target" にオートフォーカスさせる場合を考えます。
htmlサンプル
<body>
<form>
<input type="text" id="focus_target" />
<input type="submit" />
</form>

<!-- 膨大なコンテンツ -->
<!-- 省略 -->
<!-- 膨大なコンテンツ -->
</body>

方法1. window のロードを待ってからfocus()メソッドを呼び出す


まず思いつく方法として、windowのロードが完了してから、要素のfocus()メソッドを呼び出す方法があります。
window.onload = function(){
    var target = document.getElementById("focus_target");
    target.focus();
}
ただしこの方法だと、ページのロード中にユーザーが別の入力フィールドフォーカスを移動させた場合、わざわざjavascriptが最初のフィールドにフォーカスが戻してしまうという、困った問題が発生する可能性があります。
なので、この方法はなるべく避けたいところです。
代替案としては、jQueryが使えるなら、
$(document).ready($("#focus_target").focus());
のようにdocumentのロード完了時にfocusすれば、ページ内のテキストがすべてロードされた時点でフォーカスが実行されますが、やはりサイズの大きなページや、遅いネットワークから接続している場合は、同じ問題が発生する可能性があります。

方法2.input要素の直下に<script>タグを挿入

上記の問題を回避する方法としては、自動フォーカスしたい<input>タグの直下に<script>タグを挿入する方法があります。
<body>
<form>
<input type="text" id="focus_target" />
<script>document.getElementById("focus_target").focus()</script>
<input type="submit" />
</form>
</body>
input要素がロードされた直後にfocus()を呼び出しているため、方法1. の問題は回避できます。

方法3.html5のautofoucs属性を適用する

HTML5では、すべてのフォームコントロールにautofocus属性が導入されました。
<input type="text" id="focus_target" autofocus />
html5のautofocusは単なるマークアップなので、すべてのブラウザで振る舞いが統一されます。ちなみにautofocus属性をサポートしていないブラウザは、単純にこれを無視するだけです。
以下の関数で,要素がautofocus属性を持っているか検証できます。
functiton supports_input_autofocus() {
    var i = document.createElement('input');
    return 'autofocus' in i;
}

まとめ


フォームの入力フィールドにオートフォーカスさせたい場合は、、

1. まずはhtml5のautofocus属性を設定しておき、autofocusをサポートしていない場合のみ、focus()を呼び出す
<body>
<form>
<input type="text" id="focus_target" autofocus />
<script>
if (!supports_input_autofocus()) {document.getElementById("focus_target").focus()};
</script>
<input type="submit" />
</form>
</body>

2. window の load が完了するのを待ってからfocus() するのはなるべく避ける

参考文献:入門 HTML5

入門 HTML5
入門 HTML5