[JavaScript]強制回應視窗唯讀狀態下複製控制項文本

來源:互聯網
上載者:User

強制回應視窗唯讀狀態下要進行複製很麻煩,無法選定文本也無法進行複製、編輯、右鍵瀏覽器菜單。本文提供一種解決這個問題的方法:使用JavaScript指令碼,選定控制項文本,再使用CTRL+C進行複製。

一、一些後面要用到的方法:

/* 功能: 判斷是否字串類型 參數: 無調用方法: 對象.isString()NOTE: (typeof(oSource) == 'string')不能正確識別new String()產生的字串對象*/String.prototype.isString = String.prototype.isString || (    function() {         return ('[object String]' == Object.prototype.toString.call(this));     });/*功能: 擷取控制項文本。*/function GetControlText(oSource) {    return (oSource.innerText    || oSource.value    || ""); //oSource.selectorText || }/*功能: 設定控制項可複製NOTE: 選定後就可以使用Ctrl+C按鍵組合進行複製! 但不能使用瀏覽器右鍵菜單*/function SetCanCopy(oSource) {    oSource.contentEditable = true;    oSource.disabled = false;//可能不需要修改?}

判斷是否字串的方法抄自百度開源js庫;擷取控制項文本可能還有其他情況沒考慮到;設定控制項contentEditable = true;不是一定需要,不過設定了可以使得選定控制項文本的操作更加準確(在文本選定方法fnSelectText中體現),具體來說,就是雙擊控制項(控制項外部不算),選定的文本就是點擊的控制項的文本,而如果不設定contentEditable為true,則很大機率會選定同頁面出現相同文本的第一個地方。

二、儲存控制項原始屬性

/* 現場儲存與恢複 *//* 臨時變數, 用於儲存需要複製文本的控制項的原始狀態 */var OriginStatus = OriginStatus || { };/*功能: 儲存控制項原始狀態*/function SaveOriginStatus(oSource) {    //oSource.disabled = 'disabled';//禁用後不能複製    //oSource.readOnly = true;//無效, 還是可以複製    OriginStatus.contentEditable = oSource.contentEditable;    OriginStatus.disabled = oSource.disabled;}/*功能: 還原控制項原始狀態*/function RecoverOriginStatus(oSource) {    oSource.contentEditable = OriginStatus.contentEditable;    oSource.disabled = OriginStatus.disabled;}

三、滑鼠左鍵按住不放進行控制項文本選擇

/* 滑鼠左鍵按住不放進行控制項文本選擇 */var isBound = false;document.attachEvent("onmousedown", function() {    isBound = true;});document.attachEvent("onmouseup", function() {    isBound = false;});

方法內註冊事件用attachEvent,沒有考慮到非IE的情況。

四、選中要複製的控制項的文本

/*功能: 選中要複製的控制項的文本。NOTE: 方法內部是選中控制項所有文本, 而非部分.*/function fnSelectText(oSource, e) {    if (!oSource) return;        e = e || window.event;    e.returnValue = false;        //textarea採用自身選定功能. 注意textarea不能被disabled    if(oSource.type == "textarea") return;    //設定為可編輯, 是為了減少findText方法選中第一個的幾率    SaveOriginStatus(oSource);    SetCanCopy(oSource);    var sSourceText = GetControlText(oSource);    var caretPos = sSourceText.length; //文本長度    if (caretPos == 0) return;    if (oSource.createTextRange) {        var r = oSource.createTextRange();        r.move('character', caretPos);        r.select();    } else if (oSource.setSelectionRang) {        oSource.setSelectionRange(caretPos, caretPos);        oSource.focus();    } else {        //TODO: BUG, 如果頁面有多個相同文本, 則會選中第一個        var r = document.selection.createRange();//或者document.body.createTextRange();        r.findText(sSourceText);        //動態添加的內容, 可能會導致異常: htmlfile: Could not complete the operation due to error 800a025e.        r.select();    }    RecoverOriginStatus(oSource);}

注意:方法內部是選中控制項所有文本, 而非部分。另外還有個BUG未解決:如果頁面有多個相同文本, 則會選中第一個

五、頁面事件註冊

//雙擊控制項選定文本事件document.attachEvent("ondblclick", function(e) {    //強制回應視窗下Label控制項不屬於document.activeElement    if(window.event.srcElement) {        fnSelectText(window.event.srcElement, window.event || e);    }});//滑鼠左鍵按住移動選中事件document.attachEvent("onmouseover", function(e) {    if(!!isBound) {        if(window.event.srcElement) {            fnSelectText(window.event.srcElement, window.event || e);        }    }});//滑鼠右鍵事件//document.attachEvent("onmousedown", function(e) {//    e = e || window.event;//    //點擊滑鼠右鍵//    if(e.button == 2) {//        var oSource = window.event.srcElement;//        if(oSource.type == "textarea") return;//        else {//        //請同步選取Ctrl和C按鍵組合進行複製或者長按滑鼠左鍵將文本拖拉到富文字編輯器中!//            alert("請同步選取Ctrl和C按鍵組合進行複製!");//            //window.event.cancelBubble = true; //            //e.returnValue = false;//        }//        //createCopyTextarea(oSource);//        //window.event.srcElement.contentEditable = true;//    }//});document.attachEvent("oncontextmenu", function(e) {    var oSource = window.event.srcElement;    if(oSource.type == "textarea") return;    else {        alert("請同步選取Ctrl和C按鍵組合進行複製!");    }});

將事件註冊到document,而不是某個控制項,主要是考慮到頁面如果有多個控制項的話,逐個控制項註冊比較麻煩。這樣處理也符合使用者習慣,滑鼠左鍵選定或者雙擊選定文本,然後按Ctrl+C按鍵組合複製即可。

六、使用方法

假設指令檔名為CopyDataOnModalWindow.js,檔案存放路徑為"http://www.cnblogs.com/Scripts/js/CopyDataOnModalWindow.js",那麼可以如下調用:

<script type="text/javascript">if(window.document.readyState == "interactive") {    if (!window.opener) {        //如果是在強制回應視窗下, 才引用指令碼        var s = document.createElement('script');        s.src = "http://www.cnblogs.com/Scripts/js/CopyDataOnModalWindow.js";        s.type = "text/javascript";        window.document.getElementsByTagName("head")[0].appendChild(s);    } else {    }}</script>

注意:我不確定 !window.opener就一定是強制回應視窗,如果您有判斷強制回應視窗更好的方法,請留言告知。

這段指令碼放在頁面最後即可。

〇、結束語及遺留問題

指令碼如此處理,可以不用汙染頁面,只需要複製指令碼調用方法即可。遺憾的是,沒有解決JavaScript操作剪貼簿出現異常的問題;也沒處理好一些細節。

說明:

1.textarea控制項如果不是disabled狀態的話,即使是readOnly,是可以選定並且瀏覽器右鍵菜單可以彈出,所以處理時排除掉textarea;如果是disabled狀態的話,雙擊、滑鼠點擊事件均不會被觸發,暫時沒有想到有什麼其他辦法可以解決

2.select控制項的文本也無法選定。但select控制項disabled狀態下事件可以被觸發。

3.選定後,無法右鍵彈出瀏覽器原生菜單;如果是自訂菜單,暫時無法解決JavaScript操作剪貼簿出現異常的問題;

4.細節問題

bug: 選擇控制項文本, 如果頁面有多處相同文本, 將會選中第一個(當然也可以複製到文本)
bug: 選定控制項文本, 滑鼠左鍵在選定地區按下後不放, 將文本拖拉到其他地方再釋放, 這個時候isBound 還是 true;或者某種情形下,點擊右鍵,移動滑鼠會使得滑鼠移動過的控制項逐個選定文本。這個無關大雅,不過沒有深入處理。

----end----

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.