所以我确实找到了解决方案。我所做的是将我所有的事件(包括我想在准备好的文档上运行的代码)包装在单个函数中的单个对象中。然后,在实际的文档就绪调用中,我循环遍历对象中的每个函数并调用它来初始化我的事件。为了保持一致性,我还将页面上的所有函数都放入了它们自己的对象中,但这肯定是可选的。
这使我的代码更易于阅读(因为我有良好命名的事件函数,并且现在我的 Script 标记中没有松散的代码 - 它都在函数内)并且 PHPStorm 中的“结构”选项卡现在包含 JQuery 事件并且组织得井井有条也。它确实提高了我浏览代码的能力。
它是什么样子的
我将在这里使用一些示例代码来展示我所做的。请记住,与我一直在处理的一些更复杂的页面(可能是数千行代码)相比,这段代码非常简单,所以这给我的代码添加的组织级别比我要激烈得多可以在这个简单的例子中展示。
这是我的代码过去的样子:
<script>
console.log("I'd often have random code here outside any function that cluttered the Structure panel");
$(function () {
f.updateResults("Type something in the input to change this text!");
$("#myBtn").click(function () {
f.alertThis("You clicked a button!")
});
$("#myInput").change(function () {
f.updateResults($(this).val());
});
};
function alertThis (val) {
alert(val);
}
function updateResults() {
$("#results").text(text);
}
</script>
当这有 20 个事件和几乎一样多的功能时,我很难找到我要找的东西,而且结构面板是一堆完全没用的随机元素。
现在我的代码如下所示:
<script>
jsinit
e._ready = function () {
console.log("Any loose page code I now put in here. This is automatically run first when the document is ready");
f.updateResults("Type something in the input to change this text!");
};
e.myBtn_click = function () {
$("#myBtn").click(function () {
f.alertThis("You clicked a button!")
});
};
e.myInput_change = function () {
$("#myInput").change(function () {
f.updateResults($(this).val());
});
};
f.alertThis = function (val) {
alert(val);
};
f.updateResults = function (text = false) {
$("#results").text(text);
};
</script>
说 jsinit 的那一行是 lena 的回答中提到的可折叠注释。它有一些代码,我现在在需要时通过live template 每页放置一次。该代码未折叠时如下所示:
//region jsinit
window.g = (typeof g !== "undefined") ? g : [];
var e = {};
var f = (typeof f !== "undefined") ? f : {};
g.push(e);
$(function () {
setTimeout(function(){
for (var page_index in g) {
if (typeof g[page_index]._ready !== "undefined")
{
g[page_index]._ready();
delete g[page_index]._ready;
}
for (var func_index in g[page_index])
{
g[page_index][func_index]();
}
delete g[page_index];
}
},0);
});
//endregion
这段代码可以简化很多,但我想处理将一个页面包含在另一个页面中的特殊情况(例如打开 JQueryUI 对话框并通过 ajax 将其内容加载到另一个页面时)。在这些情况下, e 和 f 变量将已经存在,并且会有两个 _ready 函数,因此如果不处理它,可能会出现一些奇怪的错误。这就是循环和检查现有变量的目的。 setTimeout 行只是为了处理我正在使用的旧版本 JQuery 中的错误,并且在 JQuery 的 v3 或更新版本中不是必需的。
它的作用
您会发现只需向下浏览查找所需的功能或事件是多么容易。所有的代码也都包含在函数中,再也没有什么是松散的了。
就像我提到的,函数不需要放在它们自己的对象中,但我这样做是为了保持一致性。它还有一个额外的好处,就是可以通过键入 f 和句点轻松地将自动完成功能缩小到本地功能。
我觉得现在不仅代码更容易阅读,而且结构面板现在看起来是这样的:
我列出的所有事件和我的所有功能都列出并且易于跳转。这个面板过去看起来像是一堆毫无价值的信息。
例如,这是我使用旧结构面板的页面之一:
这是我以这种方式组织后完全相同的页面的结构面板:
我已经很好地列出了我的所有活动,我可以快速浏览我需要去的任何地方。
让这一切变得简单的实时模板
如果您有兴趣做类似的事情,我创建了 3 个实时模板,让这个组织变得超级简单。您可以通过按 Ctrl+Alt+S 并转到编辑器 > 实时模板来添加实时模板。
我在 html/xml 范围下添加了这个,以便我可以快速键入 js 并按 Tab 以创建一个包含 jsinit 代码的脚本标记:
<script>
//region jsinit
window.g = (typeof g !== "undefined") ? g : [];
var e = {};
var f = (typeof f !== "undefined") ? f : {};
g.push(e);
$(function () {
setTimeout(function () {
for (var page_index in g) {
if (typeof g[page_index]._ready !== "undefined") {
g[page_index]._ready();
delete g[page_index]._ready;
}
for (var func_index in g[page_index]) {
g[page_index][func_index]();
}
delete g[page_index];
}
}, 0);
});
//endregion$collapse$
e._ready = function () {
$END$
};
</script>
光标首先位于可折叠自定义区域的末尾。然后我按 Ctrl+Alt+- 将其折叠并按 Tab 使我的光标直接跳转到 _ready 函数(这就是模板中的 $collapse$ 和 $END$ 变量所做的)。
我还在 JavaScript 范围内添加了以下内容,因此我可以将 jsinit 代码添加到现有脚本中,而无需包含脚本标签。由于它们在不同的范围内,它们都可以用相同的缩写(js)激活,所以我什至不必考虑是否要将其包装在脚本标签中:
//region jsinit
window.g = (typeof g !== "undefined") ? g : [];
var e = {};
var f = (typeof f !== "undefined") ? f : {};
g.push(e);
$(function () {
setTimeout(function () {
for (var page_index in g) {
if (typeof g[page_index]._ready !== "undefined") {
g[page_index]._ready();
delete g[page_index]._ready;
}
for (var func_index in g[page_index]) {
g[page_index][func_index]();
}
delete g[page_index];
}
}, 0);
});
//endregion$collapse$
e._ready = function () {
$END$
};
最后,由于我现在正在创建一堆函数,所以我只是做了一个简单的脚本,以便我可以输入函数名称,f,然后 Tab 快速创建一个函数:
= function ($params$) {
$END$
};
这不是必需的,但我发现它可以节省很多时间。
编辑:
我还做了一件事,让使用这个系统导航变得非常容易。我将文件结构搜索窗口重新设置为 Ctrl+WinKey。您可以通过转到设置下的键盘映射并浏览到主菜单 > 导航 > 文件结构来找到此键盘映射。
现在我可以按 Ctrl+WinKey 并开始输入函数名称以快速跳转到它。由于我的 JQuery 事件现在被包装在函数中,我还可以以同样的方式快速找到并跳转到任何事件。