Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/iphone/45.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用“stringByEvaluatingJavaScriptFromString”单击UIWebView中的链接_Javascript_Iphone_Objective C_Ios_Xcode - Fatal编程技术网

使用“stringByEvaluatingJavaScriptFromString”单击UIWebView中的链接

使用“stringByEvaluatingJavaScriptFromString”单击UIWebView中的链接,javascript,iphone,objective-c,ios,xcode,Javascript,Iphone,Objective C,Ios,Xcode,如何在UIWebView中使用stringByEvaluatingJavaScriptFromString方法单击链接?实际的超链接本身每次都是不同的,但是测试代码中的Test语句总是相同的 我该怎么做呢?我有一个建议,就是做以下的事情,但这不起作用,也没有任何作用: var fonts = document.getElementsByTagName('font'); for(i=0;i<fonts.length;i++) { if (fonts[i].innerHTML == 'Te

如何在UIWebView中使用stringByEvaluatingJavaScriptFromString方法单击链接?实际的超链接本身每次都是不同的,但是测试代码中的Test语句总是相同的

我该怎么做呢?我有一个建议,就是做以下的事情,但这不起作用,也没有任何作用:

var fonts = document.getElementsByTagName('font');
for(i=0;i<fonts.length;i++) {
  if (fonts[i].innerHTML == 'Test') {
  fonts[i].parentNode.childNodes[0].click();
  break;
 }
} 

我已经创建了一个示例应用程序,其功能来自hooleyhoop在评论中提到的另一个SO问题

这就是我的结局:

- (void)webViewDidFinishLoad:(UIWebView *)wv {
    // Called when the website has finished loading and triggers the JS code
    NSString *javascript = @"function simulate(element, eventName) \
    { \
        var options = extend(defaultOptions, arguments[2] || {}); \
        var oEvent, eventType = null; \
        for (var name in eventMatchers) \
        { \
            if (eventMatchers[name].test(eventName)) { \
                eventType = name; break; \
            } \
        } \
        if (!eventType) { \
            alert('Only HTMLEvents and MouseEvents interfaces are supported'); \
        } \
        if (document.createEvent) \
        { \
            oEvent = document.createEvent(eventType); \
            if (eventType == 'HTMLEvents') \
            { \
                oEvent.initEvent(eventName, options.bubbles, options.cancelable); \
            } \
            else \
            { \
            oEvent.initMouseEvent(eventName, options.bubbles, options.cancelable, document.defaultView, options.button, options.pointerX, options.pointerY, options.pointerX, options.pointerY, options.ctrlKey, options.altKey, options.shiftKey, options.metaKey, options.button, element); \
            } \
            element.dispatchEvent(oEvent); \
        } \
        else \
        { \
            options.clientX = options.pointerX; \
            options.clientY = options.pointerY; \
            var evt = document.createEventObject(); \
            oEvent = extend(evt, options); \
            element.fireEvent('on' + eventName, oEvent); \
        } \
        return element; \
    } \
    function extend(destination, source) { \
        for (var property in source) \
            destination[property] = source[property]; \
        \
        return destination; \
    } \
    var eventMatchers = { \
        'HTMLEvents': /^(?:load|unload|abort|error|select|change|submit|reset|focus|blur|resize|scroll)$/, \
        'MouseEvents': /^(?:click|dblclick|mouse(?:down|up|over|move|out))$/ \
    }; \
    var defaultOptions = { \
        pointerX: 0, \
        pointerY: 0, \
        button: 0, \
        ctrlKey: false, \
        altKey: false, \
        shiftKey: false, \
        metaKey: false, \
        bubbles: true, \
        cancelable: true \
    }; \
    window.setTimeout(function() { \
        var links = document.getElementsByTagName('a'); \
        for(var i in links) { \
            if(links[i].innerHTML == 'Test') { \
                simulate(links[i], 'click'); \
            } \
        } \
    },1);";
    // Execute JS
    [webView stringByEvaluatingJavaScriptFromString:javascript];
}
测试HTML

<html>
    <head>
        <title>Testpage</title>
    </head>
    <body>
        <a href="http://www.google.com">I'm linking to google.com</a><br />
        <a href="http://www.stackoverflow.com">Test</a>
    </body>
</html>
-voidwebViewDidFinishLoad:UIWebView*wv

这是UIWebView的委托函数,web视图加载完网站后,会立即调用该函数

NSString*javascript=@

这就是我构建JS代码的地方,在开始的时候,从另一个SO问题开始的函数触发了点击。最后,我放置了一个超时,执行查找所有a标记的部分,循环遍历它们,检查是否是innerHTML文本是Test,若是这样,它调用simulate函数,其中a元素作为第一个参数,eventtype作为第二个参数。砰的一声,链接被点击了

我使用了超时,因为它导致直接执行JS时出现问题,似乎UIWebView需要一些时间,直到函数simulate可用

干杯,
Björn

我已经创建了一个示例应用程序,其功能来自hooleyhoop在评论中提到的另一个SO问题

这就是我的结局:

- (void)webViewDidFinishLoad:(UIWebView *)wv {
    // Called when the website has finished loading and triggers the JS code
    NSString *javascript = @"function simulate(element, eventName) \
    { \
        var options = extend(defaultOptions, arguments[2] || {}); \
        var oEvent, eventType = null; \
        for (var name in eventMatchers) \
        { \
            if (eventMatchers[name].test(eventName)) { \
                eventType = name; break; \
            } \
        } \
        if (!eventType) { \
            alert('Only HTMLEvents and MouseEvents interfaces are supported'); \
        } \
        if (document.createEvent) \
        { \
            oEvent = document.createEvent(eventType); \
            if (eventType == 'HTMLEvents') \
            { \
                oEvent.initEvent(eventName, options.bubbles, options.cancelable); \
            } \
            else \
            { \
            oEvent.initMouseEvent(eventName, options.bubbles, options.cancelable, document.defaultView, options.button, options.pointerX, options.pointerY, options.pointerX, options.pointerY, options.ctrlKey, options.altKey, options.shiftKey, options.metaKey, options.button, element); \
            } \
            element.dispatchEvent(oEvent); \
        } \
        else \
        { \
            options.clientX = options.pointerX; \
            options.clientY = options.pointerY; \
            var evt = document.createEventObject(); \
            oEvent = extend(evt, options); \
            element.fireEvent('on' + eventName, oEvent); \
        } \
        return element; \
    } \
    function extend(destination, source) { \
        for (var property in source) \
            destination[property] = source[property]; \
        \
        return destination; \
    } \
    var eventMatchers = { \
        'HTMLEvents': /^(?:load|unload|abort|error|select|change|submit|reset|focus|blur|resize|scroll)$/, \
        'MouseEvents': /^(?:click|dblclick|mouse(?:down|up|over|move|out))$/ \
    }; \
    var defaultOptions = { \
        pointerX: 0, \
        pointerY: 0, \
        button: 0, \
        ctrlKey: false, \
        altKey: false, \
        shiftKey: false, \
        metaKey: false, \
        bubbles: true, \
        cancelable: true \
    }; \
    window.setTimeout(function() { \
        var links = document.getElementsByTagName('a'); \
        for(var i in links) { \
            if(links[i].innerHTML == 'Test') { \
                simulate(links[i], 'click'); \
            } \
        } \
    },1);";
    // Execute JS
    [webView stringByEvaluatingJavaScriptFromString:javascript];
}
测试HTML

<html>
    <head>
        <title>Testpage</title>
    </head>
    <body>
        <a href="http://www.google.com">I'm linking to google.com</a><br />
        <a href="http://www.stackoverflow.com">Test</a>
    </body>
</html>
-voidwebViewDidFinishLoad:UIWebView*wv

这是UIWebView的委托函数,web视图加载完网站后,会立即调用该函数

NSString*javascript=@

这就是我构建JS代码的地方,在开始的时候,从另一个SO问题开始的函数触发了点击。最后,我放置了一个超时,执行查找所有a标记的部分,循环遍历它们,检查是否是innerHTML文本是Test,若是这样,它调用simulate函数,其中a元素作为第一个参数,eventtype作为第二个参数。砰的一声,链接被点击了

我使用了超时,因为它导致直接执行JS时出现问题,似乎UIWebView需要一些时间,直到函数simulate可用

干杯,
Björn

看起来您已经找到了答案,包括您需要的Objective-C代码,但我可以想象,对于javascript,您可以简单地触发链接的onclick内容或导航到适当的url,而无需费劲地模拟鼠标点击。诚然,我没有在iOS应用程序中测试过这一点,但可以尝试一下:

var links = document.getElementsByTagName('a');
for(i=0;i<links.length;i++) {
  if (links[i].innerHTML.indexOf('Test') != -1) {
  clickLink(links[i]);
  break;
 }
} 

function clickLink(linkobj) {
 var onclickHandler = linkobj.getAttribute('onclick');
 if (onclickHandler == null) window.location = linkobj.getAttribute('href').replace(/^\s\s*/, '').replace(/\s\s*$/, '');
 else eval(onclickHandler(linkobj));
}

jsFiddle使用您的示例代码演示了这一点:

看起来您已经有了一个答案,其中包括您需要的Objective-C代码,但我可以想象,对于javascript,您可以简单地触发链接onclick的内容或导航到适当的url,而不用费劲地模拟鼠标单击。诚然,我没有在iOS应用程序中测试过这一点,但可以尝试一下:

var links = document.getElementsByTagName('a');
for(i=0;i<links.length;i++) {
  if (links[i].innerHTML.indexOf('Test') != -1) {
  clickLink(links[i]);
  break;
 }
} 

function clickLink(linkobj) {
 var onclickHandler = linkobj.getAttribute('onclick');
 if (onclickHandler == null) window.location = linkobj.getAttribute('href').replace(/^\s\s*/, '').replace(/\s\s*$/, '');
 else eval(onclickHandler(linkobj));
}

jsFiddle使用示例代码演示了这一点:

您是要单击链接还是要在链接的URL处加载页面?看到了吗?问题是,我没有编辑页面的权限,并且它没有任何ID或任何东西。我需要找到网页中的文本,然后点击与该文本相关联的链接…SO链接显示如何点击链接。无需编辑页面-所有代码都进入传递给stringByEvaluatingJavaScriptFromString的字符串中。如果你的问题是找到链接。。这本身就是一个不同的问题。这将涉及到像你在问题中那样迭代页面上的所有链接。。。这就是问题所在。我如何在页面上搜索文本,例如,测试然后单击与其关联的超链接?您想单击链接还是想在链接的URL处加载页面?问题是,我没有编辑页面的权限,并且它没有任何ID或任何东西。我需要找到网页中的文本,然后点击与该文本相关联的链接…SO链接显示如何点击链接。无需编辑页面-所有代码都进入传递给stringByEvaluatingJavaScriptFromString的字符串中。如果你的问题是找到链接。。这本身就是一个不同的问题。这将涉及到像你在问题中那样迭代页面上的所有链接。。。这就是问题所在。如何在页面上搜索文本(例如测试),然后单击与之相关的超链接?谢谢您的回答!如果链接文本没有ID或任何东西,只有纯文本,这会起作用吗-是的,会的,我添加了用于
测试我的答案。你也可以用David的JS代码代替我的,它小得多,做同样的事情-谢谢你的回答!如果链接文本没有ID或任何东西,只有纯文本,这会起作用吗-是的,它会的,我在我的答案中添加了我用于测试的HTML代码。你也可以使用David的JS代码而不是我的,它小得多,并且做同样的事情-不幸的是,你的代码对我不起作用。它只是停留在同一页上?@pixelbitlabs你能发布一点HTML源代码,其中包括你试图点击的链接之一吗?我发布的代码应该可以工作,但如果没有看到任何代码,就很难准确地知道您的情况。请注意,我知道这听起来很明显,我并没有试图同时单击它们。我刚在“上一天”试过测试,但没有成功。@pixelbitlabs你有错误吗?有什么事吗?如果您将js替换为警报“Hello World!”;这样行吗?那么alertlinks.length;?alertlinks[i];?与此无关,代码中的最后一个stringWithFormat是不必要的。@pixelbitlabs我很想进一步帮助您,但我不知所措-根据您提供的示例数据,我的Javascript工作正常。我们还从另一个用户那里验证了它是否在iOS应用程序的上下文中工作,并且通过设置警报,您能够亲自看到Javascript正在您的应用程序中执行。如果不坐在你的代码前,我不知道还能为你做些什么。如果您只执行window.location,会怎么样http://apple.com/'; 和/或window.location=您的URL之一?可能有助于缩小范围。不幸的是,您的代码不适合我。它只是停留在同一页上?@pixelbitlabs你能发布一点HTML源代码,其中包括你试图点击的链接之一吗?我发布的代码应该可以工作,但如果没有看到任何代码,就很难准确地知道您的情况。请注意,我知道这听起来很明显,我并没有试图同时单击它们。我刚在“上一天”试过测试,但没有成功。@pixelbitlabs你有错误吗?有什么事吗?如果您将js替换为警报“Hello World!”;这样行吗?那么alertlinks.length;?alertlinks[i];?与此无关,代码中的最后一个stringWithFormat是不必要的。@pixelbitlabs我很想进一步帮助您,但我不知所措-根据您提供的示例数据,我的Javascript工作正常。我们还从另一个用户那里验证了它是否在iOS应用程序的上下文中工作,并且通过设置警报,您能够亲自看到Javascript正在您的应用程序中执行。如果不坐在你的代码前,我不知道还能为你做些什么。如果您只执行window.location,会怎么样http://apple.com/'; 和/或window.location=您的URL之一?可能有助于缩小范围。