संतोषप्रद, टेक्स्ट के अंत में सेट कैरेट (क्रॉस-ब्राउज़र)


111

क्रोम में आउटपुट :

<div id="content" contenteditable="true" style="border:1px solid #000;width:500px;height:40px;">
    hey
    <div>what's up?</div>
<div>
<button id="insert_caret"></button>

मुझे विश्वास है कि एफएफ में यह कुछ इस तरह दिखाई देगा:

hey
<br />
what's up?

और IE में :

hey
<p>what's up?</p>

दुर्भाग्य से, इसे बनाने का कोई अच्छा तरीका नहीं है ताकि हर ब्राउज़र <br />डिव या पी-टैग के बजाय सम्मिलित हो , या कम से कम मुझे कुछ भी ऑनलाइन नहीं मिल सके।


किसी भी तरह, मैं अब क्या करने की कोशिश कर रहा हूं, जब मैं बटन दबाता हूं, तो मैं चाहता हूं कि टेक्स्ट के अंत में कैरेट सेट हो, इसलिए इसे कुछ इस तरह दिखना चाहिए:

hey
what's up?|

ऐसा करने का कोई तरीका सभी ब्राउज़र में काम करता है ?

उदाहरण:

$(document).ready(function()
{
    $('#insert_caret').click(function()
    {
        var ele = $('#content');
        var length = ele.html().length;

        ele.focus();

        //set caret -> end pos
     }
 }

जवाबों:


282

निम्नलिखित कार्य सभी प्रमुख ब्राउज़रों में करेंगे:

function placeCaretAtEnd(el) {
    el.focus();
    if (typeof window.getSelection != "undefined"
            && typeof document.createRange != "undefined") {
        var range = document.createRange();
        range.selectNodeContents(el);
        range.collapse(false);
        var sel = window.getSelection();
        sel.removeAllRanges();
        sel.addRange(range);
    } else if (typeof document.body.createTextRange != "undefined") {
        var textRange = document.body.createTextRange();
        textRange.moveToElementText(el);
        textRange.collapse(false);
        textRange.select();
    }
}

placeCaretAtEnd( document.querySelector('p') );
p{ padding:.5em; border:1px solid black; }
<p contentEditable>foo bar </p>

शुरुआत में कैरेट को रखना लगभग समान है: इसके लिए बस बुलियन को कॉल में बदलने की आवश्यकता होती है collapse()। यहाँ एक उदाहरण है जो कार्य को प्रारंभ में और अंत में रखने के लिए कार्य करता है:

function createCaretPlacer(atStart) {
    return function(el) {
        el.focus();
        if (typeof window.getSelection != "undefined"
                && typeof document.createRange != "undefined") {
            var range = document.createRange();
            range.selectNodeContents(el);
            range.collapse(atStart);
            var sel = window.getSelection();
            sel.removeAllRanges();
            sel.addRange(range);
        } else if (typeof document.body.createTextRange != "undefined") {
            var textRange = document.body.createTextRange();
            textRange.moveToElementText(el);
            textRange.collapse(atStart);
            textRange.select();
        }
    };
}

var placeCaretAtStart = createCaretPlacer(true);
var placeCaretAtEnd = createCaretPlacer(false);

Chrome के साथ काम नहीं करता है क्योंकि createTextRange एक मानक फ़ंक्शन नहीं है। Stackoverflow.com/a/41743191/700206 देखें ।
व्हाइटनीलैंड

@ ली: यह क्रोम में ठीक काम करता है, जो समर्थन करता है window.getSelectionऔर document.createRangecreateTextRangeशाखा इंटरनेट एक्सप्लोरर के पुराने संस्करणों के लिए है।
टिम डाउन

लेखन के समय window.getSelectionसभी ब्राउज़रों के 0.29% (IE> 8) द्वारा समर्थित नहीं है। देखें: caniuse.com/#search=window.getSelection
w.stoettinger

@TimDown यह काम करता है। +1। लेकिन क्या आप कृपया टिप्पणियों को जोड़कर भी कोड की व्याख्या कर सकते हैं? महान होगा
shinobi

किसी को पता है कि एक आइफ्रेम> बॉडी एलिमेंट को टारगेट करने की कोशिश करते समय कैरेट को आखिर तक कैसे सेट करें (इस कोड का उपयोग करें)? शरीर तत्व है editablecontent="true"...? placeCaretAtEnd(this);मेरे लिए काम नहीं करेगा।
रॉबटी जू

6

दुर्भाग्य से टिम के शानदार जवाब ने मेरे लिए केवल अंत में रखने के लिए काम किया, शुरुआत में मुझे इसे थोड़ा संशोधित करना पड़ा।

function setCaret(target, isStart) {
  const range = document.createRange();
  const sel = window.getSelection();
  if (isStart){
    const newText = document.createTextNode('');
    target.appendChild(newText);
    range.setStart(target.childNodes[0], 0);
  }
  else {
    range.selectNodeContents(target);
  }
  range.collapse(isStart);
  sel.removeAllRanges();
  sel.addRange(range);
  target.focus();
  target.select();
}

यकीन नहीं है कि अगर focus()और select()वास्तव में जरूरत है।


आपने बाहरी पुस्तकालय भी शुरू किया। अगर आपको नहीं लगता कि फोकस और सेलेक्शन की आवश्यकता है तो क्यों न लाइनों की टिप्पणी करें और उसका परीक्षण करें?
डॉटनेग्गिस

धन्यवाद, हटा दिया jquery। मुझे याद है कि मेरे कुछ विरोधाभासी परिणाम थे, मैं उन्हें फिर से अलग करने की कोशिश करूंगा।
4

1

यह (लाइव) उदाहरण एक छोटा सरल कार्य दिखाता है setCaretAtStartEnd, जिसमें दो तर्क होते हैं; ए (संपादन योग्य) नोड को कैरट को रखने के लिए और बूलियन को इंगित करना चाहिए कि इसे कहां रखा जाए (नोड का प्रारंभ या अंत)

const editableElm = document.querySelector('[contenteditable]');

document.querySelectorAll('button').forEach((elm, idx) => 
  elm.addEventListener('click', () => {
    editableElm.focus()
    setCaretAtStartEnd(editableElm, idx) 
  })
)

function setCaretAtStartEnd( node, atEnd ){
  const sel = document.getSelection();
  node = node.firstChild;

  if( sel.rangeCount ){
      ['Start', 'End'].forEach(pos =>
        sel.getRangeAt(0)["set" + pos](node, atEnd ? node.length : 0)
      )
  }
}
[contenteditable]{ padding:5px; border:1px solid; }
<h1 contenteditable>Place the caret anywhere</h1>
<br>
<button>Move caret to start</button>
<button>Move caret to end</button>


-1

यदि आप Google क्लोजर कंपाइलर का उपयोग कर रहे हैं, तो आप निम्नलिखित (टिम के उत्तर से कुछ सरल) कर सकते हैं:

function placeCaretAtEnd(el) {
    el.focus();
    range = goog.dom.Range.createFromNodeContents(el);
    range.collapse(false);
    range.select();
}

यहाँ क्लोजुरस्क्रिप्ट में एक ही बात है:

(defn place-caret-at-end [el] 
   (.focus el)
   (doto (.createFromNodeContents goog.dom.Range el)
         (.collapse false)
         .select))

मैं क्रोम, सफारी और FireFox में यह परीक्षण किया है, IE के बारे में निश्चित नहीं ...


1
रेंज = goog.dom.Range.createFromNodeContents (el); goog.dom क्या है?
आह तु

इसने मेरे लिए काम किया। @ AnhTú: goog.dom एक नाम स्थान है जो क्लोजर-लाइब्रेरी द्वारा प्रदान किया जाता है।
डेविड बेनेश
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.