如何使用IE瀏覽器將資料傳送至剪貼簿?
—— CBETA經文引用複製script略談
Jyh-chyang Lee 2000/07
您在使用CBETA電子佛典時,是否運用過引用複製的功能呢?
在這篇文章之中,我們將簡單的介紹如何利用Script語言,讓網頁增加引用複製的功能。當然,在CBETA的經文資料之中,由於有充份的XML標記可以讓程式來判斷,所以能夠很便利的找到經文的段落和出處,這一點您可參考電子報之中介紹過的XML標記應用。
以下的文章對於不熟悉script語言的朋友可能有些複雜,但是程式基本上均能在IE5.0下正常執行。對於script
語言的詳細介紹,您可自行上網瀏覽相關的入門網站。
若想使用瀏覽器進行複製工作,可使用execCommand的指令,其語法簡介如下,詳細的說明您可以參考MSDN文件:
bSuccess = object.execCommand(sCommand [, bUserInterface] [, vValue])
參數說明:
sCommand
命令字串,為必要的參數,傳送一指令字串給瀏覽器執行。
bUserInterface
一個布林值,選擇性參數,告訴瀏覽器是否要通知或詢問使用者。預設值為偽(false),即不顯示使用者的界面。若為真值時(true),則依指令的情形顯示使用者的界面。例如設定字型時選擇字型內容等等。
vValue
選擇性的參數,其格式依不同的指令而變化。如改變顏色時,傳入顏色的數值。
函數的傳回值:
bSuccess
布林值,如果執行指令成功,則傳回真(true),反之則為偽(flase)。
適用物件:
document(IE4), TextRange(IE4), controlRange(IE5)
使用注意事項:
execCommand時,需在網頁下載完畢之後執行。通常在VB裡,可使用下列的事件:
Dim WithEvents WebDoc As HTMLDocument
Private Sub brwWebBrowser_DownloadComplete()
On Error Resume Next
Set WebDoc = brwWebBrowser.Document
WebDoc.execCommand "SelectAll"
'全選
End Sub
在網頁之中,則可用下列方式,在網頁下載完成之後,直接將網頁印出(IE5):
<html>
<head>
<title>Print_Me_onload!</title>
<meta author="Jester@CBETA 2000">
</head>
<script language="JavaScript1.2">
function go_print(){
document.execCommand("selectall");
if (window.print) {
window.print();
}
}
</script>
<body onload="go_print()">
……
</body>
</html>
您可利用execCommand執行許多功能,這裡先簡單列舉幾個指令,其他的指令有機會另文再談:
sCommand 指令內容
============ ===============
SelectAll 全選
Refresh 重新載入文件
Copy 複製
Cut 剪下
Delete 刪除
============ ===============
當使用者選取某段文字之後,希望讓使用者按一個鍵,或是由程式控制,將選取的資料送到剪貼簿中,以下這一段程式就能夠幫上忙:
<html>
<head>
<title>簡單的Copy</title>
<meta author="Jester@CBETA 2000">
</head>
<script language="JavaScript1.2">
function do_copy(){
if (document.selection.type!="none") {
var range=document.selection.createRange();
range1.execCommand "copy";
}
}
</script>
<body>
<input type="button" value="引用複製" name="copy"
onclick="do_copy()">
……
</body>
</html>
由於execCommand只適用於document(IE4), TextRange(IE4), controlRange(IE5)三個物件之中,因此必需先利用createRange()的方式,將選取區複製成一個TextRange,這裡即是range1。這個動作有利於將來進行其他的修改。(註:您也可以利用createTextRange來為其他的元件產生TextRange。)
在上段程式碼之中,我們加上了判斷是否有選取區的判斷式:
if (document.selection.type!="none") {
…
}
selection的type屬性可為none,text和control三種。如果沒有選取區或插入點的話,則為none。
現在,我們已經可以在網頁中加上copy的功能,而不必讓使用者按ctrl-C。不過這樣的功能並不足以讓我們滿意,因為我們希望在複製的時候,能自動的加上一些資訊,例如文章的出處、版本,甚至於依照不同的情況加上不同的資訊等等。要處理這個功能,我們則必需對於TextRange有所了解。
所謂的TextRange,簡單的來說,就好像是一列文字之中,第X字開始到第Y個字為止所產生的文字區塊,例如閱兵時為了使隊伍整齊,讓大家依身高排成一列,然後取其中身高最接近的一群人出來一樣。對於瀏覽器而言,有了這個開頭和結尾的位置,就可以決定選擇的內容。
對於TextRange物件,我們常用下列幾種方式來取得內容:
TextRange.htmlText 文字範圍的HTML碼內容
TextRange.text 文字範圍的文字內容
另外,在IE4.0以後,對於標記的物件,提供了以下四種取得/設定內容的方式,也可以運用在TextRange物件中:
TextRange.innerHTML
TextRange.outerHTML
TextRange.innerText
TextRange.outerText
或者是利用以下兩個方式動態的插入內容:
insertAdjacentText
insertAdjacentHTML
現在,我們利用設定純文字的方式,希望在使用者選取了網頁上某段文字時,能夠加上網頁的標題,和網頁最後更新的時間。
function do_Xcopy() {
if (document.selection.type!="none") { //判斷是否有選取區
//製造文字選取區
var range = document.selection.createRange();
//複製選取區,直接利用range來執行亦可
var range1=range.duplicate();
//另外設定一個字串,內容包括網頁的標題和最後修改的時間。
temp = "《"+self.document.title+"》"+self.document.lastModified;
//將range1的內容重新設定,加上換行符號及temp字串的內容,"\n"代表換行
range1.text+="\n"+temp;
//執行複製
range1.execCommand("Copy");
}
//下列兩行是IE之中防止事件沸升所做的處理。
return false;
cancelBubble;
}
如果您直接利用上面的函數,您會發現,每當您使用一次,選取的內容居然會增加我們加上的標題和日期字串。而且在執行完以後,選取區的反白會消失,然而事實上選取區仍然存在。更重要的是,居然選取的動作並沒有正常的執行。
因此,我們必須要想辦法改善目前的狀況。
改善的方法,是利用先前提及的開頭和結尾的功能,由於選取區的內容被修改過了,所以造成在執行copy指令時無法正常,因此我們希望能在要copy之前,把要加上去的文字加上,執行完指令之後,再把加上去的文字拿掉,於是我們將程式碼改成這樣:
function do_Xcopy() {
if (document.selection.type!="none") {
var range = document.selection.createRange();
var range1=range.duplicate();
var temp = "《"+self.document.title+"》"+self.document.lastModified;
//將range1的內容先存起來
var sText=range1.text
range1.text+="\n"+temp;
//沒有加上下列這一行將無法正常的執行Copy指令
range1.moveStart("character",0-sText.length-temp.length-1);
//執行複製
range1.execCommand("Copy");
//取回選取區原本的內容
range1.text=sText;
range1.moveStart("character",0-sText.length-1);
}
return false;
cancelBubble;
}
如此一來,我們就能正常的使用引用複製的功能了。
這裡需要進一步介紹的,是range1.moveStart的方法:
iMoved = TextRange.moveStart(sUnit [, iCount])
iMoved是傳回移到的位置,依照的單位是sUnit中所定義的,可分為字元"character",單字"word",句子"sentence"和文字編輯區"textedit"等等。而iCount則是移動的距離,內定值是1,可為負數。
函數string.length會傳回字串的字元數,因此我們使用character為單位,便可正確的取出我們要的選取區了。
小範例:
看了這許多,您是不是有一點眼花了呢!
沒有關係,接下來我們利用上述的功能,做一些應用上的示範。
如果我們要讓使用者在不同的網頁之中交換參數值,有幾種方法,
第一,利用伺服器的功能,如ASP、PHP、CGI等等;
第二,使用cookie;
第三,利用網頁連結時傳遞參數,如x.html?name=jester&Co=CBETA。
第四,使用frameset,然後利用瀏覽器物件和DOM來處理。
第五,其他……
現在,我們還有一個選擇,就是可以利用剪貼簿的功能來傳遞。
首先,我們要先能把資訊傳到剪貼簿,為了方便,我們詢問使用者姓名,並且動態顯示問候語。然後在換頁之後仍然保留使用者的姓名。其中我們利用TEXTAREA來處理,將可做更進一步的運用,由於超過本文範圍,在此略過不提。
<html>
<head>
<title>welcome!</title>
<meta author="Jester@CBETA 2000">
</head>
<script>
function copyname(){
var range=document.all["names"].createTextRange();
range.execCommand("copy");
}
</script>
<body onload="copyname()">
<script>
var sName=window.prompt("請問貴姓大名?","無名氏");
document.write("<p>歡迎<TEXTAREA STYLE='border:none;overflow:hidden'
ID=names>"+sName);
document.write("</TEXTAREA>光臨</p>");
</script>
………其他的內容………
</body>
</html>
其中
vTextData = window.prompt([sMessage] [, sDefaultValue])
表示顯示一個對方框讓用者輸入一個字串。
再來,我們希望另一個網頁能夠讀出這個值:
<html>
<head>
<title>Show Name!</title>
<meta author="Jester@CBETA 2000">
</head>
<script language="JavaScript">
function shownames(){
var range=document.all["names"].createTextRange();
range.execCommand("paste");
}
</script>
<body onload="shownames()">
<p><TEXTAREA STYLE='border:none;overflow:hidden' ID=names></TEXTAREA>
</p><p>………其他的內容………</p>
</body>
</html>
當然,由於剪貼簿是共用的環境,因此您能取得其他程式傳來的資訊,但也可能資訊被其他的程式所修改,這也許是個壞處,但卻是cookie所不及。
例如,我們可以做一個時計,每隔一秒鐘抓一次剪貼簿中的內容,如果有所更動,則直接線上處理,如查辭典,傳遞訊息伺服器等等。
小結:
經文加上引用複製的功能,除了要有相關的技術之外,CBETA
對於經文資料完善的標記處理,才是最重要的基礎之一。因為有完善的標記資訊,才能夠提供更多的訊息和服務,並進行交換。由於HTMLHelp版經文中所提供的引用複製功能有許多的標記分析,在此就不加以介紹了,您可利用上述的方式自由地運用在網頁上。
|