Мало знаний, большой вызов! Эта статья участвует в "Необходимые знания для программистов«Творческая деятельность
Эта статья приняла участие"Проект "Звезда раскопок"", чтобы выиграть творческий подарочный пакет и бросить вызов творческим поощрительным деньгам.
предисловие
Вчера начальник неожиданно пришел ко мне на рабочее место и дал мне форму запроса:
В эту форму необходимо добавить поле "правило". Фон будет содержать содержимое по умолчанию. Вы помещаете это содержимое в поле ввода по умолчанию. Требование состоит в том, что пользователь может изменять только содержимое в скобках, а другое содержимое не может быть изменены.
Слышала голова, у меня до сих пор такой спрос!!Миллионы в душе проходят~а я не могу,начальник деньги дает,мне надо работать. Немного подумав, на самом деле функция этого требования все-таки должна быть реализована, и я начал это делать!
идеи
Как правило, поле ввода может свободно вводить текст, так как же ограничить поле ввода для ввода текста?Нам нужно ввести текст в поле ввода.el-inputнастраиватьvalueАтрибуты,valueпросто следуйте绑定的数据изменяется, в то время как связанные данные меняются в输入事件чтобы справиться с этим. Здесь нам нужно отказаться от предыдущего использованияv-modelспособ обновления значения изменения.Код выглядит следующим образом:
<el-input
size="small"
on-input={v => {
item.__onChange && item.__onChange(v, form[item.__key], { form, key: item.__key })
}}
ref = { item.__key }
props={{
value: form[item.__key],
placeholder: '输入内容信息',
...item
}}
></el-input>
тогда нужно__onChangeКакие правила в нем прописаны, чтобы пользователи могли вводить контент только в скобках внутри контента, а другой контент оставался только читаемым? Поскольку другой контент只读, в скобках указано可写Содержимое круглых скобок, далее приходит идея, мы можем удалить измененное содержимое в круглых скобках, а затем при вводе давайте сравним, все ли содержимое после удаления круглых скобок такое же, как и предыдущее содержимое Удалим круглые скобки Содержимое равны, если они равны, это доказывает, что содержимое, введенное пользователем, вводится в круглых скобках, и данные обновляются до данных, введенных пользователем. В противном случае он не будет обновляться.
разработка правил
Теперь, когда у нас есть идея, давайте начнем!
this.formArr = new createForm()
.createInput({
__key: 'rule',
label: '规则',
type: 'textarea',
__notAutoInput: true,
__defaultVal: '今日信息: 娱乐新闻(XX)条, 体育新闻(XX)条',
__onChange: (inputVal, val, { form, key }) => {
// inputVal 用户输入的内容
// val 目前页面显示的内容(输入之前的内容)
let reg = /\([\w\W]*?\)|([\w\W]*?)/g // 兼容中英文两种括号
let input = inputVal.replace(reg, '') // 去掉现在在输入的内容括号里边的空格
let value = val && val.replace(reg, '') // 去掉括号里边原来的内容的空格
if (input === value) { // 比对去掉空格内容后,是否一致,如果是一致的话,则说明没有修改空格以外的内容,则让用户修改
form[key] = inputVal // 数据更新成用户输入的内容
}
}
}).form
Что ж, наша функция в основном завершена. Ха-ха. Я пошел сдавать функцию и показал ее начальнику, начальник попробовал и молча сказал:
"你这基本功能是实现了,但是总体体验不是太好呀,我在小括号以外的地方输入的时候,老会跳到文字的最后面去了,你再去把这里优化优化吧!" , я... (тысячу раз опущено здесь), после того, как я выплеснул свои эмоции, моя жизнь все равно должна пойти ко дну. Итак, давайте искать информацию, чтобы увидеть, есть ли решение.
Введение в API оптимизации
Наконец, с помощью Google я нашел API, который может достичь этой оптимизации.
setSelectionRange
HTMLInputElement.setSelectionRangeспособ установки<input>или<textarea>Начальная и конечная позиция выделенного в данный момент текста в элементе
В сочетании с соответствующими API они могут реализовать переход фокуса к местоположению указанного контента. После того, как у нас есть пригодный для использования API, давайте напишем демо, чтобы попробовать его:
<body>
<textarea id="txtUserID" oninput="inputHandle()"></textarea>
<script>
var textbox = document.getElementById("txtUserID")
textbox.value = '123456789'
function setFocus(textbox, index) {
if (textbox.setSelectionRange) {
textbox.focus();
textbox.setSelectionRange(index, index + 3);
}
}
function inputHandle(v) {
setFocus(textbox, 2)
}
</script>
</body>
использовать
setSelectionRangeМетод передает два параметра.Если начальный параметр и последний параметр несовместимы, могут быть реализованы произвольные данные.选中, если начальный параметр и последний параметр совпадают, вы можете установить фокус в любую позицию.
Оптимизация разработки
В демонстрации мы знаем, что для установки фокуса нам нужно получить объект dom поля ввода и позицию пользовательского ввода, так как же получить позицию пользовательского ввода? Мы можем выполнять содержимое, отображаемое на странице, и содержимое, которое пользователь вводит посимвольно.对比,до发现两个字符串对比出不一样символ, выйти из цикла и вернуть текущий индекс строки. это索引的位置减一Это позиция, которую ввел пользователь, далее мы напишем функцию сравнения строк
// 找到索引
findIndex (newVal, oldVal) {
let newValArr = newVal.split('')
let oldValArr = oldVal.split('')
for (let i = 1; i <= newVal.length; i++) {
let newItem = newValArr.slice(0, i)
let oldItem = oldValArr.slice(0, i)
if (JSON.stringify(newItem) !== JSON.stringify(oldItem)) {
return i
}
}
return newVal.length
}
Затем следует воспользоваться методом установки фокуса, который был написан в демо ранее.
// 设置焦点
setFocus (textbox, index) {
if (textbox.createTextRange) {
var r = textbox.createTextRange();
r.collapse(true);
r.moveStart('character', index);
r.select()
} else if (textbox.setSelectionRange) {
textbox.focus();
textbox.setSelectionRange(index, index);
}
}
Наконец, мы добавляем к ранее написанной форме, что если пользователь не вводит в круглых скобках,比对字符串,а также设置焦点основная логика.
this.formArr = new createForm()
.createInput({
__key: 'rule',
label: '规则',
type: 'textarea',
__notAutoInput: true,
__defaultVal: '今日信息: 娱乐新闻(XX)条, 体育新闻(XX)条',
__onChange: (inputVal, val, { form, key }) => {
let reg = /\([\w\W]*?\)|([\w\W]*?)/g // 兼容中英文两种括号
let input = inputVal.replace(reg, '') // 去掉现在在输入的内容括号里边的空格
let value = val && val.replace(reg, '') // 去掉括号里边原来的内容的空格
if (input === value) { // 比对去掉空格内容后,是否一致,如果是一致的话,则说明没有修改空格以外的内容,则让用户修改
form[key] = inputVal
} else {
// 如果用户没有在小括号内输入的时候,比对字符串,并设置焦点的主逻辑
let index = self.findIndex(inputVal, val)
let dom = self.$refs.myForm.$el.querySelector(`textarea[aria-label=规则]`)
if (dom && (index || index === 0)) {
// 由于
setTimeout(() => {
self.setFocus(dom, index - 1)
}, 10)
}
}
}
}).form
Конечный эффект:
напиши в конце
Хорошо, тогда это небольшая проблема, с которой я столкнулся в реальной работе. Хотя я чувствую, что какое-то время меня усложняли, и хотя поиск информации занял некоторое время, в конце концов, результат все равно приятный. Написав, босс доволен, и я тоже чувствую, что чему-то научился. Еще вполне доволен. Ха-ха!