web-dev-qa-db-fra.com

jquery Définition de la position du curseur dans contenteditable div

L'ancienne version de la question est ci-dessous, après des recherches plus approfondies, j'ai décidé de reformuler la question. Le problème, comme auparavant, est que je dois mettre au point une division pouvant être réglée sur le contenu sans mettre en surbrillance le texte. Faire une mise au point tout en haut surligne le texte dans Chrome.

Je me rends compte que les gens ont résolu ce problème dans les zones de texte en réinitialisant la position du curseur dans la zone de texte. Comment puis-je faire cela avec un élément contenteditable? Tous les plugins que j'ai essayés ne fonctionnent qu'avec textareas. Merci.

Ancien libellé de la question:

J'ai un élément contenteditable que Je veux me concentrer, mais seulement dans la mesure où pour placer le curseur au début de l'élément, en sélectionnant plutôt tout.

elem.trigger('focus'); avec jquery sélectionne tout le texte de la totalité élément en chrome. Firefox se comporte correctement, en plaçant le curseur sur le devant le texte. Comment puis-je avoir Chrome doit se comporter comme je le souhaite ou est concentrez-vous peut-être pas ce que je cherche pour.

Merci a tous.

35
Mark

demo: http://so.lucafilosofi.com/jquery-setting-cursor-position-in-contenteditable-div/

      <div id="editable" contentEditable="true">
            <h2>Lorem</h2> <p>ipsum dolor <i>sit</i> 
               amet, consectetur <strong>adipiscing</strong> elit.</p> Aenean.
        </div>

    <script type="text/javascript">
        $(function () {
            $('[contentEditable="true"]').on('click', function (e) {
                if (!$(this).hasClass('editing')) {
                    var html = $(this).html();
                    if (html.length) {
                        var range = rangy.createRange();
                        $(this).toggleClass('editing').html('<span class="content-editable-wrapper">' + html + '</span>');
                        var $last = $(this).find('.content-editable-wrapper');
                        range.setStartAfter($last[0]);
                        range.collapse(false);
                        rangy.getSelection().setSingleRange(range);
                    }
                }
            }).on('blur', function () {
                $(this).toggleClass('editing').find('.content-editable-wrapper').children().last().unwrap();
            });
        });
    </script>
20
Luca Filosofi

Je me trompe peut-être en posant la question, mais ce qui suit ne conviendrait-il pas (en supposant un <div> éditable avec l'id "editable")? Le chronomètre existe, car dans Chrome, le comportement du navigateur natif qui sélectionne l'élément entier semble se déclencher après l'événement focus, annulant ainsi l'effet du code de sélection, à moins qu'il ne soit différé après l'événement focus:

var div = document.getElementById("editable");

div.onfocus = function() {
    window.setTimeout(function() {
        var sel, range;
        if (window.getSelection && document.createRange) {
            range = document.createRange();
            range.selectNodeContents(div);
            range.collapse(true);
            sel = window.getSelection();
            sel.removeAllRanges();
            sel.addRange(range);
        } else if (document.body.createTextRange) {
            range = document.body.createTextRange();
            range.moveToElementText(div);
            range.collapse(true);
            range.select();
        }
    }, 1);
};

div.focus();
29
Tim Down

Oui ça arrive parce que tu as utilisé 

elem.trigger('focus'); 

essayez d'utiliser class ou d'identifier l'élément sur lequel vous souhaitez déclencher un événement déclencheur.

3
Chirag

J'ai réussi à résoudre ce problème après avoir un peu fouillé dans le DOM.

Elm.focus();
window.getSelection().setPosition(0);

Cela ne fonctionne probablement que sur les navigateurs WebKit, mais comme c'est la seule source du problème, j'ai ajouté un conditionnel (en utilisant jQuery)

if(!$.browser.webkit) {
    Elm.focus();
} else {
    Elm.focus();
    window.getSelection().setPosition(0);
}

J'espère que ceci résoudra votre problème.

1
DfKimera

Définir la position du pointeur dans les balises pre ou div:

function setCursor(pos) {
    var el = document.getElementById("asd");
    var range = document.createRange();
    var sel = window.getSelection();
    range.setStart(el.childNodes[0], pos);
    range.collapse(true);
    sel.removeAllRanges();
    sel.addRange(range);
    el.focus();
}

$('button').click(function () {
    setCursor(5);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="asd" contenteditable="true" >
asd
two
</div>
<button>Set caret position</button>

Source: https://social.msdn.Microsoft.com/Forums/en-US/f91341cb-48b3-424b-9504-f2f569f4860f/getset-caretcursor- position-in-a-contentitable-div?forum=winswithhtml5

0
K. Kuksin