在SWT浏览器中执行脚本代码时,我发现了一个非常好奇的现象 我的窗口中有两个控件:一个列表和一个浏览器,并排放置(GridLayout.numColumns = 2)。
该列表包含一些标题,我希望稍后在HTML文档中导航。
private void setFocusToElement(String id) {
StringBuilder sb = new StringBuilder();
sb.append("var elem = document.getElementById('" + id + "');");
sb.append("if (elem) {");
sb.append(" elem.setAttribute('tabindex', '-1');");
sb.append(" elem.focus();");
sb.append("}");
browser.execute(sb.toString());
}
每次单击列表中的项目时都会调用该方法 到目前为止,标题已正确选择,执行符合我的期望。
但是现在焦点移动而没有我从列表到浏览器的交互 这是一个SWT错误还是我的错误?如何防止移动焦点?
+++ UPDATED +++
我的列表控件包含我尝试查找的ID,并在浏览器的HTML文档中选择标题h1 ... h6。
我需要将焦点设置在这样的标题上,以便不能使用.scrollIntoView()。
示例:
我有一个名为" myHeading-1"的列表条目。我点击这个项目,想要在webview中选择相应的标题(h1,列表中有id)。为此,我使用上面的JavaScript代码" myHeading-1"作为输入参数。
结果是我的列表控件失去了焦点。这对我来说有点不合逻辑因为我从不使用browser.setFocus()。我只使用了JavaScript焦点功能,所以不应该发生。
我的期望是:
选择了webview中的标题,但焦点仍然放在列表控件上。
好的,这里有一些代码可以证明我的意思。也许那么重现效果会更好:
public class Main {
private List list;
private Browser browser;
public Main() {
Display display = new Display();
Shell shell = new Shell(display);
shell.setLayout(new GridLayout(2, false));
shell.setSize(400, 200);
shell.setText("Demo");
list = new List(shell, SWT.BORDER | SWT.SINGLE);
list.add("rtrx_001d");
list.add("rtrx_003e");
list.setSelection(0);
list.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
setFocusToElement(list.getSelection()[0]);
}
});
browser = new Browser(shell, SWT.NONE);
try {
browser.setText(readAllLines(new File("C:\\workspace\\file.html")));
} catch (IOException e) {
System.err.println(e);
}
shell.open();
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) {
display.sleep();
}
}
display.dispose();
}
private String readAllLines(File file) throws IOException {
return readAllLines(file, StandardCharsets.UTF_8);
}
private String readAllLines(File file, Charset charset) throws IOException {
return readAllLines(new FileInputStream(file), charset);
}
private String readAllLines(InputStream istream, Charset charset) throws IOException {
StringBuilder sb = new StringBuilder();
BufferedReader reader = new BufferedReader(new InputStreamReader(istream, charset));
try {
String line;
while ((line = reader.readLine()) != null) {
sb.append(line);
sb.append('\n');
}
return sb.toString();
} finally {
try {
reader.close();
} catch (IOException e) {
}
}
}
private void setFocusToElement(String id) {
StringBuilder sb = new StringBuilder();
sb.append("var elem = document.getElementById('" + id + "');");
sb.append("if (elem) {");
sb.append(" elem.setAttribute('tabindex', '-1');");
sb.append(" elem.focus();");
sb.append("}");
browser.execute(sb.toString());
}
public static void main(String[] args) {
new Main();
}
}
这是我的HTML文档:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>My page</title>
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
</head>
<body>
<h1 class="title" id="nlzt_0001">
<a href="nlzt0002.smil#nlzt_0001">Introduction</a>
</h1>
<h1 id="rtrx_001d">
<a href="nlzt000a.smil#rtrx_001d">Summary</a>
</h1>
<h1 id="rtrx_001e">
<a href="nlzt000b.smil#rtrx_001e">First chapter</a>
</h1>
<h2 id="rtrx_001f">
<a href="nlzt000c.smil#rtrx_001f">1</a>
</h2>
<h1 id="rtrx_003e">
<a href="nlzt002b.smil#rtrx_003e">Second chapter</a>
</h1>
</body>
</html>
答案 0 :(得分:0)
您的Javascript代码明确地将元素与elem.focus()
集中在一起。这就是浏览器获得焦点的原因。
所有UI的共同之处在于,最多可以存在一个具有当前输入焦点的UI元素,即接收键盘事件的UI元素。浏览器中的HTML元素也是一个UI元素。如果您希望焦点与列表保持一致,则不得将HTML元素集中在浏览器中。
此外,我的实验表明,将焦点放在HTML元素(例如h1)上不一定会将元素滚动到视图中。
public static void main( String[] args ) {
String html = "<html><head></head><body>";
for( int i = 0; i < 100; i++ ) {
html += "<h2 id=\"id" + i + "\">This is header " + i + "</h2>";
}
html += "</body></html>";
Display display = new Display();
Shell shell = new Shell( display );
shell.setLayout( new GridLayout( 1, false ) );
Button button = new Button( shell, SWT.PUSH );
button.setText( "Focus header 17" );
Browser browser = new Browser( shell, SWT.BORDER );
browser.setText( html );
browser.setLayoutData( new GridData( SWT.FILL, SWT.FILL, true, true ) );
button.addListener( SWT.Selection, new Listener() {
@Override
public void handleEvent( Event event ) {
if( !browser.execute( "document.getElementById( 'id17' ).focus();" ) ) {
throw new RuntimeException( "Failed to execute Javascript" );
}
}
} );
shell.open();
while( !shell.isDisposed() ) {
if( !display.readAndDispatch() )
display.sleep();
}
display.dispose();
}
要将元素滚动到视图中(不提供焦点),请参阅此处:How do I scroll to an element using JavaScript?