如何在UIWebView中使用stringByEvaluatingJavaScriptFromString方法单击链接?实际的超链接本身每次都不同,但测试代码中的措辞(“测试”)总是相同的。
我该怎么做呢?我有一个建议要做以下事情(这不起作用,也没有做任何事情):
var fonts = document.getElementsByTagName('font');
for(i=0;i<fonts.length;i++) {
if (fonts[i].innerHTML == 'Test') {
fonts[i].parentNode.childNodes[0].click();
break;
}
}
答案 0 :(得分:4)
看起来你有一个答案,包括你需要的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));
}
顺便说一句,这段代码中有一个eval将运行onclick处理程序的内容。这可能不安全。如果您只需要导航到链接指定的位置,那么您可能想要删除处理onclick的部分。
下面打印了一个更简单的版本(因为您的示例代码似乎不需要处理onclick),这可能更容易使用。在这种情况下,我在延迟1秒后调用它,但实际上,因为看起来这个代码是为响应iOS端的触发而运行的(按钮点击?),所以你不应该使用延迟而只是等待启用触发器直到加载完成 - webViewDidFinishLoad
。
function clickLink() {
var links = document.getElementsByTagName('a');
for (i = 0; i < links.length; i++) {
if (links[i].innerHTML.indexOf('Prev') != -1) {
window.location = links[i].getAttribute('href').replace(/^\s\s*/, '').replace(/\s\s*$/, '');
break;
}
}
}
setTimeout(clickLink, 1000);
jsFiddle使用您的示例代码演示了这一点:http://jsfiddle.net/fzKL7/5/
答案 1 :(得分:1)
我创建了一个示例应用程序,其中包含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>
- (void)webViewDidFinishLoad:(UIWebView *)wv
这是UIWebView的委托函数,只要Web视图加载完网站就会调用它。
NSString * javascript = @“...”
这就是我构建JS代码的重点,在开始时,来自触发点击的其他SO问题的函数。最后,我放置了一个超时,执行查找所有“a”标记的部分,循环遍历它们,检查它的innerHTML文本是否为“Test”,如果是这种情况,它会调用simulate
函数一个元素作为第一个参数,eventtype作为第二个参数。轰隆隆,点击链接。
我使用了超时,因为它导致直接执行JS的问题,似乎UIWebView需要一些时间,直到函数模拟可用。
干杯, 的Björn