本文介绍了如何在扩展器中更新Knockout js Observable时保留光标位置的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述 目标是在用户输入键入时将其转换为大写。我使用以下扩展程序: ko.extenders.uppercase = function(target,option){ target。 subscribe(function(newValue){ target(newValue.toUpperCase()); }); 返回目标; }; 此扩展程序可以添加到绑定到HTML文本框的observable中: self.userField = ko.observable(product.userField ||)。extend({uppercase:true}); 这很好用。将绑定到observable的文本转换为大写。当用户将文本键入空字段或将其添加到现有文本的末尾时,文本将转换为大写。 到目前为止,非常好! 现在,当用户想要插入文本时,光标将通过光标键或鼠标放置到插入点,并输入新文本将字符作为大写插入但是光标位置现在跳转到文本的末尾,因为底层的observable已更新。 如何仍然保留光标位置,同时仍将用户输入转换为大写? 更新1: 我创建了一个自定义绑定,因此我可以访问该元素并获取并设置光标位置。我试图利用现有的值绑定优点。我正在使用内置的 ko.selectExtensions.writeValue 函数。这可能对我的应用程序来说已经足够好了,但可能无法在所有浏览器中使用。 ko.bindingHandlers.upperCase = { init:function(element,valueAccessor,allBindings,viewModel,bindingContext){ ko.bindingHandlers [value]。init(element,valueAccessor,allBindings); }, update:function(element,valueAccessor,allBindings,viewModel,bindingContext){ var caretPosition = getCaretPosition(element); var newValue = ko.utils.unwrapObservable(valueAccessor()); ko.selectExtensions.writeValue(element,newValue.toUpperCase()); setCaretPosition(element,caretPosition); //代码来自:http://stackoverflow.com/questions/2897155/get-cursor-position-in-characters-within-a-text-input-field function getCaretPosition (ctrl){ var CaretPos = 0; // IE支持 if(document.selection){ ctrl.focus(); var Sel = document.selection.createRange(); Sel.moveStart('character', - ctrl.value.length); CaretPos = Sel.text.length; } // Firefox支持 else if(ctrl.selectionStart || ctrl.selectionStart =='0'){ CaretPos = ctrl.selectionStart; } return(CaretPos); } 函数setCaretPosition(ctrl,pos){ if(ctrl.setSelectionRange){ ctrl.focus(); ctrl.setSelectionRange(pos,pos); } else if(ctrl.createTextRange){ var range = ctrl.createTextRange(); range.collapse(true); range.moveEnd('character',pos); range.moveStart('character',pos); range.select(); } } } }; 解决方案嗯,我认为最好的解决方案是使用Vanilla Javascript 。如果没有,检查值是否为UpperCase,获取位置,更改值,设置位置。简单。 var stayUpperCase = function(){if(this.value!= this.value.toUpperCase()){var caretPos = getCaretPosition (这个); this.value = this.value.toUpperCase(); setCaretPosition(this,caretPos); document.getElementById('myinput')。addEventListener('keyup',stayUpperCase); document.getElementById('myinput')。addEventListener('change',stayUpperCase); //来自http://stackoverflow.com的代码/ questions / 2897155 / get-cursor-position-in-characters-in-a-text-input-fieldfunction getCaretPosition(elem){// Initialize var caretPos = 0; // IE支持if(document.selection){//设置焦点元素elem.focus(); //要获取光标位置,请获取空选择范围var sel = document.selection.createRange(); //将选择开始移动到0位置sel.moveStart('character', - elem.value.length); //插入符号位置是选择长度caretPos = sel.text.length; } // Firefox支持else if(elem.selectionStart || elem.selectionStart =='0'){caretPos = elem.selectionStart; } //返回结果return(caretPos);} //来自http://stackoverflow.com/questions/512528/set-cursor-position-in-html-textboxfunction的代码setCaretPosition(elem,caretPos){if(elem!= null){if(elem.createTextRange){var range = elem.createTextRange(); range.move('character',caretPos); range.select(); } else {if(elem.selectionStart){elem.focus(); elem.setSelectionRange(caretPos,caretPos); } else elem.focus(); } < input type =textid =myinput/> 您可以附加更多键盘事件使它看起来更平滑。 The goal is to have user input converted to upper case as they type. I am using the following extender:ko.extenders.uppercase = function (target, option) { target.subscribe(function (newValue) { target(newValue.toUpperCase()); }); return target;};This extender can be added to the observable that are bound to HTML text boxes:self.userField = ko.observable(product.userField || "").extend({ uppercase: true });This works great. Converts text bound to the observable to upper case. As the user types text into an empty field or adds it to the end of existing text, the text is converted to upper case.So far, so good!Now when the user wants to insert text, the cursor is placed to the insertion point either with the cursor keys or mouse and the new text is entered the character is inserted as upper case but the cursor position now jumps to the end of the text because the underlying observable is updated.How can the cursor position be retained while still converting the user input to upper case?Update 1:I created a custom binding so I could access the element and get and set the cursor position. I tried to tap into the existing value binding goodness. I am using the built in ko.selectExtensions.writeValue function. This may be good enough for my application but may not work in all browsers.ko.bindingHandlers.upperCase = { init: function (element, valueAccessor, allBindings, viewModel, bindingContext) { ko.bindingHandlers["value"].init(element, valueAccessor, allBindings); }, update: function (element, valueAccessor, allBindings, viewModel, bindingContext) { var caretPosition = getCaretPosition(element); var newValue = ko.utils.unwrapObservable(valueAccessor()); ko.selectExtensions.writeValue(element, newValue.toUpperCase()); setCaretPosition(element, caretPosition); // Code from: http://stackoverflow.com/questions/2897155/get-cursor-position-in-characters-within-a-text-input-field function getCaretPosition (ctrl) { var CaretPos = 0; // IE Support if (document.selection) { ctrl.focus (); var Sel = document.selection.createRange (); Sel.moveStart ('character', -ctrl.value.length); CaretPos = Sel.text.length; } // Firefox support else if (ctrl.selectionStart || ctrl.selectionStart == '0') { CaretPos = ctrl.selectionStart; } return (CaretPos); } function setCaretPosition(ctrl, pos) { if(ctrl.setSelectionRange) { ctrl.focus(); ctrl.setSelectionRange(pos,pos); } else if (ctrl.createTextRange) { var range = ctrl.createTextRange(); range.collapse(true); range.moveEnd('character', pos); range.moveStart('character', pos); range.select(); } } }}; 解决方案 Well, i think the best solution is with Vanilla Javascript. Check the value is UpperCase if not, get position, change value, set position. Easy.var stayUpperCase = function () { if(this.value != this.value.toUpperCase()){ var caretPos = getCaretPosition(this); this.value = this.value.toUpperCase(); setCaretPosition(this, caretPos); }};document.getElementById('myinput').addEventListener('keyup', stayUpperCase);document.getElementById('myinput').addEventListener('change', stayUpperCase);// Code from http://stackoverflow.com/questions/2897155/get-cursor-position-in-characters-within-a-text-input-fieldfunction getCaretPosition (elem) { // Initialize var caretPos = 0; // IE Support if (document.selection) { // Set focus on the element elem.focus (); // To get cursor position, get empty selection range var sel = document.selection.createRange (); // Move selection start to 0 position sel.moveStart ('character', -elem.value.length); // The caret position is selection length caretPos = sel.text.length; } // Firefox support else if (elem.selectionStart || elem.selectionStart == '0'){ caretPos = elem.selectionStart; } // Return results return (caretPos);}// Code from http://stackoverflow.com/questions/512528/set-cursor-position-in-html-textboxfunction setCaretPosition(elem, caretPos) { if(elem != null) { if(elem.createTextRange) { var range = elem.createTextRange(); range.move('character', caretPos); range.select(); } else { if(elem.selectionStart) { elem.focus(); elem.setSelectionRange(caretPos, caretPos); } else elem.focus(); } }}<input type="text" id="myinput"/>You can attach more keyboard events to make it looks smoother. 这篇关于如何在扩展器中更新Knockout js Observable时保留光标位置的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持! 10-22 03:38