如何在 WebStorm/PhpStorm 中的 jQuery 事件之间列出、组织或导航?

How do I list, organize, or navigate between jQuery events in WebStorm/PhpStorm?

我一直在努力浏览 WebStorm/PhpStorm 中的代码。当我编辑一个大页面时,在 JavaScript 部分我自然地似乎有 3 个部分:

  1. $( document ).ready()代码
  2. 页面事件(使用 jQuery)
  3. 函数

我遇到的最大问题是,一旦我在一个页面上获得大约 20 个 jQuery 事件,就很难导航并找到我正在寻找的事件。

我真的想要结构面板之类的东西,老实说,它现在看起来毫无用处,因为它似乎无法拾取 jQuery 事件,而是拾取随机代码元素。或者我喜欢 Alt + DownAlt + Up 之类的东西来导航到下一个或上一个功能,但这只适用于功能和不是 jQuery 个事件。

有没有一种方法可以在代码段之间列出或导航以识别代码中的 jQuery 事件?也许是一个插件?或者我可以构建我的代码来处理这个问题的更好方法?

这是不可能的,而且我不知道有任何插件:(

您可以在此处尝试使用自定义区域:用 // region <Event name> ... // endregion 评论围绕您的每个事件,然后使用 Navigate |自定义折叠...(默认键盘映射中的Ctrl+Alt+.)按名称导航到所需区域

所以我确实找到了解决办法。我所做的是将我所有的事件(包括我想要 运行 准备好文档的代码)包装在单个对象中的各个函数中。然后,在实际的文档就绪调用中,我循环遍历对象中的每个函数并调用它来初始化我的事件。为了保持一致性,我还将页面上的所有功能都放入了它们自己的对象中,但这当然是可选的。

这使我的代码更易于阅读(因为我的事件函数命名得当,现在我的脚本标记中没有松散的代码 - 全部在函数中)并且 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$
};

这不是必需的,但我发现它可以节省很多时间。

编辑:

我还做了一件事,使使用这个系统导航变得非常容易。我将文件结构搜索 window 重新绑定到 Ctrl+WinKey。您可以通过转到“设置”下的“键盘映射”并浏览至“主菜单”>“导航”>“文件结构”来找到此键盘映射。

现在我可以按 Ctrl+WinKey 并开始键入函数名称以快速跳转到它。由于我的 JQuery 事件现在包装在函数中,我也可以用同样的方式快速找到并跳转到任何事件。