पाठ क्षेत्र में jQuery सेट कर्सर की स्थिति


435

आप jQuery का उपयोग करके टेक्स्ट फ़ील्ड में कर्सर की स्थिति कैसे निर्धारित करते हैं? मुझे सामग्री के साथ एक पाठ क्षेत्र मिला है, और मैं चाहता हूं कि उपयोगकर्ता कर्सर को एक निश्चित ऑफसेट पर तैनात करें जब वे क्षेत्र पर ध्यान केंद्रित करते हैं। कोड इस तरह दिखना चाहिए:

$('#input').focus(function() {
  $(this).setCursorPosition(4);
});

उस setCursorPosition फ़ंक्शन का कार्यान्वयन कैसा दिखेगा? यदि आपके पास सामग्री abcdefg के साथ एक पाठ फ़ील्ड है, तो इस कॉल के परिणामस्वरूप कर्सर को इस प्रकार तैनात किया जाएगा: abcd ** | ** efg।

Java का एक समान कार्य है, setCaretPosition। क्या जावास्क्रिप्ट के लिए एक समान विधि मौजूद है?

अपडेट: मैंने jQuery के साथ काम करने के लिए CMS के कोड को इस प्रकार संशोधित किया:

new function($) {
  $.fn.setCursorPosition = function(pos) {
    if (this.setSelectionRange) {
      this.setSelectionRange(pos, pos);
    } else if (this.createTextRange) {
      var range = this.createTextRange();
      range.collapse(true);
      if(pos < 0) {
        pos = $(this).val().length + pos;
      }
      range.moveEnd('character', pos);
      range.moveStart('character', pos);
      range.select();
    }
  }
}(jQuery);

78
$(this).get(0).setSelectionRange)? तुम्हें पता है कि बिल्कुल वैसा ही है this.setSelectionRange, केवल धीमा और पढ़ने में कठिन है, है ना? jQuery यहाँ आपके लिए शाब्दिक रूप से कुछ नहीं कर रहा है।
बॉबसन

2
@Bobince टिप्पणी में जोड़ने के लिए, फ़ंक्शन को चयनित तत्वों में से प्रत्येक के लिए पुनरावृति करना चाहिए और इसे वापस करना चाहिए। सही कोड मेरे उत्तर में है।
एचआरजे

21
@ बॉबिन वास्तव में बिलकुल भी सही नहीं है। 'यह' DOM नोड नहीं है, लेकिन jQuery ऑब्जेक्ट है। तो, $ (यह) .get (0) .setSelectionRange इस के रूप में ही है। (0) .setSelectionRange, इस के रूप में ही नहीं ।setSelectionRange।
प्रेस्तेल

$ (यह) [0] तेज है तो $ (यह) .get (0)
EminezArtus

पूर्ण समाधान के लिए इस ट्यूटोरियल को देखें। webdesignpluscode.blogspot.com/2017/05/…
वकास अली

जवाबों:


254

मेरे दो कार्य हैं:

function setSelectionRange(input, selectionStart, selectionEnd) {
  if (input.setSelectionRange) {
    input.focus();
    input.setSelectionRange(selectionStart, selectionEnd);
  }
  else if (input.createTextRange) {
    var range = input.createTextRange();
    range.collapse(true);
    range.moveEnd('character', selectionEnd);
    range.moveStart('character', selectionStart);
    range.select();
  }
}

function setCaretToPos (input, pos) {
  setSelectionRange(input, pos, pos);
}

तो आप इस तरह setCaretToPos का उपयोग कर सकते हैं:

setCaretToPos(document.getElementById("YOURINPUT"), 4);

JQuery से उपयोग दिखाते हुए, a textareaऔर a दोनों के साथ जीवंत उदाहरण input:

2016 तक, क्रोम, फ़ायरफ़ॉक्स, IE11, यहां तक ​​कि IE8 पर परीक्षण किया गया और काम कर रहा है (देखें कि यहां आखिरी है ; स्टैक स्निपेट्स IE8 का समर्थन नहीं करते हैं)।


3
जब आप अंत सेट करने और चयन ऑफ़सेट शुरू करने जा रहे हैं तो क्यों (सत्य) आवश्यक होगा?
एलेक्सिस विल्के

@mareoraft: क्रोम, फ़ायरफ़ॉक्स, IE8 और IE11 पर मेरे लिए textarea(और input) काम करता है ।
टीजे क्राउडर

मुझे लगता है कि यह मेरी स्क्रिप्ट के साथ काम करने में सक्षम नहीं होगा। मेरे पास एक पाठ क्षेत्र है जो पेज लोड पर खाली है, फिर जावास्क्रिप्ट द्वारा भरा जाता है क्योंकि आवेदन का उपयोग किया जाता है। मैं चाहता हूं कि प्रत्येक नए लेखन (उपयोग का एक रिकॉर्ड) से पहले कैरेट को 0 पर लौटाया जाए। क्या यह गतिशील डेटा है जो मुझे समस्याएं पैदा कर रहा है? अगर ऐसा है तो मैं उसके आसपास कैसे पहुंच सकता हूं?
क्रिस

स्ट्रिंग शाब्दिक 'चरित्र' का क्या महत्व है? क्या उस विशिष्ट स्ट्रिंग का उपयोग करने की आवश्यकता है?
जॉन श्नाइडर

299

यहाँ एक jQuery समाधान है:

$.fn.selectRange = function(start, end) {
    if(end === undefined) {
        end = start;
    }
    return this.each(function() {
        if('selectionStart' in this) {
            this.selectionStart = start;
            this.selectionEnd = end;
        } else if(this.setSelectionRange) {
            this.setSelectionRange(start, end);
        } else if(this.createTextRange) {
            var range = this.createTextRange();
            range.collapse(true);
            range.moveEnd('character', end);
            range.moveStart('character', start);
            range.select();
        }
    });
};

इसके साथ, आप कर सकते हैं

$('#elem').selectRange(3,5); // select a range of text
$('#elem').selectRange(3); // set cursor position

2
@ जेसे: डननो यह कैसे हुआ, मैं आमतौर पर 4 का उपयोग करता हूं। फिक्स्ड।
मप्र

1
@UberNeet: आपके सुझाव के आधार पर अपडेट किया गया।
एमपीएन

1
@Enve: मेरे पास परीक्षण करने के लिए IE 5.5 की एक प्रति नहीं है, लेकिन संभावना यह होगी कि jQuery IE 5.5 का समर्थन नहीं करता है
मप्र

1
@ JaroslavZáruba: हाँ। यह है। यदि आप पहले से ही jQuery का उपयोग कर रहे हैं तो आपको लिखने की अनुमति नहीं है selectRange($('.my_input')[0], 3, 5)। इसके अलावा, इसे एक से अधिक तत्वों के साथ काम करना चाहिए, अगर आपको इसकी आवश्यकता है, जो भी कारण हो। यदि आप शुद्ध देशी चाहते हैं, तो कृपया सीएमएस के समाधान का उपयोग करें।

2
मैं $('#elem').focus()पहले से जोड़ने की जरूरत है कि पलक झपकते कर्सर को प्राप्त करने के लिए।
19

37

यहाँ समाधान jQuery एक्सटेंशन कोड को छोड़कर सही हैं।

एक्सटेंशन फ़ंक्शन को प्रत्येक चयनित तत्व पर पुनरावृति करना चाहिए और thisचेनिंग का समर्थन करना चाहिए । यहाँ है एक सही संस्करण:

$.fn.setCursorPosition = function(pos) {
  this.each(function(index, elem) {
    if (elem.setSelectionRange) {
      elem.setSelectionRange(pos, pos);
    } else if (elem.createTextRange) {
      var range = elem.createTextRange();
      range.collapse(true);
      range.moveEnd('character', pos);
      range.moveStart('character', pos);
      range.select();
    }
  });
  return this;
};

4
प्रत्येक फ़ंक्शन jquery ऑब्जेक्ट देता है। तो आप वास्तव में कर सकते हैं: return this.each(function...)और स्टैंडअलोन लाइन को हटा दें।
झूममेल

23

मुझे एक समाधान मिला जो मेरे लिए काम करता है:

$.fn.setCursorPosition = function(position){
    if(this.length == 0) return this;
    return $(this).setSelection(position, position);
}

$.fn.setSelection = function(selectionStart, selectionEnd) {
    if(this.length == 0) return this;
    var input = this[0];

    if (input.createTextRange) {
        var range = input.createTextRange();
        range.collapse(true);
        range.moveEnd('character', selectionEnd);
        range.moveStart('character', selectionStart);
        range.select();
    } else if (input.setSelectionRange) {
        input.focus();
        input.setSelectionRange(selectionStart, selectionEnd);
    }

    return this;
}

$.fn.focusEnd = function(){
    this.setCursorPosition(this.val().length);
            return this;
}

अब आप कॉल करके किसी भी तत्व के अंत पर ध्यान केंद्रित कर सकते हैं:

$(element).focusEnd();

या आप स्थिति निर्दिष्ट करें।

$(element).setCursorPosition(3); // This will focus on the third character.

3
Textarea तत्वों के लिए, ध्यान केंद्रित करने के लिए एक सुधार जोड़ना है this.scrollTop(this[0].scrollHeight);, यह सुनिश्चित करने के लिए कि सम्मिलित करने के लिए textarea स्क्रॉल किया जाता है।
ड्रयू

12

यह मैक ओएसएक्स, jQuery 1.4 पर सफारी 5 पर मेरे लिए काम किया:

$("Selector")[elementIx].selectionStart = desiredStartPos; 
$("Selector")[elementIx].selectionEnd = desiredEndPos;

मेरे लिए जो प्रत्यक्ष पहुंच के साथ ठीक काम नहीं कर रहा था, लेकिन इसने पूरी तरह से काम किया। $ (myID) .प्रॉप ('सिलेक्शनस्टार्ट', पोजिशन); $ (myID) .प्रॉप ('चयन', स्थिति);
आमदन

9

मुझे लगता है कि यह एक बहुत पुरानी पोस्ट है, लेकिन मैंने सोचा कि मुझे इसे केवल jQuery का उपयोग करके अपडेट करने के लिए एक सरल समाधान पेश करना चाहिए।

function getTextCursorPosition(ele) {   
    return ele.prop("selectionStart");
}

function setTextCursorPosition(ele,pos) {
    ele.prop("selectionStart", pos + 1);
    ele.prop("selectionEnd", pos + 1);
}

function insertNewLine(text,cursorPos) {
    var firstSlice = text.slice(0,cursorPos);
    var secondSlice = text.slice(cursorPos);

    var new_text = [firstSlice,"\n",secondSlice].join('');

    return new_text;
}

एक नई लाइन (जैसे फेसबुक में) जोड़ने के लिए ctrl-enter का उपयोग करने के लिए उपयोग:

$('textarea').on('keypress',function(e){
    if (e.keyCode == 13 && !e.ctrlKey) {
        e.preventDefault();
        //do something special here with just pressing Enter
    }else if (e.ctrlKey){
        //If the ctrl key was pressed with the Enter key,
        //then enter a new line break into the text
        var cursorPos = getTextCursorPosition($(this));                

        $(this).val(insertNewLine($(this).val(), cursorPos));
        setTextCursorPosition($(this), cursorPos);
    }
});

मैं समालोचना के लिए खुला हूं। धन्यवाद।

अद्यतन: यह समाधान काम करने के लिए सामान्य प्रतिलिपि और पेस्ट कार्यक्षमता की अनुमति नहीं देता है (यानी ctrl-c, ctrl-v), इसलिए मुझे भविष्य में इसे संपादित करना होगा ताकि यह सुनिश्चित हो सके कि भाग फिर से काम करता है। यदि आपके पास ऐसा करने का विचार है, तो कृपया यहां टिप्पणी करें, और मुझे इसका परीक्षण करने में खुशी होगी। धन्यवाद।


7

IE में कुछ स्थान पर कर्सर ले जाने के लिए यह कोड पर्याप्त है:

var range = elt.createTextRange();
range.move('character', pos);
range.select();



6

यह मेरे लिए क्रोम में काम करता है

$('#input').focus(function() {
    setTimeout( function() {
        document.getElementById('input').selectionStart = 4;
        document.getElementById('input').selectionEnd = 4;
    }, 1);
});

जाहिरा तौर पर आपको एक माइक्रोसेकंड या उससे अधिक की देरी की आवश्यकता होती है, क्योंकि आमतौर पर एक उपयोगकर्ता पाठ क्षेत्र पर पाठ क्षेत्र में किसी स्थिति पर क्लिक करके (या टैब को मारकर) जो आप को ओवरराइड करना चाहते हैं, इसलिए आपको उस स्थिति तक इंतजार करना होगा। उपयोगकर्ता द्वारा निर्धारित किया गया क्लिक करें और फिर इसे बदलें।


रीड-ओनली प्रॉपर्टीज को असाइन करने की सख्त मोड में अनुमति नहीं है
इवान रुबिन्सन

4

यदि फ़ंक्शन Chrome का उपयोग कर रहा है, तो फ़ंक्शन कॉल के बाद बस गलत तरीके से वापस लौटना याद रखें क्योंकि Chrome फ़्रेक को अन्यथा फ़्रेक करता है।

{
    document.getElementById('moveto3').setSelectionRange(3,3);
    return false;
}

2
यह सबसे अच्छा अभ्यास नहीं है return false;। आप event.preventDefault();इसके बजाय चाहते हैं। यदि आप झूठे लौटते हैं, तो आप का मतलब है event.stopPropagation()जो हमेशा वांछनीय नहीं होता है
एलन एच।

4

इस प्रश्न के आधार पर , उत्तर, और ओपेरा के लिए पूरी तरह से काम नहीं करेगा जब टेक्स्टारिया में नई लाइन होगी। इस सवाल का जवाब कैसे setSelectionRange कॉल करने से पहले selectionstart, selectionEnd समायोजित करने के लिए समझाने की।

मेरे पास @AVProgrammer द्वारा प्रस्तावित समाधान के साथ अन्य प्रश्न से एडजस्टऑफसेट की कोशिश है और यह काम करता है।

function adjustOffset(el, offset) {
    /* From https://stackoverflow.com/a/8928945/611741 */
    var val = el.value, newOffset = offset;
    if (val.indexOf("\r\n") > -1) {
        var matches = val.replace(/\r\n/g, "\n").slice(0, offset).match(/\n/g);
        newOffset += matches ? matches.length : 0;
    }
    return newOffset;
}

$.fn.setCursorPosition = function(position){
    /* From https://stackoverflow.com/a/7180862/611741 */
    if(this.lengh == 0) return this;
    return $(this).setSelection(position, position);
}

$.fn.setSelection = function(selectionStart, selectionEnd) {
    /* From https://stackoverflow.com/a/7180862/611741 
       modified to fit https://stackoverflow.com/a/8928945/611741 */
    if(this.lengh == 0) return this;
    input = this[0];

    if (input.createTextRange) {
        var range = input.createTextRange();
        range.collapse(true);
        range.moveEnd('character', selectionEnd);
        range.moveStart('character', selectionStart);
        range.select();
    } else if (input.setSelectionRange) {
        input.focus();
        selectionStart = adjustOffset(input, selectionStart);
        selectionEnd = adjustOffset(input, selectionEnd);
        input.setSelectionRange(selectionStart, selectionEnd);
    }

    return this;
}

$.fn.focusEnd = function(){
    /* From https://stackoverflow.com/a/7180862/611741 */
    this.setCursorPosition(this.val().length);
}

4

बिटबकेट में मुझे मिले कोड का छोटा संशोधन

यदि कोड 2 स्थान दिए गए हैं, तो प्रारंभ / समाप्ति बिंदुओं के साथ चयन / हाइलाइट करने में सक्षम है। एफएफ / क्रोम / आईई 9 / ओपेरा में परीक्षण और ठीक काम करता है।

$('#field').caret(1, 9);

कोड नीचे सूचीबद्ध है, केवल कुछ लाइनें बदली हैं:

(function($) {
  $.fn.caret = function(pos) {
    var target = this[0];
    if (arguments.length == 0) { //get
      if (target.selectionStart) { //DOM
        var pos = target.selectionStart;
        return pos > 0 ? pos : 0;
      }
      else if (target.createTextRange) { //IE
        target.focus();
        var range = document.selection.createRange();
        if (range == null)
            return '0';
        var re = target.createTextRange();
        var rc = re.duplicate();
        re.moveToBookmark(range.getBookmark());
        rc.setEndPoint('EndToStart', re);
        return rc.text.length;
      }
      else return 0;
    }

    //set
    var pos_start = pos;
    var pos_end = pos;

    if (arguments.length > 1) {
        pos_end = arguments[1];
    }

    if (target.setSelectionRange) //DOM
      target.setSelectionRange(pos_start, pos_end);
    else if (target.createTextRange) { //IE
      var range = target.createTextRange();
      range.collapse(true);
      range.moveEnd('character', pos_end);
      range.moveStart('character', pos_start);
      range.select();
    }
  }
})(jQuery)

Chrome 39, IE11, Safari 5.1.7 में
चलता है

3

मुझे यह काम संतोषप्रद तत्वों और jQuery के लिए करना पड़ा और किसी को लगा कि शायद वह इसका उपयोग करने के लिए तैयार है:

$.fn.getCaret = function(n) {
    var d = $(this)[0];
    var s, r;
    r = document.createRange();
    r.selectNodeContents(d);
    s = window.getSelection();
    console.log('position: '+s.anchorOffset+' of '+s.anchorNode.textContent.length);
    return s.anchorOffset;
};

$.fn.setCaret = function(n) {
    var d = $(this)[0];
    d.focus();
    var r = document.createRange();
    var s = window.getSelection();
    r.setStart(d.childNodes[0], n);
    r.collapse(true);
    s.removeAllRanges();
    s.addRange(r);
    console.log('position: '+s.anchorOffset+' of '+s.anchorNode.textContent.length);
    return this;
};

उपयोग $(selector).getCaret()संख्या को ऑफसेट करता है और ऑफ़सेट $(selector).setCaret(num)स्थापित करता है और तत्व पर ध्यान केंद्रित करता है।

एक छोटी सी टिप भी, यदि आप $(selector).setCaret(num)कंसोल से चलते हैं, तो यह कंसोल को लौटा देगी। लेकिन आप कंसोल विंडो में स्थापित होने के बाद से फोकस पर ध्यान नहीं देंगे।

कीट; डी


1

आप सीधे प्रोटोटाइप बदल सकते हैं अगर setSelectionRange मौजूद नहीं है।

(function() {
    if (!HTMLInputElement.prototype.setSelectionRange) {
        HTMLInputElement.prototype.setSelectionRange = function(start, end) {
            if (this.createTextRange) {
                var range = this.createTextRange();
                this.collapse(true);
                this.moveEnd('character', end);
                this.moveStart('character', start);
                this.select();
            }
        }
    }
})();
document.getElementById("input_tag").setSelectionRange(6, 7);

jsFiddle लिंक

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.