4

我有一个带有一些基本 html 的 UIWebView,它充当一个简单的编辑器。

// in initWithFrame: of UIView subclass.
_editorHTML = [@"<!doctype html>"
                   "<html>"
                   "<head>"
                   "<meta name=\"viewport\" content=\"width=device-width,initial-scale=1\">"
                   "<style type=\"text/css\">"
                   "#content { font-family:Arial, Helvetica, sans-serif; font-size:1em; } "
                   "</style>"
                   "<script type=\"text/javascript\">"
                   "function load()"
                   "{"
                   "    window.location.href = 'ready://' + document.body.offsetHeight;"
                   "}"
                   "</script>"
                   "</head>"
                   "<body id=\"bodyDiv\" onload=\"load()\">"
                   "<div id=\"content\" contenteditable=\"true\">%@</div>"
                   "</body>"
                   "</html>" retain];

_webView = [[UIWebView alloc] initWithFrame:CGRectMake(0, 0, frame.size.width, frame.size.height)];
_webView.delegate = self;
_webView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
_webView.scrollView.bounces = NO;
[_webView loadHTMLString:[NSString stringWithFormat:_editorHTML, @""] baseURL:[NSURL fileURLWithPath:directory]];

- (BOOL) webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
    NSURL *url = [request URL];
    if (navigationType == UIWebViewNavigationTypeOther) {
        if ([[url scheme] isEqualToString:@"ready"]) {

            int height = (int)_webView.frame.size.height;
            [webView stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:@"document.getElementById('content').style.minHeight = '%dpx'", height - WEBVIEW_DIVHEIGHT_OFFSET]];

            return NO;
        }
    }
    return YES;
}

那么,如何确定我的 div 中的光标位置,以便我可以更新我的 scrollView 以确保内容在 UIKeyboard 上方可见,从而不必让用户手动滚动以保持文本可见?

4

3 回答 3

7

您可以从选择中获取所选范围并使用其getClientRects()方法。

现场演示:http: //jsfiddle.net/timdown/xMEjD/

代码:

function getCaretClientPosition() {
    var x = 0, y = 0;
    var sel = window.getSelection();
    if (sel.rangeCount) {
        var range = sel.getRangeAt(0);
        if (range.getClientRects) {
            var rects = range.getClientRects();
            if (rects.length > 0) {
                x = rects[0].left;
                y = rects[0].top;
            }
        }
    }
    return { x: x, y: y };
}
于 2012-06-20T20:13:43.573 回答
5

@timdown 有趣的是,您的脚本总是返回 0,0 作为行首。[question] 中的脚本:浏览器页面中选定文本的坐标确实返回正确的 Y 值。

在这里重复以方便搜索:

function getSelectionCoords() {
    var sel = document.selection, range;
    var x = 0, y = 0;
    if (sel) {
        if (sel.type != "Control") {
            range = sel.createRange();
            range.collapse(true);
            x = range.boundingLeft;
            y = range.boundingTop;
        }
    } else if (window.getSelection) {
        sel = window.getSelection();
        if (sel.rangeCount) {
            range = sel.getRangeAt(0).cloneRange();
            if (range.getClientRects) {
                range.collapse(true);
                var rect = range.getClientRects()[0];
                x = rect.left;
                y = rect.top;
            }
        }
    }
    return { x: x, y: y };
}
于 2012-09-06T12:49:02.310 回答
1

该解决方案是公认答案的演变。修复了 WebKit 中的 newLine 问题。

function getCaretClientPosition() {
    var x = 0, y = 0;
    var sel = window.getSelection();
    if (sel.rangeCount) {

        var range = sel.getRangeAt(0);
        var needsToWorkAroundNewlineBug = (range.startContainer.nodeName.toLowerCase() == 'p'
                                           && range.startOffset == 0);

        if (needsToWorkAroundNewlineBug) {
            x = range.startContainer.offsetLeft;
            y = range.startContainer.offsetTop;
        } else {
            if (range.getClientRects) {
                var rects = range.getClientRects();
                if (rects.length > 0) {
                    x = rects[0].left;
                    y = rects[0].top;
                }
            }
        }
    }
    return { x: x, y: y };
}
于 2014-10-03T14:31:41.140 回答