如何在C、GTK4、GObject中实现webkit_web_view_evaluate_javascript()

前端开发 2026-07-08

我在开发一个带有内嵌浏览器的应用程序。我已经用Lisp和 C(gtk4)写了一段时间,但对JavaScript还是完全新手。我需要在浏览器里执行JavaScript来查找元素。目前我在对这个功能做总体测试,等它能工作后再实现具体的用例。

按照文档的指引,我遇到了一个问题:用于查找元素的函数返回了null。

我的做法是使用文档中 webkit_web_view_evaluate_javascript() 的示例实现代码:https://webkitgtk.org/reference/webkitgtk/unstable/method.WebView.evaluate_javascript.html

我唯一的改动,是让调用 webkit_web_view_evaluate_javascript() 的函数改为选择一个元素。它所做的只是用一个元素的ID来执行JavaScript window.document.getElementById('');。最终我还会对这个元素做一些操作,这只是一个测试。

static void
web_view_get_element (WebKitWebView *web_view,
                       const gchar   *uuid)
{
    gchar *script = g_strdup_printf ("window.document.getElementById('%s');", uuid);
    gpointer result;
    webkit_web_view_evaluate_javascript (web_view, script, -1, NULL, NULL, NULL, web_view_javascript_finished, NULL);
    g_free (script);
}

我的 web_view_javascript_finished() 函数和文档中的完全相同。

我已经在嵌入式浏览器的控制台里手动测试了这段JavaScript,结果工作正常:在嵌入的浏览器控制台中测试结果

然而,当我的程序运行 web_view_get_element() 时,web_view_javascript_finished() 显示该值为null。

有什么线索吗?谢谢!

解决方案

核心问题在于 getElementById() 返回的是一个DOM元素对象,而WebKit的 JS桥只能把原始类型(字符串、数字、布尔值)传回C。DOM元素无法跨越这座桥,因此会返回null。

解决办法是在JS表达式本身就提取你需要的部分:

c

// Does the element exist?
gchar *script = g_strdup_printf(
    "document.getElementById('%s') !== null;", uuid);

// Or grab a property from it
gchar *script = g_strdup_printf(
    "var el = document.getElementById('%s'); el ? el.tagName : null;", uuid);

如果你的目标是对该元素进行某些操作,直接把所有操作都放在脚本字符串里并返回一个状态:

c

gchar *script = g_strdup_printf(
    "var el = document.getElementById('%s');"
    "if (el) { el.style.border = '2px solid red'; 'done'; } else { 'not found'; }",
    uuid);

另外,确保不要在页面加载完成之前就调用。请监听 load-changed,等待 WEBKIT_LOAD_FINISHED 的触发,否则脚本运行时该元素在DOM中还不存在。

站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章