[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
ラベル DOM の投稿を表示しています。 すべての投稿を表示
ラベル DOM の投稿を表示しています。 すべての投稿を表示

2009年9月27日日曜日

JavaScript でマウススクロールしたときのイベント処理

1. マウススクロールに応じたイベント処理

JavaScript で生成した DOM Element を、マウススクロールに合わせて移動させたい。

位置を固定する

要素を固定するには、CSS の position 属性を absolute にする。これにより、イベント処理をしなければ、マウススクロールしても固定した位置に留まる。

スクロール量を知る

JavaScript で、スクロール量を知るには、window オブジェクトの scrollY プロパティを利用する。scrollY は、

文書が垂直スクロールされているピクセル数を返します。

イベントの設定

エレメントにイベントを設定するには、

を使う。このメソッドの使い方は、以下を参照。

マウスホイールの動きに対応するには、 Gecko-Specific DOM Events – MDC の  DOMMouseScroll を使う。

The DOMMouseScroll event is sent when the mouse wheel is moved. The target of this event is the element that was under the mouse pointer when the mouse wheel was scrolled, similar to the click event.

これにより、マウスホイールをスクロールさせたときに、直下にある要素にイベントが伝わる。

イベントの要素への伝わり方は、以下を参照。

イベントハンドラからW3C DOMイベントモデルへ

まずドキュメントツリーの上から下に向けてイベントが伝搬します。これをキャプチャー・フェーズと呼びます。

次に目的の要素にイベントが伝搬しますが,これをターゲット・フェーズと呼びます。ちなみに,この目的の要素のことを,ターゲットノードと呼びます。

しかし,ここで終わりではなく,さらに今度はターゲットノードからドキュメントツリーの上に向けてイベントが伝搬します。この段階をバブリング・フェーズと呼びます。

このように,W3C DOMイベントモデルでは,ドキュメントツリーの上からイベント発生源まで伝搬し,そして,今度は逆の方向に伝搬するという概念を持っています。イベントは,そのイベントが発生した部分だけでしか認識されないわけではない点に注意してください。

 

2. 例

HTML の div 要素を作成し、マウススクロールに合わせて移動させる。

var newElem = document.createElement("div");
var p = document.body.firstChild;
newElem.innerHTML = "挿入";
p.parentNode.insertBefore(newElem, p);

// 初期の位置
var x = 30, y = 30;
with(newElem.style){
    // 大きさ
    width = "100px";
    height = "100px";
    // 位置
    position = "absolute";
    top = y.toString() + "px";
    left = x.toString() + "px";
    // 背景の色
    backgroundColor = "red";
    // 透過度
    opacity = "0.7";
}

// マウススクロールに対するイベント処理
addEventListener("DOMMouseScroll", function(e){
    with(newElem.style){
        top = (y + scrollY).toString() + "px";
        left = (x + scrollY).toString() + "px";
    }
}, false);

 

数値を文字列に変換

数値を文字列に変換するメソッドは toString

全てのオブジェクトは toString メソッドを持ち、オブジェクトが文字列値として表されるべきときや、文字列が期待される構文で参照されたときに自動的に呼び出されます。

toString - Number オブジェクトのメソッド によると、

指定された Number オブジェクトを表す 文字列を返します。

JavaScript で XML を読み込む

DOMParser で XML を DOM ツリーに変換する

Firefox で XMLを解析し、DOM ツリーを生成するには、DOMParser を使う。

Parsing and serializing XML – MDC によると、

Mozilla は現時点では W3C の Document Object Model Load and Save に対応していない ( bug 155749) ので、DOM ツリーをシリアライズおよびデシリアライズするには次の Mozilla 専用のインターフェイスを使うのが最も簡単です。…

  • DOMParser - XML を文字列から DOM ツリーにパースする

例えば、「名前」と「年齢」を含む XML から、名前のみを抽出する。

var theString = '<persons>' +
	'<person><name>太郎</name><age>20</age></person>' +
	'<person><name>次郎</name><age>25</age></person>' +
	'<person><name>花子</name><age>30</age></person>' +
	'</persons>';
var parser = new DOMParser();
var dom = parser.parseFromString(theString, "text/xml");
var persons = dom.getElementsByTagName("person");
for (var i=0; i<persons.length; i++){
	console.log(persons[i].getElementsByTagName("name")[0].textContent);
}

Firebug のコンソールで実行した結果は、

太郎
次郎
花子

XML に対して、HTML で要素を取得するときに使う getElementsByTagName メソッドを利用している。これは、getElementsByTagName メソッドが定義されている Document インターフェイスは、HTML と XML を表現したものであるため。

2009年9月26日土曜日

JavaScript で半透明な固定した領域を生成する

1. CSS で要素を固定し、半透明にする

JavaScript で半透明な固定した領域を生成したい。

要素の位置を固定するには、HTML において、CSS の position プロパティを fixed にする。

絶対的な位置に固定配置する によると、

「position:fixed」と距離を指定するプロパティは、指定された要素を絶対的に移動させて配置しますが、その要素はウィンドウ上のその位置に固定されて、スクロールしても位置が変わらなくなります

要素を半透明にするには、CSS で filter プロパティを設定する。

IE・Firefox・Opera・Netscape・Safariで表示可能な半透明CSS/Opacityテクニック - WEBデザイン BLOG によると、

以下のコードでIE・Firefox・Opera・Netscape・Safariで同等表示がえられます。

  filter: alpha(opacity=25);
  -moz-opacity:0.25;
  opacity:0.25;

 

2. JavaScript で要素を生成し、CSS のプロパティを設定する

JavaScript で DOM Element を生成し、CSS を設定する。

DOM Element を生成する方法は、以下を参照。

CSS を設定するには、element.style を利用する。

var newElem = document.createElement("div");
var p = document.body.firstChild;    // この要素の前に newElem を挿入 
newElem.innerHTML = "挿入";
p.parentNode.insertBefore(newElem, p);

with(newElem.style){
    // 大きさ
    width = "100px";
    height = "100px";
    // 位置
    position = "fixed";
    top = "30px";
    left = "30px";
    // 背景の色
    backgroundColor = "red";
    // 透過度
    opacity = "0.7";
}

 

関連記事

2009年9月17日木曜日

JavaScript で特定の要素の前に要素を挿入する

1. DOM で要素を作成し、挿入する

例えば、JavaScript を使い、body 要素の直後に div 要素を挿入したいとする。

document – MDC のメソッドによると、

element のメソッドには、

これらを使って、コードを書く。

var newElem = document.createElement("div");
newElem.innerHTML = "挿入";
document.body.insertBefore(newElem, document.body.firstChild);

 

element.parentNode

追記 (2009.9.26) : 4.7. Inserting content before an element [Dive Into Greasemonkey] では、親要素を指定するのに、element.parentNode を利用している。

var newElem = document.createElement("div");
var p = document.body.firstChild;   // この要素の前に挿入したい
newElem.innerHTML = "挿入";
p.parentNode.insertBefore(newElem, p);

 

iframe 要素を挿入

div 要素の代わりに iframe 要素を挿入したい場合は、

var frame = document.createElement("iframe");
frame.src = "https://developer.mozilla.org/en/Gecko_DOM_Reference";
frame.width = 500;
frame.height = 500;
document.body.insertBefore(frame, document.body.firstChild);

当初、document のプロパティを見て、要素の中身を書くために

を利用すれば良いと考えた。しかし、Node.textContet には問題がある。

IEではtextContentは使えないので、この命令を使う場合にはブラウザのタイプ判定による場合分けが必要。

(innerTextとtextContent - javascript 覚え書き日記 - g:javascript より)

Node.textContent の代わりに、innerHTML を利用した。

タグの中身を取得するにはinnerHTMLを使う。

他に整形テキストを取得するinnterTextと、タグ自身を含む文字列を取得するouterHTMLがあるが、結論から言うとこの2つはFireFoxでは利用できない。innerHTMLのみが共通仕様。他にも微妙に違いがある。

(innerHTMLとか(IEとFireFoxの差異) - perl 覚え書き日記 - Hatena::Group::Perl より)

 

2. jQuery で要素を生成し、挿入する

同じことを jQuery を使って書きたい。

要素を追加するために after(content) を利用する。

after(content)

各要素の後ろにコンテンツを挿入する。

引数
content

String,Element,jQuery

追加する文字列、DOM ElementおよびjQueryオブジェクト

追加する内容は、文字列で指定する。 DOM Element でも指定できるということは、先ほどのように createElement メソッドを使って生成したものを指定できるようだ。

$(document).ready(function(){
	$("body").after("<div>挿入</div>");
});

iframe 要素を追加するには、

$(document).ready(function(){
	$("body").after('<iframe ' +
		'src="https://developer.mozilla.org/en/Gecko_DOM_Reference"' +
		'width="500" height="500" />');
});

2008年9月4日木曜日

JavaScript でキー入力に応じて HTML の要素の値とスタイルを変化させる

JavaScript でブラウザのウィンドウのリサイズに合わせて HTML の要素の値を更新 のつづき

1. JavaScript によるHTML要素の動的な変化

JavaScript を用いて、HTML の要素を動的に変化させたい。

下図に示すように、左上のフォームのテキストフィールドに、ユーザがキーボードで入力したのに応じて、右下のフォームのフィールドの数値をインクリメントする。

同時にフィールドの下にある HTML の要素の幅を広げる。

080904-001-vert

キーの入力に対応させるには、keydown, keypress, keyup のイベントハンドラを利用する。

 

ソースコード
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional/EN">
<html>
  <head>
    <title>increment</title>
    <meta http-equiv="content-type" content="text/html; charset=UTF-8">

    <style type="text/css">
    <!--
    #frm2{ text-align: center;}
    #frm2 .bar{ margin: 0px auto; }
    .bar { width: 0px; }
    #abar{ background-color: #fbb;}
    #bbar{ background-color: #bfb;}
    #cbar{ background-color: #bbf; }
    
    -->
    </style>

    <script type="text/javascript">
    <!--
    var counter = 0
    /* 指定された名前のフォームの要素の値をインクリメントする */
    function increment(name){
        stmt = 'document.forms["frm2"].' + name + '.value = counter++;';
        eval(stmt);
        incWidth(name + "bar");
    }
    
    /* 指定された id の要素の幅を広げる */
    function incWidth(id){
        width = document.getElementById(id).offsetWidth;
        width++;
        document.getElementById(id).style.width = width + 'px';
    }
    //-->
    </script>

  </head>
  <body 

    <form name="frm">
        <!-- 文字を入力するフィールド -->
        <input type="text"
                    'a')"
                    'b')"
                    'c')" />
    </form>
    
    <!-- 上のフィールドに入力された文字数に応じて表示が変化する -->
    <form id="frm2" name="frm2">
        <input type="text" name="a" />
            <div class="bar" id="abar">&nbsp;</div>
        <input type="text" name="b" />
            <div class="bar" id="bbar">&nbsp;</div>
        <input type="text" name="c" />
            <div class="bar" id="cbar">&nbsp;</div>
    </form>

  </body>
</html>

 

2. HTML 要素の幅を取得する

JavaScript で HTML の要素の幅を取得する方法は、

を参照。以下で述べる DOM の一種。

 

3. eval() 関数で実行時に評価する

eval() 関数は、eval – MDC によると、

Evaluates a string of JavaScript code without reference to a particular object.

ただし、EfficientJavaScript - Dev.Opera - 効率的な JavaScript の「eval と with は隔離しよう」の説明には、次のように述べられている。

これらの構文は性能への影響がとても大きいため, 利用は最小限に留めたい.

追記(2008.9.4) : 上記の eval() 関数を使っている部分は、 JavaScripter さんに教えていただいた書き方をすれば必要なくなる。

追記 (2009.10.3): JavaScript: The Good Parts (p129) 「付録B 悪いパーツ, B.3 eval」の「添え字記法」を参照。

 

4. HTML Form Element

DOM により要素にアクセスする

HTML の要素を取得するには、

document.getElementById(“id名”)

のように、 DOM で定義されているメソッドを経由して取得する。

What is the Document Object Model? によると、

The Document Object Model (DOM) is an application programming interface (API) for valid HTML and well-formed XML documents.

DOM とは、キチンとした形の文書に対して、その要素にアクセスするための API を定義したもの。

 

forms により要素にアクセスする

HTML のフォームの要素にアクセスするのに 、

document.forms[0].名前

と書くことができる。これは先ほどの要素へアクセスする方法とは違って見える。

Gecko DOM Referenceelement によると、

While these interfaces are generally shared by most HTML and XML elements, there are more specialized interfaces for particular objects listed in the DOM HTML Specification—for example the HTML Table Element and HTML Form Element interfaces.

getElementById() は一般的な DOM であるのに対して、document.forms[] は HTML に特有な方法。

forms とは、Document Object Model HTML によると、

forms of type HTMLCollection, readonly
A collection of all the forms of a document.

HTMLCollection とは、1.5. Objects related to HTML documents によると、

An HTMLDocument is the root of the HTML hierarchy and holds the entire content. Besides providing access to the hierarchy, it also provides some convenience methods for accessing certain sets of information from the document.

つまり、form は要素にアクセスしやすくするために定義されている。

以下の中で forms が定義されている。

Firebug の DOM タブにおいて document を表示させると、上記に定義されているものが表示される。

080904-004-horz

Firebug の表示は長くて、まともに見たことがなかったけれど、この際チェックしておこう。 (@_@;)