Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: 修复移动端编辑模式双击光标位置不正确的问题 #11516

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 35 additions & 18 deletions packages/amis-editor-core/src/inlineEdit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,12 +92,12 @@ function startPlainTextEdit({
elem.focus();

let caretRange = event
? getMouseEventCaretRange(event)
? getMouseEventCaretRange(event, elem)
: createRangeAtTheEnd(elem);

// Set a timer to allow the selection to happen and the dust settle first
setTimeout(function () {
selectRange(caretRange);
selectRange(caretRange, elem);
}, 10);
}

Expand Down Expand Up @@ -188,12 +188,12 @@ async function startRichTextEdit({
origin = editor.html.get();

let caretRange = event
? getMouseEventCaretRange(event)
? getMouseEventCaretRange(event, elem)
: createRangeAtTheEnd(elem);

// Set a timer to allow the selection to happen and the dust settle first
setTimeout(function () {
selectRange(caretRange);
selectRange(caretRange, elem);
}, 10);
}
);
Expand All @@ -206,7 +206,7 @@ async function startRichTextEdit({
* @returns {Range} 创建的Range对象
*/
function createRangeAtTheEnd(elem: HTMLElement) {
const range = document.createRange();
const range = elem.ownerDocument.createRange();
range.selectNodeContents(elem);
range.collapse(false);
return range;
Expand All @@ -219,35 +219,49 @@ function createRangeAtTheEnd(elem: HTMLElement) {
* @param {MouseEvent} evt - 鼠标事件对象
* @returns {Range} 光标位置的Range对象
*/
function getMouseEventCaretRange(evt: MouseEvent) {
function getMouseEventCaretRange(evt: MouseEvent, elem: HTMLElement) {
let range,
x = evt.clientX,
y = evt.clientY;

const target = evt.target as HTMLElement;
const doc = elem.ownerDocument;

if (target.ownerDocument !== doc) {
// 如果点击事件来自iframe外部,需要调整坐标
const iframe = doc.defaultView?.frameElement as HTMLIFrameElement;

if (iframe) {
const rect = iframe.getBoundingClientRect();
x -= rect.left;
y -= rect.top;
}
}

// Try the simple IE way first
if ((document.body as any).createTextRange) {
range = (document.body as any).createTextRange();
if ((doc.body as any).createTextRange) {
range = (doc.body as any).createTextRange();
range.moveToPoint(x, y);
} else if (typeof document.createRange != 'undefined') {
} else if (typeof doc.createRange != 'undefined') {
// Try Mozilla's rangeOffset and rangeParent properties,
// which are exactly what we want
if (typeof (evt as any).rangeParent != 'undefined') {
range = document.createRange();
range = doc.createRange();
range.setStart((evt as any).rangeParent, (evt as any).rangeOffset);
range.collapse(true);
}

// Try the standards-based way next
else if ((document as any).caretPositionFromPoint) {
let pos: any = (document as any).caretPositionFromPoint(x, y);
range = document.createRange();
else if ((doc as any).caretPositionFromPoint) {
let pos: any = (doc as any).caretPositionFromPoint(x, y);
range = doc.createRange();
range.setStart(pos.offsetNode, pos.offset);
range.collapse(true);
}

// Next, the WebKit way
else if (document.caretRangeFromPoint) {
range = document.caretRangeFromPoint(x, y);
else if (doc.caretRangeFromPoint) {
range = doc.caretRangeFromPoint(x, y);
}
}

Expand All @@ -259,12 +273,15 @@ function getMouseEventCaretRange(evt: MouseEvent) {
* 支持IE和标准浏览器两种方式
* @param {Range} range - 要选中的Range对象
*/
function selectRange(range: any) {
function selectRange(range: any, elem: HTMLElement) {
const doc = elem.ownerDocument;
const win = doc.defaultView || (doc as any).parentWindow;

if (range) {
if (typeof range.select != 'undefined') {
range.select();
} else if (typeof window.getSelection != 'undefined') {
let sel: any = window.getSelection();
} else if (typeof win.getSelection != 'undefined') {
let sel: any = win.getSelection();
sel.removeAllRanges();
sel.addRange(range);
}
Expand Down
Loading