如臂使指——Dojo框架下讓浮動窗口跟隨鼠標而動

介紹

在web應用的很多場合,需要讓浮動窗口跟隨鼠標而動。比如這兒舉的一個例子:當用戶選中網頁上一段內容時,彈出工具條讓用戶進行標記。可以想象一下,有一個在線看書的應用,支持讀者在閱讀的時候隨時做筆記。當讀者選中一段文字時,彈出一個小工具條,讓用戶保存成筆記標題或筆記內容。在這種場景下,讓小工具條出現在選中文字的旁邊是必要的用戶體驗。在實際應用場合,還必須確保在不同的瀏覽器中、當文字內容有滾動條時,小工具條的位置都不錯。

 

下面就來看看如何實現這種效果(代碼已經在Firefox 17.0.9,Chrome 30.0.1599.101,IE 10下面測過)。

首先用Dojo widget(Dojo 1.7.3)搭建一個網頁框架。在主模塊中放入文字內容。接下來要做的就是創建一個浮動窗口,讓它在用戶選中一段文字內容的時候出現。

 

代碼實現

test.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<style type="text/css">
@import "../js/dijit/themes/tundra/tundra.css";
@import "../css/main.css";
</style>

</head>
<body class="tundra">
<div data-dojo-type="dijit.layout.BorderContainer"
		style="width: 100%; height: 100%; margin: 0px; padding: 0px; ">
	<div data-dojo-type="dojox.layout.ContentPane"
		data-dojo-props="region:'top'"
		style="height:38px;width:100%;background-color: black; color: white;font-family: arial;font-size: 28px;">
		在線閱讀器
	</div>
	<div data-dojo-type="dojox.layout.ContentPane"
		data-dojo-props="region:'center', splitter: true"
		style="width: 100%; height: 100%; border: none; padding: 0px; background-color: #ffffff;">
		<div style="width: 99%; margin: -3px 0px -2px 2px;">
			<button id="open_model_btn" data-dojo-type="dijit.form.Button"
				class="menu_button" type="button">打開文章</button>
		</div>
		<div data-dojo-type="dijit.layout.BorderContainer"
			data-dojo-props="design:'sidebar', gutters:true, liveSplitters:true"
			style="width: 100%; height: 300px;">
			<div data-dojo-type="dojox.layout.ContentPane" data-dojo-props="splitter:true,region:'left'"
				style="width: 300px;">
				<div style="background-color: lightgray;">筆記列表</div>
			</div>
			<div data-dojo-type="dojox.layout.ContentPane" style="font-size: 16px;"
				data-dojo-props="splitter:true,region:'center'">
				<div id="resource_text_container">
					<div>閱讀 reading</div>
					<div>1、從書面材料中獲取信息的過程。書面材料主要是文字,也包括符號、公式、圖表等。首先是把文字符號變成聲音,後達到對書面材料的理解。閱讀是一種主動的過程,是由閱讀者根據不同的目的加以調節控制的。</div>
					<div>2、朗讀是一種閱讀方式。朗讀是指出聲誦讀,默讀則指沒有明顯發聲的誦讀。在某些情況下,如詩詞欣賞。朗讀有特殊功用,可高度集中注意力,但就從書面材料中獲取知識而言,默讀更爲重要,理解文字材料主要靠默讀。閱讀時的眼動是一系列的跳動,跳動本身歷時很短,而且不能產生對文字的清晰視覺。對文字的清晰視覺都是在注視時得到的。</div>
					<div>3、影響閱讀理解的外部因素包括文字材料和情境的物理特點,如照明條件,文字的字體、型號等;文字材料的易讀度,如字詞的常用程度
						,句子的長短與結構的繁簡
						,命題密度(即在一定長度的材料中出現的概念數)等;材料的概括與抽象的程度;由外部確定的閱讀目的等等。影響閱讀理解的內部因素主要是閱讀者的知識基礎。此外,閱讀者的注意、記憶和思維也都是重要的內部因素。</div>
					<div>閱讀可以分成四種情況。第一種是信息式閱讀法。這類閱讀的目的只是爲了瞭解情況。我們閱讀報紙、廣告、說明書等屬於這種閱讀方法。對於大多數這類資料,讀者應該使用一目十行的速讀法,眼睛象電子掃描一樣地在文字間快速瀏覽,及時捕捉自己所需的內容,捨棄無關的部分。任何人想及時瞭解當前形勢或者研究某一段歷史,速讀法是不可少的,然而,是否需要中斷、精讀或停頓下來稍加思考,視所讀的材料而定。</div>
					<div>第二種是文學作品閱讀法。文學作品除了內容之外,還有修辭和韻律上的意義。因此閱讀時應該非常緩慢,自己能聽到其中每一個詞的聲音,嘴脣沒動,是因爲偷懶。例如讀“壓力”這個詞時,喉部肌肉應同時運動。閱讀詩詞更要注意聽到聲音,即使是一行詩中漏掉了一個音節,照樣也能聽得出來。閱讀散文要注意它的韻律,聆聽詞句前後的聲音,還需要從隱喻或詞與詞之間的組合中獲取自己的感知。文學家的作品,唯有充分運用這種接受語言的能力,才能汲取他們的聰明才智、想象能力和寫作技巧。這種依賴耳聽—一通過眼睛接受文字信號,將它們轉譯成聲音,到達喉嚨,然後加以理解的閱讀方法,最終同我們的臆想能力相關。</div>
					<div>第三種是經典著作閱讀法,這種方法用來閱讀哲學、經濟、軍事和古典著作。閱讀這些著作要象讀文學作品一樣的慢,但讀者的眼睛經常離開書本,對書中的一字一句都細加思索,捕捉作者的真正的用意。從而理解其中的深奧的哲理。值得注意的是,如果用經典著作閱讀法閱讀文學作品,往往容易忽略文學作品的特色,以
						使讀者自己鑽進所謂文學觀念史的牛角尖中去。</div>
					<div>第四種閱讀方法是麻醉性的閱讀法。這種閱讀只是爲了消遣。如同服用麻醉品那樣使讀者忘卻了自己的存在,飄飄然於無限的幻想之中。這類讀者一般對自己的經歷和感受不感興趣,把自己完全置身於書本之外。如果使用麻醉性的閱讀方法閱讀名著,讀者只能得到一些已經添加了自己的幻想的膚淺的情節,使不朽的名著下降到鴛鴦蝴蝶派作家的庸俗作品的水平。如果漫不經心地閱讀《安娜•卡列尼娜》,猶如讀一本拙劣的三角戀愛小說。麻醉性的閱讀在將進入成年的時候達到頂峯。年輕人的麻醉閱讀是造成大量的文學作品質量低劣的原因。</div>
				</div>
				<div id="resource_text_floating_pane" 
					style="border: 1px solid #BBBBBB;position: absolute;width: 85px;z-index: 10;display:none;">
					<div data-dojo-type="dijit.Toolbar" style="padding: 3px 0 0 3px;">
					    <div id="add_paragraph" data-dojo-type="dijit.form.Button" data-dojo-props="showLabel:true">
					        	段落
					    </div>
						<div id="add_content" data-dojo-type="dijit.form.Button" data-dojo-props="showLabel:true">
					        	內容
					    </div>
					</div>
				</div>
			</div>
		</div>
	</div>
</div>

<script>
		dojoConfig = {
			isDebug : false,
			parseOnLoad : true,
			async : true
		};
	</script>
	<script type="text/javascript" src="../js/dojo/dojo.js"></script>
	<script>
		require([ "dojo/parser", "dijit/form/Button", "dijit/Toolbar",
				"dijit/layout/BorderContainer", "dojox/layout/ContentPane"]);
	</script>
	<script>
		require(
				[ "dojo/ready", 
				  "dijit/registry",
				  "dojo/dom",
				  "dojo/on"
				  ],
				function(ready, registry, dom, on) {
					ready(function() {
						var resource_text_container = dom.byId("resource_text_container");
						on(resource_text_container, "mouseup", function(e){
							//拿到鼠標位置
							var selection = document.getSelection();
							var start = selection.anchorOffset;
							var end = selection.focusOffset;
							
							var fp = dom.byId("resource_text_floating_pane");
							if(start-end != 0){
								//根據鼠標位置,計算浮動窗口的位置
								if(dojo.isChrome != undefined){//Chrome
									var cx = e.layerX;
									var cy = resource_text_container.parentElement.scrollTop + e.layerY;								
								}else if(dojo.isIE != undefined){//IE
									var cx = e.layerX - resource_text_container.parentElement.offsetLeft;
									var cy = resource_text_container.parentElement.scrollTop + e.layerY;	
								}else {//Firefox
									var cx = e.layerX;
									var cy = e.layerY;
								}
								fp.style.left = (cx + 0) + "px";
								fp.style.top = (cy + 0) + "px";
								fp.style.display = "block";
							}else{
								fp.style.display = "none";
							}
						});
						
						on(registry.byId("add_paragraph"), "click", function(e){
							alert("新建段落");
						});
						
						on(registry.byId("add_content"), "click", function(e){
							alert("新建內容");
						});
					});
				});
	</script>
</body>
</html>

總結

在確定浮動窗口位置時,我們主要使用了鼠標事件的layerX和layerY屬性。關於Event對象與定位相關的屬性,和瀏覽器的版本密切相關。想支持其他版本的,可以參考這篇文章


發佈了81 篇原創文章 · 獲贊 29 · 訪問量 42萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章