10

Does anyone have any suggestions on how to edit an link in a contentEditable div? It would be ideal once the link is either clicked with mouse, or the cursor hits the link, that the a small prompt would pop up and allow the user to change the href property of the link. The prompt isn't the issue, but how is it possible to detect the link has been either clicked or that the cursor has arrived at the link? onfocus doesn't seem to work in a contentEditable div on Firefox & Safari. Any ideas?

4

2 回答 2

17

我很确定这就是你要找的东西,但是我使用 jQuery 只是为了让这个概念更容易模拟。 jsbin预览可用,所以去看看。如果有人能够为了答案而将其转换为纯 JS,我已将其设为社区 wiki。

它通过绑定到可编辑 div 上的 keyup/click 事件来工作,然后检查用户插入符号window.getSelection()用于标准或document.selection那些 IE 人员的节点。其余代码处理弹出/处理编辑。

jQuery方法:

function getSelectionStartNode(){
  var node,selection;
  if (window.getSelection) { // FF3.6, Safari4, Chrome5 (DOM Standards)
    selection = getSelection();
    node = selection.anchorNode;
  }
  if (!node && document.selection) { // IE
    selection = document.selection
    var range = selection.getRangeAt ? selection.getRangeAt(0) : selection.createRange();
    node = range.commonAncestorContainer ? range.commonAncestorContainer :
           range.parentElement ? range.parentElement() : range.item(0);
  }
  if (node) {
    return (node.nodeName == "#text" ? node.parentNode : node);
  }
}

$(function() {
    $("#editLink").hide();
    $("#myEditable").bind('keyup click', function(e) {
        var $node = $(getSelectionStartNode());
        if ($node.is('a')) {
          $("#editLink").css({
            top: $node.offset().top - $('#editLink').height() - 5,
            left: $node.offset().left
          }).show().data('node', $node);
          $("#linktext").val($node.text());
          $("#linkhref").val($node.attr('href'));
          $("#linkpreview").attr('href', $node.attr('href'));
        } else {
          $("#editLink").hide();
        }
    });
    $("#linktext").bind('keyup change', function() {
      var $node = $("#editLink").data('node');
      $node.text($(this).val());
    });
    $("#linkhref").bind('keyup change', function() {
      var $node = $("#editLink").data('node');
      $node.attr('href', $(this).val());
      $node.and('#linkpreview').attr('href',$(this).val());
    });
});
于 2010-03-17T00:43:53.810 回答
0

我只在 chrome 上测试过

按钮样式

button.cmd {
 ...
}

工具栏按钮

<button type="button" id="linkEditor" class="cmd">link</button>

模态对话框 -> 链接编辑器

<div id="optionDialog" class="modal">
    <div class="modal-content">
        <div id="linkOption">
            <p>
                <label>Indirizzo link</label><br />
                <input type="text" id="linkUrl" value="" placeholder="http://www..." />
            </p>
            <p>
                <label>Testo link</label><br />
                <input type="text" id="linkData" value="" placeholder="link label" />
            </p>
            <p>
                <button type="button" id="linkDone">apply</button>
                <button type="button" id="cancel">cancel</button>
            </p>
        </div>
    </div>
</div>

javascript, jQuery

var cur_range;
var cur_dialog;

$(document).ready(function() {
    $('.editor').focus();

    //on toolbar button mousedown keep current range
    $('.cmd').mousedown(function(event) {
        event.preventDefault();
        try {
            cur_range = document.getSelection().getRangeAt(0);
        }
        catch(error) {
            console.log(error);
        }
    });

    $('#linkEditor').click(function() {
        event.preventDefault();

        //if user select edit link, else insert link
        if (!cur_range.collapsed) {
            //if selection is a link set edit values
            if (cur_range.commonAncestorContainer.parentNode.nodeName.toLowerCase() == 'a') {
                $('#linkUrl').val(cur_range.commonAncestorContainer.parentNode.href);
                $('#linkData').val(cur_range.commonAncestorContainer.data);
            }
            else {
                //alert here
                return false;
            }
        }
        else {
            $('#linkUrl').val('');
            $('#linkData').val('');
        }
        //open link editor dialog
        $('#optionDialog').show();
        $('#linkOption').show();

        //store current dialog section (link, table, header)
        cur_dialog = $('#linkOption');
    });

    $('#linkDone').click(function() {
        event.preventDefault();
        if (cur_range.collapsed) {
            //insert link at caret position
            var node = '<a href="' + $('#linkUrl').val() + '" target="_blank">' + $('#linkData').val() + '</a>';
            cur_range.insertNode(cur_range.createContextualFragment(node));
        }
        else {
            //replace existing link values
            cur_node = cur_range.commonAncestorContainer.parentNode;
            cur_node.href = $('#linkUrl').val();
            cur_node.innerText = $('#linkData').val();
        }
        //update range
        document.getSelection().removeAllRanges();
        document.getSelection().addRange(cur_range);
        document.getSelection().collapseToEnd();
        $('.modal-close').click();

        //if you don't use observer some code is nedeed
        //save_history(1);
    });

    //When the user clicks anywhere outside of the modal, close it
    window.onclick = function(event) {
        optionDialog = document.getElementById('optionDialog');
        if (event.target == optionDialog) {
            $('#optionDialog').hide();
            cur_dialog.hide();
            cur_dialog = null;
        }
    }
});
于 2018-08-10T01:45:29.673 回答