JavaScript プログラミング講座

 

DataTransfer クラスについて

 


■ DataTransfer クラスについて


DataTransfer クラスは、ドラッグアンドドロップで利用します。
 
データを格納するための入れ物として使用します。
 
ドラッグアンドドロップについては、こちらで解説しています。
 

■ DataTransfer オブジェクトを取得する


DataTransfer オブジェクトを取得するには、DragEventdataTransfer プロパティを使用します。
 
ドラッグを開始した時に、DataTransfer オブジェクトを取得する

<html>
  <body>

    <div id="aaa" draggable="true" style="width:400px; height:300px; background:#fcc;"></div>

    <script type="text/javascript">
    <!--
	// "aaa" という ID 属性のエレメントを取得する
	var element = document.getElementById("aaa");

	// ------------------------------------------------------------
	// ドラッグを開始した時に実行されるイベント
	// ------------------------------------------------------------
	element.ondragstart = function (e){
		if(!e) e = window.event; // レガシー

		// DataTransfer オブジェクトを取得する
		var data_transfer = e.dataTransfer;

		// 出力テスト
		console.log(data_transfer);
	};

    //-->
    </script>

  </body>
</html>
 
 

 

データを格納する

 


■ドラッグ開始時に、DataTransfer オブジェクトを取得する

 
ドラッグを開始したか調べるには、ondragstart イベントを使用します。
 
ドラッグ時のイベントについては、こちらで解説しています。
 

■タイプ名を指定して、データを格納する


タイプ名を指定して、データを格納するには、setData() メソッドを使用します。
 
DataTransfer.setData("タイプ名" , "データ") :Void
第01引数 Stringデータのタイプ名を指定
第02引数 Stringデータを指定
戻り値 Voidなし
 
■第01引数(データのタイプ名)
 
格納するデータのタイプ名を指定します。
 
タイプ名ごとに、1つのデータを格納することができます。
 
複数のデータを格納するには、タイプ名を変更しながら、setData() メソッドを複数回実行します。
 
指定したタイプ名に既にデータが存在する場合は、上書きされます。
 
InternetExplorer 6 でも指定できる、最も互換性のあるタイプの一覧です。
 
タイプ名説明
"text"文字列を格納することができます。
 
HTML5 に対応している一部のブラウザは、以下のコンテンツタイプも指定できるようです。
 
InternetExplorer 11 の時点では、動作しません。(エラーが発生します)
 
タイプ名説明
"text/plain"文字列を格納することができます。"text" と同じ。
"text/html"HTML 文字列を格納することができます。
 
■使用例
 
DataTransfer オブジェクトに、タイプ名を指定してデータを格納する

<html>
  <body>

    <div id="aaa" draggable="true" style="width:400px; height:300px; background:#fcc;"></div>

    <script type="text/javascript">
    <!--
	// "aaa" という ID 属性のエレメントを取得する
	var element = document.getElementById("aaa");

	// ------------------------------------------------------------
	// ドラッグを開始した時に実行されるイベント
	// ------------------------------------------------------------
	element.ondragstart = function (e){
		if(!e) e = window.event; // レガシー

		// DataTransfer オブジェクトを取得する
		var data_transfer = e.dataTransfer;

		// テキストデータを格納する
		data_transfer.setData("text","1つ目のテスト文字列です。");

		try{

			// HTML 文字列データを格納する
			data_transfer.setData("text/html","<span>2つ目のテスト文字列です。</span>");

		}catch(e){}

	};

    //-->
    </script>

  </body>
</html>
 
 

 

データを取得する

 
 


■ドロップ発生時に、DataTransfer オブジェクトを取得する

 
ドロップが発生したか調べるには、ondrop イベントを使用します。
 
ドロップ時のイベントについては、こちらで解説しています。
 

■タイプ名を指定して、データを取得する


タイプ名を指定して、データを取得するには、getData() メソッドを使用します。
 
DataTransfer.getData("タイプ名") :String
第01引数 Stringデータのタイプ名を指定
戻り値 String指定したタイプのデータが存在する場合、そのデータが得られる。存在しない場合、空文字列が得られる。
 
■第01引数(データのタイプ名)
 
取得したいデータのタイプ名を指定します。
 
タイプ名ごとに、1つのデータが格納されています。
 
複数のデータを取得するには、タイプ名を変更しながら、getData() メソッドを複数回実行します。
 
InternetExplorer 6 でも指定できる、最も互換性のあるタイプの一覧です。
 
タイプ名説明
"text"テキスト文字列の取得を試みます。
"url"URL 文字列の取得を試みます。
 
HTML5 に対応している一部のブラウザは、以下のコンテンツタイプも指定できるようです。
 
InternetExplorer 11 の時点では、動作しません。(エラーが発生します)
 
タイプ名説明
"text/plain"テキスト文字列の取得を試みます。"text" と同じ。
"text/uri-list"URL 文字列の取得を試みます。"url" と同じ。
"text/html"HTML 文字列の取得を試みます。
 
■使用例
 
タイプ名を指定して、データを取得する

<html>
  <body>

    <div id="bbb" style="width:400px; height:300px; background:#ccf;" ></div>

    <script type="text/javascript">
    <!--
	// "bbb" という ID 属性のエレメントを取得する
	var element = document.getElementById("bbb");

	// ------------------------------------------------------------
	// ドラッグしながらマウスカーソルを移動した時に実行されるイベント
	// ------------------------------------------------------------
	element.ondragover = function (e){
		if(!e) e = window.event; // レガシー

		// ------------------------------------------------------------
		// デフォルトのドラッグを無効化(ドロップ操作を許可)
		// ------------------------------------------------------------
		if(e.preventDefault){
			// デフォルトのドラッグを無効化する
			e.preventDefault();
		}else{
			// デフォルトのドラッグを無効化する(非標準)
			return false;
		}
	};

	// ------------------------------------------------------------
	// ドロップしたときに実行されるイベント
	// ------------------------------------------------------------
	element.ondrop = function (e){
		if(!e) e = window.event; // レガシー

		// ------------------------------------------------------------
		// DataTransfer オブジェクトを取得する
		// ------------------------------------------------------------
		var data_transfer = e.dataTransfer;

		// ------------------------------------------------------------
		// データを取得する
		// ------------------------------------------------------------
		// テキスト文字列の取得を試みる
		var str = data_transfer.getData("text");
		console.log("text:" + str);

		// URL 文字列の取得を試みる
		var str = data_transfer.getData("url");
		console.log("url:" + str);

		// ------------------------------------------------------------
		// デフォルトのドロップを無効化
		// ------------------------------------------------------------
		if(e.preventDefault){
			// デフォルトのドロップを無効化する
			e.preventDefault();
		}else{
			// デフォルトのドロップを無効化する(非標準)
			return false;
		}
	};

    //-->
    </script>

  </body>
</html>
 

■格納されているデータのタイプ名をすべて取得する(HTML5 世代)


格納されているデータのタイプ名をすべて取得するには、types プロパティを使用します。
 
DOMStringList オブジェクトが得られます。
 
DOMStringList オブジェクトは、配列のように中身を取り出せます。
 
DOMStringList オブジェクトの中には、タイプ名が格納されています。
 
格納されているタイプ名の順番は、データをセットしたときの順番と同じです。
 
InternetExplorer 9 以前では、対応していません。
 
■ファイルデータが存在する場合
 
ファイルデータが存在する場合、"Files" という文字列が得られます。
 
"Files" タイプを使って、getData() メソッドから Filelist を取得することはできません。
 
InternetExplorer では、エラーが発生します。
 
ファイルリストを取得するには、files プロパティを使用します。
 
■すべてのデータを順番に取得する
 
すべてのデータを順番に取得する

<html>
  <body>

    <div id="bbb" style="width:400px; height:300px; background:#ccf;" ></div>

    <script type="text/javascript">
    <!--
	// "bbb" という ID 属性のエレメントを取得する
	var element = document.getElementById("bbb");

	// ------------------------------------------------------------
	// ドラッグしながらマウスカーソルを移動した時に実行されるイベント
	// ------------------------------------------------------------
	element.ondragover = function (e){
		if(!e) e = window.event; // レガシー

		// ------------------------------------------------------------
		// デフォルトのドラッグを無効化(ドロップ操作を許可)
		// ------------------------------------------------------------
		if(e.preventDefault){
			// デフォルトのドラッグを無効化する
			e.preventDefault();
		}else{
			// デフォルトのドラッグを無効化する(非標準)
			return false;
		}
	};

	// ------------------------------------------------------------
	// ドロップしたときに実行されるイベント
	// ------------------------------------------------------------
	element.ondrop = function (e){
		if(!e) e = window.event; // レガシー

		// ------------------------------------------------------------
		// DataTransfer オブジェクトを取得する
		// ------------------------------------------------------------
		var data_transfer = e.dataTransfer;

		// ------------------------------------------------------------
		// すべてのデータを順番に取得する
		// ------------------------------------------------------------
		// types プロパティに対応している
		if(data_transfer.types !== undefined){

			// 格納されているデータのタイプ名をすべて取得する
			var type_list = data_transfer.types;

			var i;
			var num = type_list.length;
			for(i=0;i < num;i++){
				// タイプ名を取得する
				var type = type_list[i];
				var data;
				try{
					// タイプ名を指定して、データを取得する(エラー発生に注意)
					data = data_transfer.getData(type);
				}catch(e){}

				// 出力テスト
				console.log("--- id:" + i);
				console.log("type:" + type);
				console.log("data:" + data);
			}
		}

		// ------------------------------------------------------------
		// デフォルトのドロップを無効化
		// ------------------------------------------------------------
		if(e.preventDefault){
			// デフォルトのドロップを無効化する
			e.preventDefault();
		}else{
			// デフォルトのドロップを無効化する(非標準)
			return false;
		}
	};

    //-->
    </script>

  </body>
</html>
 

■ファイルを取得する(HTML5 世代)


格納されているファイルをすべて取得するには、files プロパティを使用します。
 
FileList オブジェクトが得られます。
 
FileList オブジェクトは、配列のように中身を取り出せます。
 
FileList オブジェクトの中には、File オブジェクトが格納されています。
 
File オブジェクトについては、こちらで解説しています。
 
InternetExplorer 9 以前では、対応していません。
 
■すべてのファイルを順番に取得する
 
すべてのファイルを順番に取得する

<html>
  <body>

    <div id="bbb" style="width:400px; height:300px; background:#ccf;" ></div>

    <script type="text/javascript">
    <!--
	// "bbb" という ID 属性のエレメントを取得する
	var element = document.getElementById("bbb");

	// ------------------------------------------------------------
	// ドラッグしながらマウスカーソルを移動した時に実行されるイベント
	// ------------------------------------------------------------
	element.ondragover = function (e){
		if(!e) e = window.event; // レガシー

		// ------------------------------------------------------------
		// デフォルトのドラッグを無効化(ドロップ操作を許可)
		// ------------------------------------------------------------
		if(e.preventDefault){
			// デフォルトのドラッグを無効化する
			e.preventDefault();
		}else{
			// デフォルトのドラッグを無効化する(非標準)
			return false;
		}
	};

	// ------------------------------------------------------------
	// ドロップしたときに実行されるイベント
	// ------------------------------------------------------------
	element.ondrop = function (e){
		if(!e) e = window.event; // レガシー

		// ------------------------------------------------------------
		// DataTransfer オブジェクトを取得する
		// ------------------------------------------------------------
		var data_transfer = e.dataTransfer;

		// ------------------------------------------------------------
		// すべてのファイルを順番に取得する
		// ------------------------------------------------------------
		// files プロパティに対応している
		if(data_transfer.files !== undefined){

			// FileList オブジェクトを取得する
			var file_list = data_transfer.files;

			var i;
			var num = file_list.length;
			for(i=0;i < num;i++){
				// File オブジェクトを取得する
				var file = file_list[i];

				// 出力テスト
				console.log("--- id:" + i);
				console.log("name:" + file.name);
				console.log("size:" + file.size);
				console.log("type:" + file.type);
			}
		}

		// ------------------------------------------------------------
		// デフォルトのドロップを無効化
		// ------------------------------------------------------------
		if(e.preventDefault){
			// デフォルトのドロップを無効化する
			e.preventDefault();
		}else{
			// デフォルトのドロップを無効化する(非標準)
			return false;
		}
	};

    //-->
    </script>

  </body>
</html>
 
 

 

データを除外する

 


■DataTransfer オブジェクトを取得する

 
ドラッグを開始したか調べるには、ondragstart イベントを使用します。
 
ドラッグ時のイベントについては、こちらで解説しています。
 

■タイプ名を指定して、データを除外する


タイプ名を指定して、データを除外するには、clearData() メソッドを使用します。
 
draggable 属性が有効なエレメントからドラッグした場合のみ、データを除外できるようです。
 
InternetExplorer 6 を含む一部のブラウザでは、ドラッグ操作で自動的に格納されるデータも除外できます。
 
DataTransfer.clearData("タイプ名") :Void
第01引数(略可)Stringデータのタイプ名を指定。省略すると、すべてのデータを除外する。
戻り値 Voidなし
 
■第01引数(データのタイプ名)
 
除外したいデータのタイプ名を指定します。
 
引数を省略すると、すべてのデータを除外します。
 
InternetExplorer 6 でも指定できる、最も互換性のあるタイプの一覧です。
 
タイプ名説明
"text"文字列を除外します。
 
HTML5 に対応している一部のブラウザは、以下のコンテンツタイプも指定できるようです。
 
InternetExplorer 11 の時点では、動作しません。(エラーが発生します)
 
タイプ名説明
"text/plain"文字列を除外します。"text" と同じ。
"text/html"HTML 文字列を除外します。
 
■使用例
 
タイプ名を指定して、データを除外する

<html>
  <body>

    <div id="aaa" draggable="true" style="width:400px; height:300px; background:#fcc;"></div>

    <script type="text/javascript">
    <!--
	// "aaa" という ID 属性のエレメントを取得する
	var element = document.getElementById("aaa");

	// ------------------------------------------------------------
	// ドラッグを開始した時に実行されるイベント
	// ------------------------------------------------------------
	element.ondragstart = function (e){
		if(!e) e = window.event; // レガシー

		// DataTransfer オブジェクトを取得する
		var data_transfer = e.dataTransfer;

		// 文字列データを格納する
		data_transfer.setData("text","テスト文字列です。");

		// 文字列データをクリアする
		data_transfer.clearData("text");
	};

    //-->
    </script>

  </body>
</html>
 
 

 

許可エフェクトを設定する

 
 
 


■ドラッグ側の許可エフェクトを設定する

 
ドラッグ側の許可エフェクトを設定するには、effectAllowed プロパティを使用します。
 
以下の文字列を設定することができます。
 
ondragstart イベントに登録したコールバック関数内で、設定します。
 
「移動」「複製」「リンク」の3つの概念があります。
 
文字列説明
"copy"「複製」のみ許可します。
"move"「移動」のみ許可します。
"link"「リンク」のみ許可します。
"copyMove"「複製」と「移動」を許可します。
"copyLink"「複製」と「リンク」を許可します。
"linkMove"「リンク」と「移動」を許可します。
"all"すべて許可します。「複製」と「移動」と「リンク」の3つです。
"none"すべて禁止します。
"uninitialized"未設定の状態です。デフォルトの値です。"all" と同等の効果があります。
 
■使用例
 
ドラッグ時に許可エフェクトを設定する

<html>
  <body>

    <div id="aaa" draggable="true" style="width:400px; height:300px; background:#fcc;"></div>

    <script type="text/javascript">
    <!--
	// "aaa" という ID 属性のエレメントを取得する
	var element = document.getElementById("aaa");

	// ------------------------------------------------------------
	// ドラッグを開始した時に実行されるイベント
	// ------------------------------------------------------------
	element.ondragstart = function (e){
		if(!e) e = window.event; // レガシー

		// DataTransfer オブジェクトを取得する
		var data_transfer = e.dataTransfer;

		// 文字データをセット
		data_transfer.setData("text","テスト文字列");

		// 「複製」のみ許可する
		data_transfer.effectAllowed = "copy";
	};

    //-->
    </script>

  </body>
</html>
 

■ドロップ側のエフェクトを設定する

 
ドロップ側のエフェクトを設定するには、dropEffect プロパティを使用します。
 
以下の文字列を設定することができます。
 
ondragover イベントに登録したコールバック関数内で、設定します。
 
「移動」「複製」「リンク」の3つの概念があります。
 
文字列説明
"copy"ドラッグ側で、「複製」が許可されていれば受け入れます。それ以外は拒否します。
"move"ドラッグ側で、「移動」が許可されていれば受け入れます。それ以外は拒否します。
"link"ドラッグ側で、「リンク」が許可されていれば受け入れます。それ以外は拒否します。
"none"すべての受け入れを拒否します。(明示的に設定した場合)
未設定「移動」「複製」「リンク」の1つでも許可されていれば受け入れます。
 
■未設定時のデフォルトの値に注意
 
dropEffect プロパティを設定しなかった場合、"none" 値が格納されている事があります。
 
未設定時の "none" は、「移動」「複製」「リンク」の1つでも許可されていれば受け入れます。
 
明示的に、"none" 値をセットした場合、すべての受け入れを拒否します。
 
■アイコンの変化について
 
effectAlloweddropEffect プロパティの組み合わせで、以下のようにアイコンが変化します。
 
左側が、effectAllowed(ドラッグ側)の設定です。
 
上側が、dropEffect(ドロップ側)の設定です。
 
未設定"copy""move""link""none"
"copy"
"move"
"link"
"copyMove"
"copyLink"
"linkMove"
"all"
"none"
"uninitialized"
 
■使用例
 
ドロップ側のエフェクトを設定する

<html>
  <body>

    <div id="bbb" style="width:400px; height:300px; background:#ccf;" ></div>

    <script type="text/javascript">
    <!--
	// "bbb" という ID 属性のエレメントを取得する
	var element = document.getElementById("bbb");

	// ------------------------------------------------------------
	// ドラッグしながらマウスカーソルを移動した時に実行されるイベント
	// ------------------------------------------------------------
	element.ondragover = function (e){
		if(!e) e = window.event; // レガシー

		// ------------------------------------------------------------
		// DataTransfer オブジェクト
		// ------------------------------------------------------------
		// DataTransfer オブジェクトを取得する
		var data_transfer = e.dataTransfer;

		// 「複製」が許可されていれば受け入れる
		data_transfer.dropEffect = "copy";


		// ------------------------------------------------------------
		// デフォルトのドラッグを無効化(ドロップ操作を許可)
		// ------------------------------------------------------------
		if(e.preventDefault){
			// デフォルトのドラッグを無効化する
			e.preventDefault();
		}else{
			// デフォルトのドラッグを無効化する(非標準)
			return false;
		}
	};

    //-->
    </script>

  </body>
</html>
 
 

 

ドラッグ時に画像を表示する(HTML5 世代)

 


■ドラッグ時に画像を表示する

 
ドラッグ時に任意のエレメントを描画したい場合は、setDragImage() メソッドを使用します。
 
InternetExplorer 11 の時点では、未対応です。
 
Opera(Presto 版) では動作しません。
 
DataTransfer.setDragImage( エレメント , x , y ) :Void
第01引数 HTMLElement描画したい、HTMLElement オブジェクトを指定します。
第02引数 Number水平オフセット位置を指定します。負の値で右、正の値で左に移動します。
第03引数 Number垂直オフセット位置を指定します。負の値で下、正の値で上に移動します。
戻り値 Voidなし
 
■第01引数(エレメント)
 
描画したい、HTMLElement オブジェクトを指定します。
 
画像を表示したい場合は、HTMLImageElement オブジェクトをセットします。
 
画像イメージについては、こちらで解説しています。
 
画像が読み込み途中であった場合、イメージは表示されません。
 
■使用例
 
ドラッグ時に画像を表示する

<html>
  <body>

    <div id="aaa" draggable="true" style="width:400px; height:300px; background:#fcc;" ></div>

    <script type="text/javascript">
    <!--
	// "aaa" という ID 属性のエレメントを取得する
	var element = document.getElementById("aaa");

	// ------------------------------------------------------------
	// ドラッグ時に描画したい画像イメージ
	// ------------------------------------------------------------
	// HTMLImageElement オブジェクトを作成する
	var image = new Image();

	// URL を指定して、画像の読み込みを開始する
	image.src = "http://hakuhin.jp/graphic/title.png";


	// ------------------------------------------------------------
	// ドラッグを開始した時に実行される関数
	// ------------------------------------------------------------
	function DragStartFunc(e){
		// DataTransfer オブジェクトを取得する
		var data_transfer = e.dataTransfer;

		// 文字データをセット
		data_transfer.setData("text","テスト文字列");

		// ドラッグイメージに対応している
		if(data_transfer.setDragImage){

			// ドラッグイメージを設定する
			data_transfer.setDragImage(image,156,56);

		}
	}
	
	// ------------------------------------------------------------
	// リッスンを開始する
	// ------------------------------------------------------------
	// イベントリスナーに対応している
	if(element.addEventListener){

		// ドラッグ開始時に実行されるイベント
		element.addEventListener("dragstart",DragStartFunc);

	// アタッチイベントに対応している
	}else if(element.attachEvent){

		// ドラッグ開始時に実行されるイベント
		element.attachEvent("ondragstart",DragStartFunc);

	}
    //-->
    </script>

  </body>
</html>