【问题标题】:Which function does this jsaction call?这个 jsaction 调用了哪个函数?
【发布时间】:2026-01-26 22:55:01
【问题描述】:
我正在尝试计算谷歌驱动器加载其文件夹内容的路径,从双击文件夹名称到加载文件夹内容。
我注意到谷歌使用类似的东西:
<div jsaction="click:cOuCgd; contextmenu:mg9Pef; dblclick:FNFY6c; focus:AHmuwe" jsname="LvFR7c" role="row" tabindex="0" aria-selected="false" aria-disabled="false">
dblclick:FNFY6c 是做什么的? FNFY6c 是一个函数吗?整个过程如何运作?我一直试图弄清楚它是如何使用 Chromes DevTools 工作的,但似乎无法在任何地方找到 FNFY6c。
我如何知道点击dblclick:FNFY6c 时接下来会发生什么?
【问题讨论】:
标签:
javascript
google-chrome-devtools
google-closure-compiler
google-closure-library
【解决方案1】:
JsAction 不仅仅是一个属性,它是一个完整的 google-d^ 库,用于处理/调度事件。
google/jsaction > README.md
JsAction 是一个小型事件委托库,它允许将执行操作的 DOM 节点与处理该操作的 JavaScript 代码解耦。
添加事件处理程序的传统方法是获取对节点的引用并将事件处理程序添加到它。 JsAction 允许我们通过一个名为 jsaction 的自定义 HTML 属性在事件和这些事件的处理程序名称之间进行映射。
另外,JavaScript 代码使用给定名称注册事件处理程序,这些名称不需要全局公开。当一个事件发生时,动作的名称被映射到相应的处理程序被执行。
最后,JsAction 将事件处理与实际实现分离。因此,人们可能会延迟加载实现,而应用程序始终能够响应通过 JsAction 标记的用户操作。这有助于大大减少页面加载时间,尤其是对于服务器端呈现的应用程序。
jsaction 的基本设置如下,
HTML
<script src="https://www.gstatic.com/jsaction/contract.js"></script>
<script src="https://www.gstatic.com/jsaction/dispatcher.js" ></script>
<div id="foo"
jsaction="leftNav.clickAction;dblclick:leftNav.doubleClickAction">
some content here </div>
JavaScript
const eventContract = new jsaction.EventContract();
// Events will be handled for all elements under this container.
eventContract.addContainer(document.getElementById('container'));
// Register the event types we care about.
eventContract.addEvent('click');
const dispatcher = new jsaction.Dispatcher();
eventContract.dispatchTo(dispatcher.dispatch.bind(dispatcher));
// Register individual handlers
const click = function(flow) {
// do stuff
alert('click event dispatched!');
};
dispatcher.registerHandlers(
'leftNav', // the namespace
null, // handler object
{ // action map
'clickAction': click
});
让我们举一些关于jsaction的例子:
// A BASIC SETUP --- JSACTION
const eventContract = new jsaction.EventContract();
// Events will be handled for all elements under this container.
eventContract.addContainer(document.getElementById('container'));
// Register the event types we care about.
eventContract.addEvent('click');
const dispatcher = new jsaction.Dispatcher();
eventContract.dispatchTo(dispatcher.dispatch.bind(dispatcher));
// Register individual handlers
const click = function(flow) {
// do stuff
alert('click event dispatched!');
};
dispatcher.registerHandlers(
'leftNav', // the namespace
null, // handler object
{ // action map
'clickAction': click
});
<script src="https://www.gstatic.com/jsaction/contract.js"></script>
<script src="https://www.gstatic.com/jsaction/dispatcher.js" ></script>
<div id="container">
<div id="foo" jsaction="click:leftNav.clickAction">
some content here
</div>
</div>
// Set up
const eventContract = new jsaction.EventContract();
// Events will be handled for all elements under this container.
eventContract.addContainer(document.getElementById('container'));
// Register the event types we care about.
eventContract.addEvent('dblclick');
const dispatcher = new jsaction.Dispatcher();
eventContract.dispatchTo(dispatcher.dispatch.bind(dispatcher));
// Register individual handlers
const dbClick = function(flow) {
// do stuff
alert('double-click event dispatched!');
};
dispatcher.registerHandlers(
'leftNav', // the namespace
null, // handler object
{ // action map
'doubleClickAction': dbClick
});
<script src="https://www.gstatic.com/jsaction/contract.js"></script>
<script src="https://www.gstatic.com/jsaction/dispatcher.js" ></script>
<div id="container">
<div id="foo" jsaction="dblclick:leftNav.doubleClickAction">
some content here
</div>
</div>
// Set up
const eventContract = new jsaction.EventContract();
// Events will be handled for all elements under this container.
eventContract.addContainer(document.getElementById('container'));
// Register the event types we care about.
eventContract.addEvent('click');
eventContract.addEvent('mouseover');
eventContract.addEvent('mouseout');
const dispatcher = new jsaction.Dispatcher();
eventContract.dispatchTo(dispatcher.dispatch.bind(dispatcher));
// Register individual handlers
const click = function(flow) {
// do stuff
console.log('click called!');
};
const mouseOver = function(flow) {
// do stuff
console.log('mouseover called!');
};
const mouseOut = function(flow) {
// do stuff
console.log('mouseout called!');
};
dispatcher.registerHandlers(
'leftNav', // the namespace
null, // handler object
{ // action map
'clickAction': click,
'mouseOverAction': mouseOver,
'mouseOutAction': mouseOut
});
<script src="https://www.gstatic.com/jsaction/contract.js"></script>
<script src="https://www.gstatic.com/jsaction/dispatcher.js" ></script>
<div id="container">
<div id="foo" jsaction="click:leftNav.clickAction;mouseover:leftNav.mouseOverAction;mouseout:leftNav.mouseOutAction">
some content here
</div>
</div>
这里有一个complete list的jsaction事件,其中大部分是css-events。
^: “谷歌开发”的缩写;)
【解决方案2】:
按Ctrl+Shift+I打开检查器,然后按Ctrl+Shift+F,搜索页面中使用的所有源文件。搜索“FNFY6c”或任何其他参考。单击左下角的小{} 图标以漂亮地打印代码。您应该有一些好的起点来在代码中放置断点并开始跟踪您现在正在寻找的函数。
我猜他们在document.body 上使用dblclick 处理程序,所以我使用getEventListeners(document.body) 来查找事件处理程序。我放置了一个条件断点检查c.type == 'dblclick' 以获得一个断点。它继续进入监听器并最终调度一个“活动”事件并继续。
我不确定您希望达到什么目标,但即使您拥有高水平的反转能力,您也很可能很难从中获得有意义的东西。代码输出通过 Google Closure Compiler 使用非常激进的混淆代码,甚至在字符串中使用引用名称。您将挖掘非常复杂的代码,基本上没有可识别的名称。
如果您有兴趣倒车并以此为乐,祝您好运。只是如果没有大量的时间和练习,我不会期望太多。甚至可能经过大量时间和练习。