Question

Quelqu'un at-il des suggestions sur la façon de modifier un lien dans un contentEditable div? Il serait idéal une fois que le lien est soit cliqué avec la souris ou le curseur touche le lien, que le petit invite sauterait et permettre à l'utilisateur de changer la propriété href du lien. L'invite est pas le problème, mais comment est-il possible de détecter le lien a été soit cliqué ou que le curseur est arrivé sur le lien? onfocus ne semble pas fonctionner dans un contentEditable div sur Firefox et Safari. Toutes les idées?

Était-ce utile?

La solution

Je suis assez sûr que ce soit ce que vous recherchez, mais je jQuery juste pour rendre le concept un peu plus facile de se moquer. jsbin aperçu disponible, alors allez le regarder. Si quelqu'un est capable de convertir en JS pur pour le bien de la réponse, je l'ai fait un wiki communautaire.

Il agit en se liant à la keyup / cliquez sur les événements sur la div éditable, puis de vérifier pour le nœud que les utilisateurs Caret est mis à l'aide window.getSelection() pour les normes ou document.selection pour les personnes IE. Le reste du code poignées popping / gérer les modifications.

méthodes 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());
    });
});

Autres conseils

Je l'ai testé que sur le chrome

style de bouton

button.cmd {
 ...
}

bouton de barre d'outils

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

dialogue modale -> éditeur de liens

<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;
        }
    }
});
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top