Load Local Javascript file In Flutter
You can copy paste run 4 full code main.dart, index.html, script.js, style.css
below
And add android:usesCleartextTraffic="true"
in AndroidManifest.xml
You can use package https://pub.dev/packages/webview_flutter_plus
webview_flutter_plus
is a powerful extension of webview_flutter
. This package helps to load Local HTML, CSS
and Javascript
content from Assets
or Strings
. This inherits all features of webview_flutter
with minor API changes.
You can directly download full example code from https://github.com/shah-xad/webview_flutter_plus and test it
code snippet
WebViewPlus(
initialUrl: 'assets/index.html',
onWebViewCreated: (controller) {
this._controller = controller;
},
onPageFinished: (url) {
_controller.getHeight().then((double height) {
print("Height: " + height.toString());
setState(() {
_height = height;
});
});
},
javascriptMode: JavascriptMode.unrestricted,
),
setting of assets
working demo of example code
full code of main.dart
import 'package:flutter/material.dart';
import 'package:webview_flutter_plus/webview_flutter_plus.dart';
void main() {
runApp(WebViewPlusExample());
}
class WebViewPlusExample extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: WebViewPlusExampleMainPage(),
);
}
}
class WebViewPlusExampleMainPage extends StatefulWidget {
@override
_WebViewPlusExampleMainPageState createState() =>
_WebViewPlusExampleMainPageState();
}
class _WebViewPlusExampleMainPageState
extends State<WebViewPlusExampleMainPage> {
WebViewPlusController _controller;
double _height = 1000;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('webview_flutter_plus Example'),
),
body: ListView(
children: [
SizedBox(
height: 500,
child: WebViewPlus(
initialUrl: 'assets/index.html',
onWebViewCreated: (controller) {
this._controller = controller;
},
onPageFinished: (url) {
_controller.getHeight().then((double height) {
print("Height: " + height.toString());
setState(() {
_height = height;
});
});
},
javascriptMode: JavascriptMode.unrestricted,
),
)
],
),
);
}
}
full code of index.html
<!DOCTYPE HTML>
<html>
<head>
<title>webview_flutter_plus</title>
<link crossorigin="anonymous" href="style.css" rel="stylesheet">
</head>
<body>
<div id="testDiv">
webview_flutter_plus is an extension of webview_flutter to load HTML, CSS and Javascript even from Assets or String.
<br>
<br>
<br>
Please tap the text to see Javascript execution.
</div>
<script src="script.js"></script>
</body>
full code of script.js
var testDiv = document.getElementById("testDiv");
testDiv.addEventListener('click', function f(e) {
testDiv.setAttribute('style', 'background:red;')
console.log("style changed");
})
full code of style.css
#testDiv {
background: green;
color: white;
}
tomerpacific
Updated on December 26, 2022Comments
-
tomerpacific over 1 year
I have a Flutter project and I am using the webview_flutter package to create a Webview widget.
This is my main.dart file:
import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:webview_flutter/webview_flutter.dart'; void main() { runApp(MyApp()); } class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: 'Communication Bridge', theme: ThemeData( primarySwatch: Colors.blue, visualDensity: VisualDensity.adaptivePlatformDensity, ), home: MyHomePage(title: 'Native - JS Communication Bridge'), ); } } class MyHomePage extends StatefulWidget { MyHomePage({Key key, this.title}) : super(key: key); final String title; @override _MyHomePageState createState() => _MyHomePageState(); } class _MyHomePageState extends State<MyHomePage> { WebViewController _controller; final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>(); @override Widget build(BuildContext context) { return Scaffold( key: _scaffoldKey, appBar: AppBar(title: Text('Webview')), body: WebView( initialUrl: 'about:blank', javascriptMode: JavascriptMode.unrestricted, javascriptChannels: Set.from([ JavascriptChannel( name: 'messageHandler', onMessageReceived: (JavascriptMessage message) { _scaffoldKey.currentState.showSnackBar( SnackBar( content: Text( message.message) ) ); }) ]), onWebViewCreated: (WebViewController webviewController) { _controller = webviewController; _loadHtmlFromAssets(); }, ), floatingActionButton: FloatingActionButton( child: const Icon(Icons.arrow_upward), onPressed: () { _controller.evaluateJavascript('foo("message")'); }, ), ); } _loadHtmlFromAssets() async { String file = await rootBundle.loadString('assets/index.html'); _controller.loadUrl(Uri.dataFromString( file, mimeType: 'text/html', encoding: Encoding.getByName('utf-8')).toString()); } }
As you can see, I am loading a local html file into the webview (_loadHtmlFromAssets).
The html file has the following markup:
<html> <head> <title>My Local HTML File</title> </head> <body> <script type="text/javascript"> function foo(msg) { //Code } </script> </body> </html>
When the html contains the javascript like the code above, I have no problems and am able to communicate from the application to the webview.
I want to have the javascript code in a separate file, and not inside the html file.
<html> <head> <title>My Local HTML File</title> </head> <body> <script src="script.js"></script> // <------- </body> </html>
When I tried doing this, I get the following error (where it's trying to reference methods defined in the javascript file):
I/chromium(15188): [INFO:CONSOLE(1)] "Uncaught ReferenceError: foo is not defined
I have added the file in my pubspec.yaml under assets, so that is not the issue.
I have seen this question on SO, but the solution there does not help.
-
tomerpacific over 3 yearsThanks for the answer. Are you saying the scenario I asked s not possible using the webview_flutter package?
-
chunhunghan over 3 yearsThere is actually a pull request github.com/flutter/plugins/pull/1247 , long time ago, still not merged.
-
chunhunghan over 3 yearsI suggest you can use this extension if you have deadline. because it's inherits all features of webview_flutter with minor API changes