Angular8+Kendo UI带内嵌chips的自定义输入框光标定位问题求助
解决方法
你遇到的光标无法定位的问题,是因为contenteditable容器插入非文本的chip元素后,没有预留可输入的文本点位,同时浏览器不会主动把光标移动到新增元素后方,需要你手动调用浏览器的选区API处理。
你可以按照以下方式修改addChip方法:
addChip(event: Event) { this.selectedValue = event; const inputEl = document.querySelector('#inputArea') as HTMLElement; // 先让输入容器获得焦点,避免后续选区操作失效 inputEl.focus(); const closeButton = document.createElement('span'); closeButton.classList.add('chip-close-button', 'k-icon', 'k-i-close-circle'); // 把当前chip传入删除方法,避免多chip场景下删错元素 closeButton.addEventListener('click', () => this.remove(chip)); const textNode = document.createTextNode(this.selectedValue?.text) const chip = document.createElement('span') KENDO_CHIP_CONFIG.attributes.forEach(HTMLattribute => { chip.setAttribute(HTMLattribute.attribute, HTMLattribute.value); }) chip.appendChild(textNode) chip.appendChild(closeButton) chip.classList.add('chip') // 如果你需要在当前光标位置插入chip,而不是固定追加到末尾,可以替换下面的appendChild逻辑: // const selection = window.getSelection(); // if (selection && selection.rangeCount > 0) { // const range = selection.getRangeAt(0); // range.deleteContents(); // range.insertNode(chip); // } else { // inputEl.appendChild(chip); // } inputEl.appendChild(chip); // 插入不换行空白文本节点,给光标提供附着位置,不会被浏览器自动折叠 const trailingSpace = document.createTextNode('\u00A0'); inputEl.appendChild(trailingSpace); // 手动定位光标到空白文本节点后方 const range = document.createRange(); const sel = window.getSelection(); range.setStartAfter(trailingSpace); range.collapse(true); sel?.removeAllRanges(); sel?.addRange(range); } // 修改删除方法,支持删除指定chip,适配多chip场景 public remove(targetChip: HTMLElement): void { targetChip.remove() this.selectedValue = null; }
额外注意点
- 你现在直接给
contenteditable的span绑定formControl是不会生效的,Angular的响应式表单默认只适配原生输入控件,如果你需要表单状态能正常绑定,需要自定义实现ControlValueAccessor接口。 - 如果需要支持在文本中间任意位置插入chip,可以放开上面代码中注释的「光标位置插入」逻辑,替换原本的
appendChild操作即可。
内容的提问来源于stack exchange,提问作者jsdev2023
相关产品推荐
相关产品推荐

