亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

在內容可編輯<div>上設置光標位置

在內容可編輯<div>上設置光標位置

精慕HU 2019-07-03 13:55:45
我需要一個明確的跨瀏覽器解決方案,將游標/插入符號的位置設置為最后一個已知的位置,當內容編輯=‘on’<div>重新獲得焦點時。內容可編輯div的默認功能似乎是每次單擊div時將插入符號/光標移動到div中文本的開頭,這是不可取的。我相信,當它們離開div的焦點時,我必須將當前光標的位置存儲在變量中,然后當它們再次將焦點放在內部時,重新設置這個值,但是我還不能將它們放在一起,或者找到一個工作代碼示例。如果有人有任何想法,工作代碼片段或樣本,我會很高興看到他們。我還沒有真正的代碼,但下面是我所擁有的:<script type="text/javascript">// jQuery$(document).ready(function() {    $('#area').focus(function() { .. }  // focus I would imagine I need.}</script><div id="area" contentEditable="true"></div>PS。我嘗試過這個資源,但它似乎不適用于<div>??赡苤贿m用于TextArea(如何將光標移動到可內容實體的末尾)在內容可編輯<div>上設置光標位置
查看完整描述

3 回答

?
墨色風雨

TA貢獻1853條經驗 獲得超6個贊

這與基于標準的瀏覽器兼容,但在IE中可能會失敗。我把它作為起點。不支持DOM范圍。

var editable = document.getElementById('editable'),
    selection, range;// Populates selection and range variablesvar captureSelection = function(e) {
    // Don't capture selection outside editable region
    var isOrContainsAnchor = false,
        isOrContainsFocus = false,
        sel = window.getSelection(),
        parentAnchor = sel.anchorNode,
        parentFocus = sel.focusNode;

    while(parentAnchor && parentAnchor != document.documentElement) {
        if(parentAnchor == editable) {
            isOrContainsAnchor = true;
        }
        parentAnchor = parentAnchor.parentNode;
    }

    while(parentFocus && parentFocus != document.documentElement) {
        if(parentFocus == editable) {
            isOrContainsFocus = true;
        }
        parentFocus = parentFocus.parentNode;
    }

    if(!isOrContainsAnchor || !isOrContainsFocus) {
        return;
    }

    selection = window.getSelection();

    // Get range (standards)
    if(selection.getRangeAt !== undefined) {
        range = selection.getRangeAt(0);

    // Get range (Safari 2)
    } else if(
        document.createRange &&
        selection.anchorNode &&
        selection.anchorOffset &&
        selection.focusNode &&
        selection.focusOffset    ) {
        range = document.createRange();
        range.setStart(selection.anchorNode, selection.anchorOffset);
        range.setEnd(selection.focusNode, selection.focusOffset);
    } else {
        // Failure here, not handled by the rest of the script.
        // Probably IE or some older browser
    }};// Recalculate selection while typingeditable.onkeyup = captureSelection;
    // Recalculate selection after clicking/drag-selectingeditable.onmousedown = function(e) {
    editable.className = editable.className + ' selecting';};document.onmouseup = function(e) {
    if(editable.className.match(/\sselecting(\s|$)/)) {
        editable.className = editable.className.replace(/ selecting(\s|$)/, '');
        captureSelection();
    }};editable.onblur = function(e) {
    var cursorStart = document.createElement('span'),
        collapsed = !!range.collapsed;

    cursorStart.id = 'cursorStart';
    cursorStart.appendChild(document.createTextNode('—'));

    // Insert beginning cursor marker
    range.insertNode(cursorStart);

    // Insert end cursor marker if any text is selected
    if(!collapsed) {
        var cursorEnd = document.createElement('span');
        cursorEnd.id = 'cursorEnd';
        range.collapse();
        range.insertNode(cursorEnd);
    }};// Add callbacks to afterFocus to be called after cursor is replaced
    // if you like, this would be useful for styling buttons and so onvar afterFocus = [];editable.onfocus = function(e) {
    // Slight delay will avoid the initial selection
    // (at start or of contents depending on browser) being mistaken
    setTimeout(function() {
        var cursorStart = document.getElementById('cursorStart'),
            cursorEnd = document.getElementById('cursorEnd');

        // Don't do anything if user is creating a new selection
        if(editable.className.match(/\sselecting(\s|$)/)) {
            if(cursorStart) {
                cursorStart.parentNode.removeChild(cursorStart);
            }
            if(cursorEnd) {
                cursorEnd.parentNode.removeChild(cursorEnd);
            }
        } else if(cursorStart) {
            captureSelection();
            var range = document.createRange();

            if(cursorEnd) {
                range.setStartAfter(cursorStart);
                range.setEndBefore(cursorEnd);

                // Delete cursor markers
                cursorStart.parentNode.removeChild(cursorStart);
                cursorEnd.parentNode.removeChild(cursorEnd);

                // Select range
                selection.removeAllRanges();
                selection.addRange(range);
            } else {
                range.selectNode(cursorStart);

                // Select range
                selection.removeAllRanges();
                selection.addRange(range);

                // Delete cursor marker
                document.execCommand('delete', false, null);
            }
        }

        // Call callbacks here
        for(var i = 0; i < afterFocus.length; i++) {
            afterFocus[i]();
        }
        afterFocus = [];

        // Register selection again
        captureSelection();
    }, 10);};


查看完整回答
反對 回復 2019-07-03
?
holdtom

TA貢獻1805條經驗 獲得超10個贊

此解決方案適用于所有主要瀏覽器:

saveSelection()連接到onmouseuponkeyup事件,并將所選內容保存到變量中。savedRange.

restoreSelection()連接到onfocus事件,并重新選擇保存在savedRange.

這是非常有效的,除非您希望在用戶單擊div時恢復所選內容(這有點非直觀,通常您希望光標到您單擊的位置,但代碼是完整的)。

為了實現這一點,onclickonmousedown事件被函數取消。cancelEvent()它是一個跨瀏覽器函數,用于取消事件。這個cancelEvent()函數還運行restoreSelection()函數,因為在取消單擊事件時,div不會接收焦點,因此,除非運行此函數,否則不會選擇任何內容。

變量isInFocus存儲它是否在焦點中并被更改為“false”。onblur和“真實”onfocus..這允許只在div不在焦點時才取消單擊事件(否則根本無法更改所選內容)。

如果希望在div通過單擊來聚焦時更改所選內容,而不恢復所選內容onclick(并且只有在以編程方式將焦點分配給元素時,才使用document.getElementById("area").focus();或者類似的,然后簡單地刪除onclickonmousedown事件。這個onblur事件和onDivBlur()cancelEvent()在這種情況下也可以安全地刪除函數。

如果您想要快速測試該代碼,那么如果將它直接放到html頁面的正文中,則該代碼應該可以工作:

<div id="area" style="width:300px;height:300px;" onblur="onDivBlur();" onmousedown="return cancelEvent(event);
" onclick="return cancelEvent(event);" contentEditable="true" onmouseup="saveSelection();" onkeyup="saveSelection()
;" onfocus="restoreSelection();"></div><script type="text/javascript">var savedRange,isInFocus;function saveSelection(){
    if(window.getSelection)//non IE Browsers
    {
        savedRange = window.getSelection().getRangeAt(0);
    }
    else if(document.selection)//IE
    { 
        savedRange = document.selection.createRange();  
    } }function restoreSelection(){
    isInFocus = true;
    document.getElementById("area").focus();
    if (savedRange != null) {
        if (window.getSelection)//non IE and there is already a selection
        {
            var s = window.getSelection();
            if (s.rangeCount > 0) 
                s.removeAllRanges();
            s.addRange(savedRange);
        }
        else if (document.createRange)//non IE and no selection
        {
            window.getSelection().addRange(savedRange);
        }
        else if (document.selection)//IE
        {
            savedRange.select();
        }
    }}//this part onwards is only needed if you want to restore selection onclickvar isInFocus = false;function onDivBlur(){
    isInFocus = false;}function cancelEvent(e){
    if (isInFocus == false && savedRange != null) {
        if (e && e.preventDefault) {
            //alert("FF");
            e.stopPropagation(); // DOM style (return false doesn't always work in FF)
            e.preventDefault();
        }
        else {
            window.event.cancelBubble = true;//IE stopPropagation
        }
        restoreSelection();
        return false; // false = IE style
    }}</script>


查看完整回答
反對 回復 2019-07-03
?
繁星淼淼

TA貢獻1775條經驗 獲得超11個贊

我編寫了一個跨瀏覽器范圍和選擇庫,名為蘭迪它包含了我在下面發布的代碼的改進版本。您可以使用選擇保存和恢復模塊對于這個特殊的問題,雖然我很想用這樣的方法@Nico Burns的回答如果您沒有在項目中做其他的選擇,并且不需要大量的庫。


查看完整回答
反對 回復 2019-07-03
  • 3 回答
  • 0 關注
  • 2992 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號