How to use Flutter webview evaluateJavascript?

14,727

Solution 1

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.

Solution 2

Using document.getElementsByClassName('someclassname')[0] worked for me.

Share:
14,727

Related videos on Youtube

Nick
Author by

Nick

Updated on June 04, 2022

Comments

  • Nick
    Nick over 1 year

    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)),
                  );
                });
          }
    
        }
    
  • Nick
    Nick over 4 years
    I couldn't see anything in debug console. All I see this: Xcode build done. 11,6s Syncing files to device iPhone X... flutter: Page finished loading: stackoverflow.com
  • obscure
    obscure over 4 years
    And if you try _myController.evaluateJavascript("console.log(document.title‌​);"); setState(() { _loadedPage = true; });
  • Nick
    Nick over 4 years
    I am using IntelliJ and nothing shows in debug console, all I see same as before. Page finished loading: stackoverflow.com
  • Nick
    Nick over 4 years
    Its work when I use document.getElementById. But doesn't work with document.getElementsByClassName. Thanks.
  • Canada2000
    Canada2000 about 2 years
    Did you use it like this ? controller!.evaluateJavascript("document.getElementsByClassN‌​ame('someclassname')‌​[0];")