使用“stringByEvaluatingJavaScriptFromString”单击UIWebView中的链接
如何在UIWebView中使用stringByEvaluatingJavaScriptFromString方法单击链接?实际的超链接本身每次都是不同的,但是测试代码中的Test语句总是相同的 我该怎么做呢?我有一个建议,就是做以下的事情,但这不起作用,也没有任何作用:使用“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
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之一?可能有助于缩小范围。