UIWebView正在使用elementFromPoint()获取图像url

UIWebView getting image url with elementFromPoint()

本文关键字:获取 图像 url elementFromPoint UIWebView      更新时间:2023-09-26

我正试图使用UILongPressGestureRecognizer获取UIWebView中点击的图像的url。

我有点工作,但我不确定坐标是否关闭,或者只是在DOM中找不到img标记,因为它并不总是工作。

我使用的是这个代码:

int displayWidth = [[self.webView stringByEvaluatingJavaScriptFromString:@"window.outerWidth"] intValue];
CGFloat scale = self.webView.frame.size.width / displayWidth;
CGPoint pt = [gesture locationInView:self.webView];
pt.x /= scale;
pt.y /= scale;
NSString *imgURL = [NSString stringWithFormat:@"document.elementFromPoint(%f, %f).parentElement.getElementsByTagName('"img'")[0].src", pt.x, pt.y];
NSString *urlToSave = [self.webView stringByEvaluatingJavaScriptFromString:imgURL];

如果我使用的网站一开始是缩小的,并且在网格中有图像,然后放大并选择一个图像,我会得到页面左上角的图像,而不是点击的图像。不确定是缩放问题、偏移问题还是DOM问题?

编辑---------------

首先,坐标绝对不正确!如果我在UIWebView中点击网页上的一个点,我会得到以下结果:滚动Y:0点击点Y:89Y*=刻度+=滚动Y=86.8293

现在,如果我向上滚动页面,使我单击的点与顶部对齐(大约在y=0处),我会得到以下结果:滚动Y:144单击点Y:1Y*=刻度+=滚动Y=144.976

现在,在计算之前,滚动条似乎关闭了。点是89,但当滚动到该点时,滚动条显示144。为什么会这样?

我正在从window.pageYOffset 获取滚动。

将这2个javascript函数放入名为JSTools.js 的文件中

function getHTMLElementsAtPoint(x,y) {
var tags = "";
var e;
var offset = 0;
while ((tags.search(",(A|IMG),") < 0) && (offset < 20)) {
    tags = ",";
    e = document.elementFromPoint(x,y+offset);
    while (e) {
        if (e.tagName) {
            tags += e.tagName + ',';
        }
        e = e.parentNode;
    }
    if (tags.search(",(A|IMG),") < 0) {
        e = document.elementFromPoint(x,y-offset);
        while (e) {
            if (e.tagName) {
                tags += e.tagName + ',';
            }
            e = e.parentNode;
        }
    }
    offset++;
}
return tags;}
function getLinkSRCAtPoint(x,y) {
var tags = "";
var e = "";
var offset = 0;
while ((tags.length == 0) && (offset < 20)) {
    e = document.elementFromPoint(x,y+offset);
    while (e) {
        if (e.src) {
            tags += e.src;
            break;
        }
        e = e.parentNode;
    }
    if (tags.length == 0) {
        e = document.elementFromPoint(x,y-offset);
        while (e) {
            if (e.src) {
                tags += e.src;
                break;
            }
            e = e.parentNode;
        }
    }
    offset++;
}
return tags;}

然后在你的控制器

- (void)longPressRecognized:(UILongPressGestureRecognizer *)gestureRecognizer {
if (gestureRecognizer.state == UIGestureRecognizerStateBegan) {
    CGPoint point = [gestureRecognizer locationInView:webView];
    longpressTouchedPoint = point;
    // convert point from view to HTML coordinate system
    CGSize viewSize = [webView frame].size;
    CGSize windowSize = [webView windowSize];
    CGFloat f = windowSize.width / viewSize.width;
    if ([[[UIDevice currentDevice] systemVersion] doubleValue] >= 5.) {
        point.x = point.x * f;
        point.y = point.y * f;
    } else {
        // On iOS 4 and previous, document.elementFromPoint is not taking
        // offset into account, we have to handle it
        CGPoint offset = [webView scrollOffset];
        point.x = point.x * f + offset.x;
        point.y = point.y * f + offset.y;
    }
    // Load the JavaScript code from the Resources and inject it into the web page
    NSString *path = [[NSBundle mainBundle] pathForResource:@"JSTools" ofType:@"js"];
    NSString *jsCode = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:nil];
    [webView stringByEvaluatingJavaScriptFromString: jsCode];

    // call js functions
    NSString *tags = [webView stringByEvaluatingJavaScriptFromString:
                      [NSString stringWithFormat:@"getHTMLElementsAtPoint(%i,%i);",(NSInteger)point.x,(NSInteger)point.y]];
    NSString *tagsSRC = [webView stringByEvaluatingJavaScriptFromString:
                         [NSString stringWithFormat:@"getLinkSRCAtPoint(%i,%i);",(NSInteger)point.x,(NSInteger)point.y]];
    NSLog(@"src : %@",tags);
    NSLog(@"src : %@",tagsSRC);
    NSString *url = nil;
    if ([tags rangeOfString:@",IMG,"].location != NSNotFound) {
        url = tagsSRC;    // Here is the image url!
    }

多种来源混合,值得网络社区称赞!

编辑

您还必须在uiwebview上创建一个具有以下两个功能的类别:

- (CGSize)windowSize {
CGSize size;
size.width = [[self stringByEvaluatingJavaScriptFromString:@"window.innerWidth"] integerValue];
size.height = [[self stringByEvaluatingJavaScriptFromString:@"window.innerHeight"] integerValue];
return size;}
- (CGPoint)scrollOffset {
CGPoint pt;
pt.x = [[self stringByEvaluatingJavaScriptFromString:@"window.pageXOffset"] integerValue];
pt.y = [[self stringByEvaluatingJavaScriptFromString:@"window.pageYOffset"] integerValue];
return pt;}

我最近也实现了一个类似的目标,但我没有确定"触摸"坐标。

如果您有修改html/javascript源代码的权限,我的答案会有所帮助。

我做了什么:

在每个图像<img... html DOM元素上,我放置onClick javascript处理程序来更改window.location

f.e

javascript function clickedImage(imageURL) {
    window.location = "customScheme://"+imageURL; // attached image url to be able to read it inside `UIWebView`
}

UIWebView委托的方法中忽略上面的链接,但是,我们可以获得图像URL。

- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
  if ([[request.URL scheme] isEqualToString:@"customScheme"]) {
        //Fetching image URL
        NSLog(@"Clicked on image with URL %@", [request.URL host])
        ...
        // Always return NO not to allow `UIWebView` process such links
        return NO; 
    }
    ....
}

很抱歉,如果这种方法不完全符合你的问题,但我想这是一个你可以遵循并深入挖掘的选项。

小提示:要使用UILongPressGestureRecognizer,您可以通过制作javascript来模拟这种行为:在JavaScript中长按?

您可以通过以下代码获取元素

        <script type="text/javascript">
            (function($) {
             $.fn.longClick = function(callback, timeout) {
             var timer;
             timeout = timeout || 500;
             $(this).mousedown(function(e) {
                               timer = setTimeout(function() { callback(e.offsetX,e.offsetY); }, timeout);
                               return false;
                               });
             $(document).mouseup(function() {
                                 clearTimeout(timer);
                                 return false;
                                 });
             };
             })(jQuery);

            $(window).longClick(function(x,y)
            {
              var element = document.elementFromPoint(x, y);
              alert(nodeToString(element));
            },600);

            function nodeToString ( node ) {
                var tmpNode = document.createElement( "div" );
                tmpNode.appendChild( node.cloneNode( true ) );
                var str = tmpNode.innerHTML;
                tmpNode = node = null; // prevent memory leaks in IE
                return str;
            }
        </script>

这只是js代码。mousedown和mouseup不适用于ios。您需要为ios webView使用其他替代事件。