LoginSignup
8
7

More than 5 years have passed since last update.

ElectronのWebviewにexecuteJavaScriptを利用した場合のコールバックについて

Posted at

Electronでのアプリケーションの開発中、特定のWebページを表示する必要が出てきたので<webview>タグを利用した。

その時に、<webview>側からElectron側のウィンドウへデータを受け渡す必要が出てきたため、executeJavaScriptをを利用したものの、うまくコールバックが発火せず、データの受け渡しに苦戦したのでメモ。

問題のコード

<webview>側のページから特定のセレクタに付与されているCSSを取得したいというニーズだったのでそのまま掲載。

electron.js
const $ = e=>document.querySelector(e);
const webview = $("webview");
webview.addEventListener("did-stop-loading", ()=>{
      webview.executeJavaScript(
        `return $("#col_channels_bg").css("backgroundColor")`,
        false,
        function(color){
            console.log(color);
        }
      );
});

この場合、一件問題なくWebview側で読み込まれていたjQueryを利用して背景色を取得できているようにみえるが、コールバック関数のcolorが何故かundefinedであった

問題の原因

webview.openDevTools();

と入力することでwebview側のデベロッパーコンソールを開くことができるため、こちらで値を確認してみることに。
すると、以下のようなエラーが発生していた。

Uncaught SyntaxError: Illegal return statement

どうやら送った文字列をそのままeval()かなにかでwebview上でベタに走らせているようで、グローバルでreturnした場合と同じエラーが発生している様子。

解決方法

結論としては、returnせずにそのままJSオブジェクトとして吐かせると、うまくコールバックが動作した。

electron-fix.js
const $ = e=>document.querySelector(e);
const webview = $("webview");
webview.addEventListener("did-stop-loading", ()=>{
      webview.executeJavaScript(
        `color:{$("#col_channels_bg").css("backgroundColor")}`,
        false,
        function(color){
            console.log(color); // rgb(100, 100, 100);
            // 決してcolor.colorではなく、colorでアクセスすることになるので注意
        }
      );
});

まとめ

  • Electronのwebview.executeJavaScript()で実行されるコードはそれ自体にスコープを持っていない
  • そのため、returnをするとグローバルでのreturnと同様とみなされエラーが発生する
  • これを防ぎつつコールバック側にデータを渡すには、それ自体をJSオブジェクトの形式としてコードを記述すると良い
8
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
7