Help us understand the problem. What is going on with this article?

PyWebViewで複数のJavaScriptファイルを読み込む

PyWebViewで複数のJavaScriptを使いたい

PyWebViewで、ウィンドウにJavaScriptを読み込ませたいときには、window#evaluate_js()というメソッドを利用します。

このメソッド、複数回呼び出したときは、それぞれのJavaScriptを別々のファイルと認識して処理します、このため次のようなメソッドを作っておくと、HTML5アプリケーション開発により近い感覚でPyWebViewのGUIを作れます。

def webview_load_elems(window):
  """
  引数で指定した任意のウィンドウに、次のCSS、JSライブラリを読み込む
  ・bootstrap.css
  ・bootstrap.js/popper.js/jquery.js
  ・独自開発用の、index.css/index.js
  """
  css = ["index.css"]
  js = ["index.js", "classes.js"]
  nm = "node_modules"
  dist = nm / "bootstrap-honoka" / "dist"
  distjs = dist / "js"

  css.insert(0, dist / "css" / "bootstrap.css")
  js.insert(0, nm / "popper.js" / "dist" / "popper.js")
  js.insert(0, distjs / "bootstrap.js")
  js.insert(0, nm / "jquery" / "dist" / "jquery.js")

  for file in css:
    with open(file, mode="r", encoding="utf-8") as f:
      window.load_css(f.read())
  for file in js:
    with open(file, mode="r", encoding="utf-8") as f:
      window.evaluate_js(f.read())
index.js
let test = TestClass()
/* ... */
classes.js
class TestClass {
  /* ... */
}

上記コードの問題

上記のようにファイルを読み込むと、classes.jsで宣言したクラスをindex.jsで使うことはできません。ReferenceErrorが発生してしまいます。

最近のJavaScriptであればexport文などもありますが、PyWebView上で扱われるファイルは(初期設定では)ローカルファイルとして扱われること、そもそもファイルを読み込んでいるわけではなく、JavaScriptのコードを直接ブラウザエンジンに読み込んでることから、export文は使えません

グローバルな変数のプロパティとして追加する

このようなときは、jQueryなどのファイルの先頭にヒントがあります。

jquery.js
( function( global, factory ) {

    "use strict";

    if ( typeof module === "object" && typeof module.exports === "object" ) {

        // For CommonJS and CommonJS-like environments where a proper `window`
        // is present, execute the factory and get jQuery.
        // For environments that do not have a `window` with a `document`
        // (such as Node.js), expose a factory as module.exports.
        // This accentuates the need for the creation of a real `window`.
        // e.g. var jQuery = require("jquery")(window);
        // See ticket #14549 for more info.
        module.exports = global.document ?
            factory( global, true ) :
            function( w ) {
                if ( !w.document ) {
                    throw new Error( "jQuery requires a window with a document" );
                }
                return factory( w );
            };
    } else {
        factory( global );
    }

// Pass this if window is not defined yet
} )( typeof window !== "undefined" ? window : this, function( window, noGlobal ) {

jQueryはJavaScriptの実行環境毎に、グローバル変数やエクスポート領域に自分自身を登録することで、他のJavaScriptファイルからjQueryを呼び出すことを可能にしています。

PyWebViewの実行環境において、使えるグローバル変数はwindowです。ですので、windowのプロパティとして、宣言したクラスを登録すればOK。

classes.js
class TestClass {
  /* ... */
}

window.TestClass = TestClass;

これでindex.jsからでもclasses.jsのクラスが利用できるようになります。

おまけ:PyWebViewウィンドウの開発者コンソールから、JavaScriptファイルを見たい

webview.start()メソッドのguiに開発者コンソールが利用できるブラウザエンジン(cefなど)、debugTrueに設定すると、ブラウザウィンドウの右クリックメニューから開発者コンソールが開けるようになります。

この開発者コンソールから読み込んだJavaScriptファイルを見たい場合。読み込んだJavaScriptコードはファイルの形式ではないので、Sourceタブから中身を見ることができません。

そんなときは、JavaScriptファイルの先頭行にconsole.log("ファイル名")などと入れておくと良いです。

image.png

画面右の「VMnn:行数」というリンクをクリックすると、読み込んだJavaScriptコードを閲覧することができます。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした