当前位置: 首页 > 知识库问答 >
问题:

javascript - vscode插件开发使用WebView,WebView内部js脚本不执行,怎么解决?

丁豪
2024-02-20

我想要基本地了解一下vscode插件开发下的自定义编辑器的使用。就用一个测试功能了解一下

功能逻辑是这样的:打开一个txt文件,打开自定义编辑器,该自定义编辑器内的webview,只有一个文本框和一个按钮,打开文件后将文件的内容读取到webview内的文本框中,点击编辑器内webview中的按钮,将旁边文本框的内容通过postMessage发给编辑器中配置的事件处理函数onDidReceiveMessage,在该函数中判断类型是不是“save”,是就保存接受到的消息的内容到对应的文件中

但遇到问题,就是自定义编辑器中使用到WebView渲染html代码成功,但是script标签下的js不执行。导致文件内容无法读取到文本框中,点击按钮也无法保存文本框的内容到文本文件中

之所以确定WebView中的js脚本没有执行,是因为两点
(1)按crtl+shift+p打开控制台发现没有出现自己调用console.log()输出的内容。这个是不是要配置什么才能显示webview下
(2)假设执行了,只是console.log不能用的话,那 content.value="123"这段代码,应该也有相应的效果。

相关代码

const vscode = require('vscode');class CustomEditorProvider {    constructor(context) {      this.context = context;    }      /**     * 打开文件     */    async resolveCustomTextEditor(document, webviewPanel, _token) {      //获取需要渲染的html内容      webviewPanel.webview.html = this.getHtmlForWebview(webviewPanel.webview, document.fileName);       //WebView事件      webviewPanel.webview.onDidReceiveMessage(async message => {        //如果那边消息类型是save,就保存内容到文件中        if (message.command === 'save') {          vscode.workspace.fs.writeFile(document.uri, Buffer.from(message.text, 'utf-8'));          vscode.window.showInformationMessage('File saved successfully.');        }      });            const content = await vscode.workspace.fs.readFile(document.uri);      //读取打开的文件内容      const text = Buffer.from(content).toString('utf-8');            webviewPanel.webview.postMessage({ text: text });    }              //获取渲染的html内容    getHtmlForWebview(webview, fileName) {        return `<!DOCTYPE html>        <html lang="en">        <head>        </head>        <body>          <textarea id="content" style="width:100%; height: 300px"></textarea>          <button id="saveButton">Save</button>          <button >123</button>          <script>          console.log("123")            const vscode = acquireVsCodeApi();            const content = document.getElementById('content');            const saveButton = document.getElementById('saveButton');            content.value="123"            window.addEventListener('message', event => {                console.log("456")              content.value = event.data.text;            });            saveButton.addEventListener('click', () => {                content.value="567"                console.log("89")              vscode.postMessage({ command: 'save', text: content.value });            });          </script>        </body>        </html>`;      }  }/** * 初始化 * @param {*} context  */  function initing(context){    let customEditorProvider = new CustomEditorProvider(context);    context.subscriptions.push(        vscode.window.registerCustomEditorProvider('customEditor', customEditorProvider)    );  }  module.exports= {    CustomEditorProvider:CustomEditorProvider,    initing:initing};

package.json文件相关内容

  "contributes": {    "customEditors": [      {        "viewType": "customEditor",        "displayName": "Custom Editor",        "selector": [          {            "filenamePattern": "*.txt"           }        ]      }    ]  },

共有1个答案

张晨朗
2024-02-20

首先,我注意到你的问题主要集中在VSCode插件开发中的WebView使用。你提到WebView中的JavaScript脚本无法执行,导致无法读取文件内容并保存。

对于你提到的问题,我注意到你在resolveCustomTextEditor方法中直接发送了文件内容到WebView,但没有确保文件内容实际上被读取并填充到textarea元素中。另外,在JavaScript脚本中,你设置了一个事件监听器来处理来自外部的消息,但在你的代码中,这个监听器并没有被触发。

为了解决这个问题,我建议进行以下更改:

  1. 在将文件内容发送到WebView之前,确保文件内容实际上被读取并存储在一个变量中。
  2. 在WebView的HTML中,确保textarea元素的ID与你在脚本中使用的ID匹配。
  3. 触发WebView中的消息事件,以便触发你设置的事件监听器。

下面是对你代码的修改建议:

const vscode = require('vscode');class CustomEditorProvider {    constructor(context) {        this.context = context;    }    /**     * 打开文件     */    async resolveCustomTextEditor(document, webviewPanel, _token) {        // 获取需要渲染的html内容        const htmlContent = this.getHtmlForWebview(webviewPanel.webview, document.fileName);         webviewPanel.webview.html = htmlContent;        // WebView事件        webviewPanel.webview.onDidReceiveMessage(async message => {            // 如果那边消息类型是save,就保存内容到文件中            if (message.command === 'save') {                vscode.workspace.fs.writeFile(document.uri, Buffer.from(message.text, 'utf-8'));                vscode.window.showInformationMessage('File saved successfully.');            }        });        // 读取打开的文件内容,并发送到WebView的textarea元素中        const content = await vscode.workspace.fs.readFile(document.uri);        const text = Buffer.from(content).toString('utf-8');        webviewPanel.webview.postMessage({ text: text });    }    /**     * 获取渲染的html内容     */    getHtmlForWebview(webview, fileName) {        return `<!DOCTYPE html>        <html lang="en">        <head>        </head>        <body>          <textarea id="content" style="width:100%; height: 300px"></textarea>          <button id="saveButton">Save</button>          <script>            window.addEventListener('message', event => {                document.getElementById('content').value = event.data.text;            });          </script>        </body>        </html>`;    }}/** * 初始化 * @param {*} context  */function initing(context) {    let customEditorProvider = new CustomEditorProvider(context);    context.subscriptions.push(        vscode.window.registerCustomEditorProvider('customEditor', customEditorProvider)    );}
 类似资料:
  • 我正在使我的flash游戏成为一个Android应用程序与以下代码。它工作得很好,但编译器给出了错误 这段代码可以工作,但不会持续很长时间。我怎样才能达到同样的效果?我读到将来不支持WebView插件。有没有其他方法使我的flash游戏的应用程序? 我听说了土坯空气。那还支持吗?以后还能用吗?

  • 本文向大家介绍android 中 webview 怎么用 localStorage,包括了android 中 webview 怎么用 localStorage的使用技巧和注意事项,需要的朋友参考一下 我在 android里面 使用html5的 localStorage 为什么存不进去也读不出来呀? 网上搜了好多都没效果 解决方案: 这个测试了是可以的

  • 本文向大家介绍vscode extension插件开发详解,包括了vscode extension插件开发详解的使用技巧和注意事项,需要的朋友参考一下 最近公司要使用vscode作为开发工具,需要对vscode做一些定制功能,比如snippet提示,内容提示,以及其他插件集成等,为此做了一些调查,并做了一定的开发与支持。 官方文档 https://code.visualstudio.com/doc

  • 通过ai问答vscode,实现打开文件后触发和切换标签页触发弹出消息框,根据ai提供的代码编写,但是没有达到期望效果,期望效果是vscode打开文件后,切换标签,弹出消息框,显示设置的内容 初次进行vscode 插件开发尝试,先从实现打开文件后触发和切换标签页触发弹出消息框开始,通过chat的ai问答得知可以通过onDidChangeActiveTextEditor和onDidOpenTextDo

  • 我正在试验JavaFX控件,我想使用MathJax Javascript库来呈现数学内容。 作为测试,我创建了一个基本的JavaFXFXML项目,在FXML中添加了一个WebView,并更新了控制器代码,如下所示: html文件如下所示: 这正如预期的那样工作,并产生以下结果: 请注意,对于测试,html和JavaScript文件路径都是硬编码到硬盘上的位置,因此下一步是将html打包为与应用程序

  • 问题内容: 我正在尝试从Webview中的javascript界面​​开始一项活动。该示例显示了一个烤面包。我怎么能称呼课程而不是敬酒? 这是html页面。 问题答案: 您必须先在Webview上注册JavaScriptInterface。JavaScriptInterFace可以是一个内部类,如下所示。此类将具有您可以从html页面(通过javaScript)调用的函数,并且可以在该函数内部编写