I try to use webview evaluateJavascript
and got error. WebView Controller
has 2 function; evaluateJavascript
, and loadUrl
. I tested both in onPageFinished: (url){}
, so I can initialise my javascript code. Documentation is not clear. But the error tells me something missing pr not implemented in webview plugin. I am trying to load page and initialising some basic javascript so I can hide some part of the page.
How to use Flutter webview evaluateJavascript?
Error:
Syncing files to device iPhone X...
flutter: Page finished loading: https://stackoverflow.com/
[VERBOSE-2:ui_dart_state.cc(148)] Unhandled Exception: PlatformException(evaluateJavaScript_failed, Failed evaluating JavaScript, JavaScript string was: 'javascript:(function() { var head = document.getElementsByClassName('top-bar js-top-bar top-bar__network _fixed')[0].style.display='none'; })()'
Error Domain=WKErrorDomain Code=4 "A JavaScript exception occurred" UserInfo={WKJavaScriptExceptionLineNumber=1, WKJavaScriptExceptionMessage=TypeError: undefined is not an object (evaluating 'document.getElementsByClassName('top-bar js-top-bar top-bar__network _fixed')[0].style'), WKJavaScriptExceptionColumnNumber=117, WKJavaScriptExceptionSourceURL=https://stackoverflow.com/, NSLocalizedDescription=A JavaScript exception occurred})
#0 StandardMethodCodec.decodeEnvelope (package:flutter/src/services/message_codecs.dart:564:7)
#1 MethodChannel.invokeMethod (package:flutter/src/services/platform_channel.dart:302:33)
<asynchronous suspension>
#2 WebViewController.evaluateJavascript (package:web<…>
Application finished.
Code:
class _WebViewExampleState extends State<WebViewExample> {
WebViewController _myController;
bool _loadedPage = false;
@override
void initState() {
// TODO: implement initState
super.initState();
setState(() {
_loadedPage = false;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.green,
title: const Text(
’Stackoverflow’,
style: TextStyle(fontSize: 14),
),
),
body: Builder(builder: (BuildContext context) {
return new Stack(
children: <Widget>[
new WebView(
initialUrl: 'https://stackoverflow.com',
javascriptMode: JavascriptMode.unrestricted,
onWebViewCreated: (controller){
_myController = controller;
},
javascriptChannels: <JavascriptChannel>[
_toasterJavascriptChannel(context),
].toSet(),
onPageFinished: (url){
print('Page finished loading: $url');
_myController.evaluateJavascript("javascript:(function() { " +
"var head = document.getElementsByClassName('top-bar js-top-bar top-bar__network _fixed')[0].style.display='none'; " +
"})()");
/*
_myController.loadUrl("javascript:(function() { " +
"var head = document.getElementsByClassName('top-bar js-top-bar top-bar__network _fixed')[0].style.display='none'; " +
"})()");
*/
setState(() {
_loadedPage = true;
});
},
),
_loadedPage == false
? new Center(
child: new CircularProgressIndicator(
backgroundColor: Colors.green),
)
: new Container(),
],
);
}),
);
}
JavascriptChannel _toasterJavascriptChannel(BuildContext context) {
return JavascriptChannel(
name: 'Toaster',
onMessageReceived: (JavascriptMessage message) {
Scaffold.of(context).showSnackBar(
SnackBar(content: Text(message.message)),
);
});
}
}
You are using it correctly - though you don't need to wrap it inside
javascript:(function() { }
Anyway, this is the important part of the error message:
TypeError: undefined is not an object
This merely means the object for which you're trying to modify the style attribute doesn't exist.
If you try the following code
_myController.evaluateJavascript("console.log(document.documentElement.innerHTML);");
setState(() {
_loadedPage = true;
});
and take a look at the debug console, you'll notice that this code - which should return the complete HTML for the stackoverflow website - just returns a little bit and not enough to reach the header element which uses the class top-bar js-top-bar top-bar__network _fixed
.
使用document.getElementsByClassName('someclassname')[0]
对我有用。
All the answers are outdated now, and evaluateJavascript
no longer existed in the package. It's now call runJavascript
; If you don't need value return from your javascript, otherwise use runJavascriptReturningResult
.
You can see an example here
Use controller.evaluateJavascript
to edit on webview javascript, available in in_app_webview packages.
Notes that controller.evaluateJavascript
need to write inside onLoadStop() functions. Inside the code where your WebView is finished loaded.
Example:
String Username = 'User';
String Password = '123';
InAppWebView(
...
onLoadStop: (controller, url) async{
pullToRefreshController.endRefreshing();
controller.evaluateJavascript(
source: '''
document.getElementById('uname').value = "$Username"; //Autofill in username field
document.getElementById('pwd').value = "$Password"; //Autofill in password field
var z = document.getElementById('submitBtn').click(); //Autoclick function
'''
);
setState(() {
this.url = url.toString();
urlController.text = this.url;
});
},
...
)//InAppWebView
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.