XUL菜单列表,以编程方式打开

XUL menulist, open programmatically

本文关键字:编程 方式打 菜单 列表 XUL      更新时间:2023-09-26

我想模仿菜单列表XUL项中的自动完成行为(原始的自动完成组件对于我的情况来说太不切实际了,所以实际上更容易使用它然后创建一个完整的XPCOM组件)。

然而,有问题的部分是导致它打开它的下拉部分,它以编程方式显示选项。 即我不想按向下箭头按钮来打开它,我希望它在我输入时打开(如果没有匹配的选项,则关闭)。由于我可以处理输入文本,我想在同一个处理程序中打开/关闭下拉部分,有没有办法做到这一点?

编辑

下面是我用于组件的XUL文件的简化示例:

<?xml version="1.0"?>
<?xml-stylesheet href="chrome://global/skin/global.css" type="text/css"?>
<dialog id="whatever" title="Select a tab to open"
        xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
        buttons="accept,cancel"
        buttonlabelcancel="Cancel"
        buttonlabelaccept="Save"
        ondialogaccept="return doOK();"
        ondialogcancel="return doCancel();">
  <dialogheader title="Select tab"/>
  <menulist id="search-box" editable="true"
            oncommand="commandHandler(event)"
            onkeyup="keyUpHandler(event)"/>
  <script>
    var a = window.arguments[0];
    var opener = window.arguments[1];
    var menu = document.getElementById('search-box');
    function doOK()
    {
        opener.selectTabAtIndex(a.indexOf(menu.value));
        return true;
    }
    function doCancel(){ return true; }
    function commandHandler(event)
    {
        doOK();
        window.close();
    }
    function keyUpHandler(event)
    {
        var v = menu.value;
        menu.removeAllItems();
        populate(a.filter(function (x, i)
        {
            if (x == v) opener.selectTabAtIndex(i);
            return x.indexOf(v) > -1;
        }));
    }
    function populate(choices)
    {
        for (var i = choices.length - 1, s; i >= 0; i--)
        {
            s = choices[i];
            menu.appendItem(s, s);
        }
    }
    menu.focus();
    menu.select();
    populate(a);
    menu.open = true;
  </script>
</dialog>

如您所见,menu.open = true 对此没有影响。

编辑 2

我也试过:

var e = document.createEvent("KeyboardEvent");
e.initEvent("keydown", true, false, menu, false, false, false, false, 0, 40);
menu.dispatchEvent(e);

以及键下/键/按键和切换键码和字符码和亚达亚达的变化,所有这些都不起作用。

顺便说一句,我喜欢 API,让人想起旧的好 WinAPI,但还不够无用的参数

这实际上很简单,您使用 open 属性:

menulist.open = true;

您的问题可能是不希望读取/写入此属性并寻找方法 - 但更改属性确实是打开下拉列表的正确方法。