uni-app在app平台使用evalJS执行html中的js函数提示函数未定义

发布于 1周前 作者 caililin 来自 Uni-App

uni-app在app平台使用evalJS执行html中的js函数提示函数未定义

uniapp 调用 HTML 中定义的 JavaScript 函数问题

uniapp可以获取修改html的js中定义的变量并可以修改,但是无法执行里面定义函数。下面是在Html的js中定义了一个函数 uniMsg(),但是在uniapp是无法调用这个函数:

Uncaught ReferenceError: uniMsg is not defined

代码示例

uniapp 代码

<template>  
    <view class="qrt_root">  
        <web-view src="/static/html/index.html"></web-view>  
    </view>  
</template>  

<script setup>  
import { onMounted } from 'vue';  
onMounted(() => {  
    // 获取dom元素  
    let pages = getCurrentPages();  
    let page = pages[pages.length - 1];  
    let wv = page.$getAppWebview();  

    setTimeout(() => {  
        wv.evalJS("uniMsg('uniapp message!');");  
    }, 1000)  
});  
</script>

HTML 文件

<!DOCTYPE html>  
<html lang="en">  
<head>  
    <meta name="viewport" content="width=device-width, initial-scale=1.0">  
</head>  

<body>  
    <h3>html页面</h3>  
    <div class="msg_box"></div>  
</body>  

<script>  
    let el = document.getElementsByClassName('msg_box')[0];  
    let uniMsg = val => {  
        el.innerHTML = val;  
    }  
    /* 全局定义无效  
    window.uniMsg = val => {  
        el.innerHTML = val;  
    }  
    */  
</script>  

</html>

解决方案

为了使 uniMsg 函数在 uniapp 中可调用,需要将该函数挂载到全局对象 window 上。修改后的 HTML 文件如下:

<!DOCTYPE html>  
<html lang="en">  
<head>  
    <meta name="viewport" content="width=device-width, initial-scale=1.0">  
</head>  

<body>  
    <h3>html页面</h3>  
    <div class="msg_box"></div>  
</body>  

<script>  
    let el = document.getElementsByClassName('msg_box')[0];  
    window.uniMsg = val => {  
        el.innerHTML = val;  
    }  
</script>  

</html>

这样,uniMsg 函数就可以在 uniapp 中通过 wv.evalJS 成功调用了。


3 回复

改一下写法

<script setup> import {onMounted,getCurrentInstance} from 'vue'; var wv; //计划创建的webview const {ctx} = getCurrentInstance() onMounted(() => { setTimeout(() => { var currentWebview = ctx.$scope.$getAppWebview() wv = currentWebview.children()[0] wv.evalJS("uniMsg()") }, 1000) }); </script>

解决了吗 我我也遇到这个我问题了

在uni-app中,evalJS 函数主要用于在 H5 平台上执行页面内的 JavaScript 代码。然而,在 app 平台上(如 Android 或 iOS),由于运行环境不同,evalJS 并不能直接执行页面内嵌入的 HTML 或 JavaScript 代码。因此,如果你在 app 平台上使用 evalJS 并遇到函数未定义的错误,这通常是因为 evalJS 找不到指定的函数。

在 app 平台上,与原生代码的交互通常需要使用 uni-app 提供的 plus API 或者其他原生插件接口。以下是一个如何在 app 平台上调用原生 JavaScript 函数(如果确实需要在原生 WebView 中执行)的替代方案,但请注意,这通常不是推荐的做法,因为它绕过了 uni-app 的框架设计,并可能导致跨平台兼容性问题。

示例:使用 plus.webview 执行 JavaScript

如果你确实需要在 app 平台的 WebView 中执行 JavaScript 代码,你可以使用 plus.webview 对象。但请注意,这要求你的页面是在一个 plus.webview.create 创建的 WebView 中加载的。

// 假设你已经有一个 WebView 对象
var webview = plus.webview.currentWebview(); // 获取当前 WebView

// 要执行的 JavaScript 代码
var jsCode = "function testFunction() { console.log('Hello from testFunction!'); } testFunction();";

// 执行 JavaScript 代码
webview.evalJS(jsCode);

然而,上面的代码直接在 evalJS 中定义了函数并立即调用它,这在大多数情况下是不可行的,因为 evalJS 执行的是立即执行的代码片段,它不会保留定义的函数。

更好的做法:通过消息传递

更推荐的做法是通过 uni-app 提供的消息传递机制(如 postMessage 和监听消息事件)来与原生页面或组件通信。以下是一个简单的示例:

在原生页面(或组件)中

// 监听来自 uni-app 的消息
plus.runtime.onMessage = function(event) {
    if (event.data && event.data.action === 'executeJS') {
        // 在这里执行你的 JavaScript 代码
        eval(event.data.code);
    }
};

在 uni-app 中

// 发送消息到原生页面
plus.runtime.postMessage({
    action: 'executeJS',
    code: 'console.log("Hello from uni-app!");'
});

这种方法避免了直接在 app 平台的 WebView 中使用 evalJS 执行复杂或长期存在的 JavaScript 函数,并提供了更好的跨平台兼容性和代码管理。

回到顶部