I am executing a javascript code in my webview of JavaFX application. I need to make it execute repeatedly whenever there is a mouse click and get the element details into a java variable. I'm using the below code and using Firebug Lite. In Firebug console, required items are printing. But I want it returned to java application.
engine.documentProperty().addListener(new ChangeListener<Document>() {
@Override public void changed(ObservableValue<? extends Document> prop, Document oldDoc, Document newDoc) {
enableFirebug(engine);
Object obj=engine.executeScript("var lastElement = null; "
+ "document.addEventListener('click', function(e) {"
+ "if (e.target != lastElement) {"
+ "lastElement = e.target;"
+ "console.log(lastElement.name);"
+ "return lastElement.name;"
+ "}}, false);");
System.out.println(obj.toString());
}
});
It is getting executed when the page is loaded, but not after every mouse click. Please suggest me how to modify it.
Try calling this the other way around. Assuming you're loading your page as
final WebEngine webEngine = webview.getEngine();
webEngine.load("http://localhost/demo/clickHandler/");
We're going to set a listener for the successful state - basically we're going to inject a Java class into the JavaScript and have it call us back. Let's create a WebController
that checks what is passed in and prints out the ID:
public class WebController {
public void printId(Object object) {
if (org.w3c.dom.html.HTMLElement.class.isAssignableFrom(object.getClass())) {
org.w3c.dom.html.HTMLElement it = (org.w3c.dom.html.HTMLElement) object;
System.out.println("Id is " + it.getId());
}
}
}
Now on successful load, we inject this into the app as clickController
.
webEngine.getLoadWorker().stateProperty().addListener(new ChangeListener<State>() {
@Override
public void changed(ObservableValue<? extends State> ov, State oldState, State newState) {
if (newState == State.SUCCEEDED) {
JSObject window = (JSObject) webEngine.executeScript("window");
window.setMember("clickController", new WebController());
}
}
}
);
Now we need some JavaScript on the page to call us back. Assuming you're using jQuery, add this code to your page:
$(function () {
$('*').click(function (event) {
event.preventDefault();
event.stopPropagation();
clickController.printId(this);
});
});
Now when anything is clicked on, a call back will be made to webController
, which will check that the object is an HTMLElement
and print out its ID (or null if there is no ID).
Not using jQuery makes it a bit harder but you can add this to the end of your document:
var nonJQuery = function (event) {
clickController.printId(this);
event.preventDefault();
event.stopPropagation();
};
var elements = document.querySelectorAll("*");
for (var i = 0; i < elements.length; i++) {
elements[i].addEventListener("click", nonJQuery, false);
}
If adding content to the document is not possible, you can execute the script to add the click handler in the succeeded function. Update the succeeded function to look as follows:
webEngine.getLoadWorker().stateProperty().addListener(new ChangeListener<State>() {
@Override
public void changed(ObservableValue<? extends State> ov, State oldState, State newState) {
if (newState == State.SUCCEEDED) {
JSObject window = (JSObject) webEngine.executeScript("window");
webEngine.executeScript("var nonJQuery = function (event) {\n" +
" clickController.printId(this);\n" +
" event.preventDefault();\n" +
" event.stopPropagation();\n" +
"};\n" +
"var elements = document.querySelectorAll(\"*\");\n" +
"for (var i = 0; i < elements.length; i++) {\n" +
" elements[i].addEventListener(\"click\", nonJQuery, false);\n" +
"}");
window.setMember("clickController", new WebController());
}
}
}
);
Finally, if you want to prevent page navigation eg. from links, you can add return false;
to the JavaScript:
webEngine.getLoadWorker().stateProperty().addListener(new ChangeListener<State>() {
@Override
public void changed(ObservableValue<? extends State> ov, State oldState, State newState) {
if (newState == State.SUCCEEDED) {
JSObject window = (JSObject) webEngine.executeScript("window");
webEngine.executeScript("var nonJQuery = function (event) {\n" +
" clickController.printId(this);\n" +
" event.preventDefault();\n" +
" event.stopPropagation();\n" +
" return false;\n" +
"};\n" +
"var elements = document.querySelectorAll(\"*\");\n" +
"for (var i = 0; i < elements.length; i++) {\n" +
" elements[i].addEventListener(\"click\", nonJQuery, false);\n" +
"}");
window.setMember("clickController", new WebController());
}
}
}
);
来源:https://stackoverflow.com/questions/30390257/how-to-catch-return-value-from-javascript-in-javafx