سؤال

كيف يمكنك ضبط موضع المؤشر في حقل النص باستخدام jQuery؟لدي حقل نصي يحتوي على محتوى، وأريد أن يتم وضع مؤشر المستخدمين على إزاحة معينة عند التركيز على الحقل.يجب أن يبدو الرمز كما يلي:

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

كيف سيبدو تنفيذ وظيفة setCursorPosition؟إذا كان لديك حقل نصي يحتوي على المحتوى abcdefg، فسيؤدي هذا الاستدعاء إلى وضع المؤشر على النحو التالي:abcd**|**efg.

جافا لديها وظيفة مماثلة، setCaretPosition.هل توجد طريقة مماثلة لجافا سكريبت؟

تحديث:لقد قمت بتعديل كود CMS للعمل مع jQuery كما يلي:

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);
هل كانت مفيدة؟

المحلول

لدي وظيفتان:

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);

مثال حي مع كل من أ textarea و input, ، يُظهر الاستخدام من jQuery:

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);
}

$("#set-textarea").click(function() {
  setCaretToPos($("#the-textarea")[0], 10)
});
$("#set-input").click(function() {
  setCaretToPos($("#the-input")[0], 10);
});
<textarea id="the-textarea" cols="40" rows="4">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</textarea>
<br><input type="button" id="set-textarea" value="Set in textarea">
<br><input id="the-input" type="text" size="40" value="Lorem ipsum dolor sit amet, consectetur adipiscing elit">
<br><input type="button" id="set-input" value="Set in input">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

اعتبارًا من عام 2016، تم اختباره والعمل على Chrome وFirefox وIE11 وحتى IE8 (راجع هذا الأخير هنا;لا تدعم مقتطفات المكدس IE8).

نصائح أخرى

إليك حل 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

الحلول هنا صحيحة باستثناء رمز ملحق 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;
};

لقد وجدت الحل الذي يناسبني:

$.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;
    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();

نجح هذا معي على Safari 5 على نظام التشغيل Mac OSX، jQuery 1.4:

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

أدرك أن هذا منشور قديم جدًا، لكنني أعتقد أنه ينبغي علي تقديم حل أبسط لتحديثه باستخدام 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 لإضافة سطر جديد (كما هو الحال في Facebook):

$('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)، لذا سأضطر إلى تعديل هذا في المستقبل للتأكد من أن هذا الجزء يعمل مرة أخرى.إذا كانت لديك فكرة عن كيفية القيام بذلك، يرجى التعليق هنا، وسأكون سعيدًا بتجربتها.شكرًا.

أنا أستخدم هذا: http://plugins.jquery.com/project/jCaret

في IE لتحريك المؤشر في موضع ما، يكفي هذا الرمز:

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

اضبط التركيز قبل إدراج النص في منطقة النص؟

$("#comments").focus();
$("#comments").val(comments);

هذا يعمل بالنسبة لي في الكروم

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

من الواضح أنك تحتاج إلى تأخير قدره ميكروثانية أو أكثر، لأنه عادة ما يركز المستخدم على حقل النص من خلال النقر على موضع ما في حقل النص (أو عن طريق الضغط على علامة التبويب) الذي تريد تجاوزه، لذلك عليك الانتظار حتى يصبح الموضع يحددها المستخدم بالنقر ثم تغييره.

تعديل بسيط على الكود الذي وجدته bitbucket

أصبح الرمز الآن قادرًا على التحديد/التمييز بنقاط البداية/النهاية إذا تم منحه موضعين.تم اختباره ويعمل بشكل جيد في FF/Chrome/IE9/Opera.

$('#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 يقوم بتعديل التكسير بطريقة أخرى.

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

بناء على هذا سؤال, ، لن تعمل الإجابة بشكل مثالي مع ie و Opera عندما يكون هناك سطر جديد في منطقة النص.ال إجابة اشرح كيفية ضبط التحديد ابدأ، ثم حدد النهاية قبل استدعاء setSelectionRange.

لقد جربت AdjustOffset من السؤال الآخر مع الحل الذي اقترحه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);
}

كان علي أن أجعل هذا يعمل مع عناصر contenteditable و 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) من وحدة التحكم، سيُرجع console.log ولكنك لن تتمكن من تصور التركيز نظرًا لأنه تم إنشاؤه في نافذة وحدة التحكم.

الأفضل ؛د

يمكنك تغيير النموذج الأولي مباشرةً في حالة عدم وجود 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 وصلة

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top