質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Internet Explorer

Internet Explorer(IE;MSIE)はマイクロソフトが開発したウェブブラウザです。Microsoft Windowsに組み込まれています。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

1回答

3991閲覧

PyWebViewにて、ドキュメント内に表示したiframeのスクロール位置を保存・設定できない

TakamiChie

総合スコア59

Internet Explorer

Internet Explorer(IE;MSIE)はマイクロソフトが開発したウェブブラウザです。Microsoft Windowsに組み込まれています。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2019/03/12 15:19

編集2019/03/12 15:27

前提・実現したいこと

以下OSSの編集を行っています。
TakamiChie/Re-VIEW-Preview: Tool to live Preview any Re:VIEW format document

このソフトでは、PythonのPyWebViewモジュールを使って、HTMLでレンダリングしたGUIを表示、その中にiframeで他ドキュメント(ここではRe:VIEWで生成したHTMLドキュメント)を読み込み表示する という処理を行っています。

なお、PyWebViewのHTMLレンダリングエンジンは、Windowsの場合Trident(IE11)となります。

このソフトで、iframeにて表示中のドキュメントが再読込されたとき、スクロール位置を維持する機能を実装したいと考えています。

発生している問題・エラーメッセージ

PyWebViewないしIE11の以下の制約により、どの方法でもスクロール位置を保存・復元することができません。

iframe内で表示しているドキュメントで、スクロール位置を保存しようとした場合

  • IE11はローカルHTMLを読み込んでいる場合、localStorageないしsessionStorageが使用できない
  • PyWebViewでは子ウィンドウからwindow.parent.***として親ウィンドウを参照することができない(「アクセスが拒否されました」というエラーが表示される)

iframeを持つドキュメント(PyWebView#load_html()で表示しているドキュメント)でスクロール位置を保存しようとした場合

  • PyWebViewでは、iframeのcontentDocumentプロパティが参照できない(「アクセスが拒否されました」というエラーが表示される)

PyWebViewではHTMLドキュメントの情報にアクセスする方法がwebview.evaluatejs()メソッドしかないため、HTML上でできないことをPython上で実現することもできない状況です。

該当のソースコード・試したこと

html

1<!-- main.html --> 2<!DOCTYPE html> 3<html lang="ja"> 4<head> 5 <meta charset="UTF-8"> 6 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 7 <link rel="stylesheet" href="../node_modules/bootstrap-honoka/dist/css/bootstrap.css"> 8 <link rel="stylesheet" href="../html/main.css"> 9 <title>Re:View Preview</title> 10</head> 11<body> 12 <header class="navbar navbar-expand-lg navbar-light bg-primary"> 13 <h1 class="navbar-brand">Preview</h1> 14 15 <ul class="navbar-nav mr-auto"> 16 <li class="nav-item" id="refresh_view"><a class="nav-link">&#x1F504;</a></li> 17 </ul> 18 <form class="form-inline my-2 my-lg-0"> 19 <select class="form-control" id="review-file" aria-label="file"></select> 20 </form> 21 </header> 22 <div class="container-fluid"> 23 <iframe id="preview_frame" src="../html/loading.html"></iframe> 24 </div> 25 <script src="../html/main.js"></script> 26 <script src="../node_modules/es6-promise/dist/es6-promise.js"></script> 27 <script src="../node_modules/jquery/dist/jquery.js"></script> 28 <script src="../node_modules/bootstrap-honoka/dist/js/bootstrap.js"></script> 29</body> 30</html>

js

1// main.js 2let current; 3// 以下の行が、IE上ではエラーにならないが、PyWebViewで実行するとエラーになる 4document.getElementById("preview_frame").contentDocument.addEventListener("scroll", function (e) { 5 current = document.getElementById("preview_frame").contentDocument.documentElement.scrollTop; 6});

html

1<!-- loading.html --> 2<!DOCTYPE html> 3<html> 4<head> 5 <!-- reference from: http://tobiasahlin.com/spinkit/ --> 6 <meta charset="utf-8"> 7 <meta http-equiv="X-UA-Compatible" content="IE=edge"> 8 <title>Loading</title> 9</head> 10<body> 11 Loading... 12 13<script src='D:\...\review_preview\html\frame.js'></script></body> 14</html>

js

1// frame.js 2document.addEventListener("scroll", function (e) { 3 // 以下の行で、「SCRIPT5007: 未定義または NULL 参照のプロパティ 'setItem' は取得できません」というメッセージが表示される 4 localStorage.setItem("pos", document.documentElement.scrollTop); 5 // 以下の行が、IE上ではエラーにならないが、PyWebViewで実行するとエラーになる 6 window.parent.pos = document.documentElement.scrollTop; 7});

補足情報(FW/ツールのバージョンなど)

  • Python: 3.6.6(3.7だとPyWebViewインストール時にエラーが頻発したため3.6.6としました)
  • PyWebView: 2.4
  • bootstrap-honoka: 4.3.1
  • Windows: 10 Ver 1809 Build 17763.316

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

自己解決

両方ローカルのHTMLだったのでクロスオリジンではない と思っていましたが、PyWebViewで表示した場合クロスオリジンになってiframe内外の通信に制限が発生していたようです。

よってWindow#postMessage()で解決しました。

js

1// frame.js 2document.addEventListener("DOMContentLoaded", function (e) { 3 let h = location.hash; 4 if(h.substr(0, 4) == "#top"){ 5 window.scroll(0, parseInt(h.substring(4))); 6 } 7}) 8document.addEventListener("scroll", function (e) { 9 window.parent.postMessage(document.documentElement.scrollTop, "*"); 10})

js

1// main.js 2 3var pos = 0; 4 5window.addEventListener("message", function (e) { 6 pos = e.data; 7})

python

1# js_api.py 2 def show_review(self, filename = None): 3 pos = 0 4 if filename is None: # リロード時のみスクロール位置を保存 5 pos = webview.evaluate_js("pos") 6 self._comm.frameurl = path_to_url(mypath() / "html" / "loading.html") 7 # 中略 8 self._comm.frameurl = path_to_url(previewhtml) + "?{0}#top{1}".format(self._review_file.stem, pos)

Added to remember scroll when reloading files. #3 · TakamiChie/Re-VIEW-Preview@f12471a

投稿2019/03/13 01:59

TakamiChie

総合スコア59

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問