悬停时的 Html 选择框选项?

发布于 2024-10-10 05:56:14 字数 412 浏览 0 评论 0原文

我在 youtube 上看到过这个非常简单的选择框,其中选择选项在悬停时可见(而不是单击),如下面的屏幕截图所示。

alt text

我试图在下面的简单选择框中创建类似的效果。有人可以帮忙如何做到这一点吗?谢谢。

<select name="size">
   <option value="small">Small</option>
    <option value="medium">Medium</option>
    <option value="large">Large</option>
  </select> 

I've seen this very simple selectbox on youtube, where the select options are visible on hover (instead of clicking), as seen in following screenshot.

alt text

I'm trying to create similar effect in the following simple select box. Can someone please help how this can be done? Thanks.

<select name="size">
   <option value="small">Small</option>
    <option value="medium">Medium</option>
    <option value="large">Large</option>
  </select> 

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

那一片橙海, 2024-10-17 05:56:14

这是一种方法,但我更喜欢一种更多的插件方法(而不是硬编码 html ul):

$('#selectUl li:not(":first")').addClass('unselected');
// Used to hide the 'unselected' elements in the ul.

$('#selectUl').hover(
    function(){
    // mouse-over
        $(this).find('li').click(
            function(){
                $('.unselected').removeClass('unselected');
                // removes the 'unselected' style

                $(this).siblings('li').addClass('unselected');
                // adds 'unselected' style to all other li elements

                var index = $(this).index();
                $('select option:selected').removeAttr('selected');
                // deselects the previously-chosen option in the select

                $('select[name=size]')
                    .find('option:eq(' + index + ')')
                    .attr('selected',true);
                // assumes a 1:1 relationship between the li and option elements
            });
    },
    function(){
    // mouseout (or mouseleave, if they're different, I can't remember).
    });

JS Fiddle 演示


编辑以包含一个 alert,演示 select 元素值的更改:JS Fiddle 演示


编辑以包含演示中使用的 css 和 html:

html

<select name="size">
    <option value="small">Small</option>
    <option value="medium">Medium</option>
    <option value="large">Large</option>
</select>

<ul id="selectUl">
    <li>small</li>
    <li>medium</li>
    <li>large</li>
</ul>

css:

select {
    opacity: 0.5;
}
ul {
    width: 8em;
    line-height: 2em;
}

li {
    display: list-item;
    width: 100%;
    height: 2em;
    border:1px solid #ccc;
    border-top-width: 0;
    text-indent: 1em;
    background-color: #f90;
}
li:first-child {
    border-top-width: 1px;
}

li.unselected {
    display: none;
    background-color: #fff;
}
ul#selectUl:hover li.unselected {
    background-color: #fff;
}
ul#selectUl:hover li,
ul#selectUl:hover li.unselected {
    display: list-item;
}
ul#selectUl:hover li {
    background-color: #fc0;
}
ul#selectUl li:hover,
ul#selectUl li.unselected:hover {
    background-color: #f90;
}

这会导致菜单隐藏未选择的项目,直到ul悬停结束,然后显示所有选项,并使用 click() 事件将 unselected 类名分配给未单击的元素;这允许单击的元素在鼠标移出时仍然可见。

上面的 CSS 反映了最近的编辑,以使当前选定的、:hover-ed、li 更加可见。

最新 JS Fiddle 演示


编辑因为,嗯,我有点无聊。没有更好的事情可做,所以我做了一个简单的插件:

(function($) {
    $.fn.selectUl = function(){
        var $origSelect = $(this);
        var newId = $(this).attr('name') + '-ul';
        var numOptions = $(this).children().length;

        $('<ul id="' + newId + '" class="plainSelect" />')
            .insertAfter($(this));

        for (var i = 0; i < numOptions; i++) {
            var text = $(this).find('option').eq(i).text();
           $('<li />').text(text).appendTo('#' + newId);
        }

        if ($(this).find('option:selected')) {
            var selected = $(this).find('option:selected').index();
            $('#' + newId)
                .find('li')
                .not(':eq(' + selected + ')')
                .addClass('unselected');
        }

        $('#' + newId + ' li')
            .hover(
                function(){
                    $(this).click(
                        function(){
                            var newSelect = $(this).index();
                            $(this)
                                .parent()
                                .find('.unselected')
                                .removeClass('unselected');
                            $(this)
                                .parent()
                                .find('li')
                                .not(this)
                                .addClass('unselected');
                            $($origSelect)
                                .find('option:selected')
                                .removeAttr('selected');
                            $($origSelect)
                                .find('option:eq(' + newSelect + ')')
                                .attr('selected',true);
                        });
                },
                function(){
            });
                    // assuming that you don't want the 'select' visible:
                    $(this).hide();

        return $(this);
    }
        })(jQuery);


$('#sizes').selectUl();

JS Fiddle 演示,包括 'plug -in'

注意:

  • 这不是绝对定位的,因此如果您有多个select(您当然可以这样做,并且工作正常),它确实会扰乱页面流一点(或很多),但这可以在CSS中修改(我想,虽然我还没有尝试过)。
  • 它可能需要一些选项,可能允许使用 dl 元素来代替当前的 ul 元素,这将允许对可用选项进行解释。
  • 我怀疑它可以比目前优化得更多,但我不知道如何优化。可能睡一会儿,然后浏览 jQuery API 可能会提供一些见解(尽管如果有人看到任何明显的内容,请离开或者使用 JS Fiddle,如果需要更好的术语,请分叉它(尽管我显然很感激任何后续分支/更新的链接,但
  • 我不完全确定我可以使用哪些许可选项(因为SO上的所有内容都是知识共享 cc-by-sa,根据 Jeff Atwood,以及此网站的页脚无论如何),但就其价值而言,我很高兴任何人都能接受上述内容,并且可以用它做任何你喜欢的事情(如果有任何用处,祝你玩得开心!)

<强>编辑因为我觉得应该有一个可见的“指导”元素,并尝试解释它是如何运作的。

给定 html:

<select name="sizes" id="sizes" class="makePlain" title="Select a size:">
    <option value="xxs">XX-Small</option>
    <option value="xs">X-Small</option>
    <option value="s">Small</option>
    <option value="m">Medium</option>
    <option value="l">Large</option>
    <option value="xl">X-Large</option>
    <option value="xxl">XX-Large</option>
</select>

使用 jQuery 调用插件:

$('#sizes').selectUl();

这需要上面的选择,并创建一个带有以下标记的 ul

<ul id="sizes-ul" class="plainSelect">
    <li class="guidance">Select a size:</li>
    <li>XX-Small</li>
    <li class="unselected">X-Small</li>
    <li class="unselected">Small</li>
    <li class="unselected">Medium</li>
    <li class="unselected">Large</li>
    <li class="unselected">X-Large</li>
    <li class="unselected">XX-Large</li>
</ul>

使用的 CSS(在演示中):

ul.plainSelect {
    /* targets those 'ul' elements created by the plug-in */
    border: 1px solid #000;
}
ul.plainSelect li {
    /* this styles the 'selected' li 'option' element */
    background-color: #f90;
    display: list-item;
}
ul.plainSelect li.guidance {
    /* this is the 'Select a Reason' guidance/explanation from the image in the question */
    border-bottom: 1px solid #000;
    padding: 0.3em;
    font-weight: bold;
    font-size: 1.2em;
    background-color: #fff;
}

ul.plainSelect li.unselected {
    /* hides the 'unselected' options, and removes the background-color for contrast */
    background-color: #fff;
    display: none;
}

ul.plainSelect:hover li,
ul.plainSelect:hover li.unselected {
    /* ensures that the 'li' elements pop-up when the list is hovered over, */
    /* and act/display like 'li' elements */
    display: list-item;
}

JS Fiddle 演示

Here's one way of doing it, though I'd prefer a more plug-in approach (rather than hard-coding the html ul):

$('#selectUl li:not(":first")').addClass('unselected');
// Used to hide the 'unselected' elements in the ul.

$('#selectUl').hover(
    function(){
    // mouse-over
        $(this).find('li').click(
            function(){
                $('.unselected').removeClass('unselected');
                // removes the 'unselected' style

                $(this).siblings('li').addClass('unselected');
                // adds 'unselected' style to all other li elements

                var index = $(this).index();
                $('select option:selected').removeAttr('selected');
                // deselects the previously-chosen option in the select

                $('select[name=size]')
                    .find('option:eq(' + index + ')')
                    .attr('selected',true);
                // assumes a 1:1 relationship between the li and option elements
            });
    },
    function(){
    // mouseout (or mouseleave, if they're different, I can't remember).
    });

JS Fiddle demo.


Edited to include an alert demonstrating the changes in the select element's value: JS Fiddle demo.


Edited to include the css and html used in the demo:

html

<select name="size">
    <option value="small">Small</option>
    <option value="medium">Medium</option>
    <option value="large">Large</option>
</select>

<ul id="selectUl">
    <li>small</li>
    <li>medium</li>
    <li>large</li>
</ul>

css:

select {
    opacity: 0.5;
}
ul {
    width: 8em;
    line-height: 2em;
}

li {
    display: list-item;
    width: 100%;
    height: 2em;
    border:1px solid #ccc;
    border-top-width: 0;
    text-indent: 1em;
    background-color: #f90;
}
li:first-child {
    border-top-width: 1px;
}

li.unselected {
    display: none;
    background-color: #fff;
}
ul#selectUl:hover li.unselected {
    background-color: #fff;
}
ul#selectUl:hover li,
ul#selectUl:hover li.unselected {
    display: list-item;
}
ul#selectUl:hover li {
    background-color: #fc0;
}
ul#selectUl li:hover,
ul#selectUl li.unselected:hover {
    background-color: #f90;
}

This causes the menu to hide the unselected items until the ul is hovered over, then revealing all the options, and uses the click() event to assign the unselected class name to the non-clicked elements; which allows the clicked element to be still visible on mouseout.

The above CSS reflects the most-recent edit, to make the currently-selected, and :hover-ed, li more visible.

Latest JS Fiddle demo.


Edited because, well, I got a little bored. And had nothing better to do, so I made a simple plug-in:

(function($) {
    $.fn.selectUl = function(){
        var $origSelect = $(this);
        var newId = $(this).attr('name') + '-ul';
        var numOptions = $(this).children().length;

        $('<ul id="' + newId + '" class="plainSelect" />')
            .insertAfter($(this));

        for (var i = 0; i < numOptions; i++) {
            var text = $(this).find('option').eq(i).text();
           $('<li />').text(text).appendTo('#' + newId);
        }

        if ($(this).find('option:selected')) {
            var selected = $(this).find('option:selected').index();
            $('#' + newId)
                .find('li')
                .not(':eq(' + selected + ')')
                .addClass('unselected');
        }

        $('#' + newId + ' li')
            .hover(
                function(){
                    $(this).click(
                        function(){
                            var newSelect = $(this).index();
                            $(this)
                                .parent()
                                .find('.unselected')
                                .removeClass('unselected');
                            $(this)
                                .parent()
                                .find('li')
                                .not(this)
                                .addClass('unselected');
                            $($origSelect)
                                .find('option:selected')
                                .removeAttr('selected');
                            $($origSelect)
                                .find('option:eq(' + newSelect + ')')
                                .attr('selected',true);
                        });
                },
                function(){
            });
                    // assuming that you don't want the 'select' visible:
                    $(this).hide();

        return $(this);
    }
        })(jQuery);


$('#sizes').selectUl();

JS Fiddle demo, including the 'plug-in'.

Notes:

  • This isn't absolutely positioned, so if you have more than one select (which you can certainly do, and works okay) it does screw with the page-flow a little (or a lot), but this can be amended in the CSS (I'd imagine, though I've not yet tried).
  • It could probably do with some options, possibly allowing dl elements to be used in place of the current ul, which would allow for giving an explanation of the available options.
  • I suspect that it could be optimised a great deal more than it currently is, but I'm not, off-hand, sure how. Possibly some sleep and, late, browsing the jQuery API might offer some insights (though if anyone sees anything obvious please leave a comment! Or take the JS Fiddle and, for want of a better term, fork it (though I'd obviously appreciate links to any subsequent forks/updates).
  • I'm not entirely sure what licensing options are available to me (since everything on SO is Creative Commons cc-by-sa, according to Jeff Atwood, and the footer of this site, anyway), but for what it's worth I'm quite happy for anyone to take the above and, well, do whatever you like with it (if it's of any use, have fun!).

Edited because I felt that there should be a visible 'guidance' element, and also to try and explain something of how it all works.

Given the html:

<select name="sizes" id="sizes" class="makePlain" title="Select a size:">
    <option value="xxs">XX-Small</option>
    <option value="xs">X-Small</option>
    <option value="s">Small</option>
    <option value="m">Medium</option>
    <option value="l">Large</option>
    <option value="xl">X-Large</option>
    <option value="xxl">XX-Large</option>
</select>

Use the jQuery to call the plugin:

$('#sizes').selectUl();

This takes the above select, and creates a ul with the following mark-up:

<ul id="sizes-ul" class="plainSelect">
    <li class="guidance">Select a size:</li>
    <li>XX-Small</li>
    <li class="unselected">X-Small</li>
    <li class="unselected">Small</li>
    <li class="unselected">Medium</li>
    <li class="unselected">Large</li>
    <li class="unselected">X-Large</li>
    <li class="unselected">XX-Large</li>
</ul>

The CSS used (in the demo):

ul.plainSelect {
    /* targets those 'ul' elements created by the plug-in */
    border: 1px solid #000;
}
ul.plainSelect li {
    /* this styles the 'selected' li 'option' element */
    background-color: #f90;
    display: list-item;
}
ul.plainSelect li.guidance {
    /* this is the 'Select a Reason' guidance/explanation from the image in the question */
    border-bottom: 1px solid #000;
    padding: 0.3em;
    font-weight: bold;
    font-size: 1.2em;
    background-color: #fff;
}

ul.plainSelect li.unselected {
    /* hides the 'unselected' options, and removes the background-color for contrast */
    background-color: #fff;
    display: none;
}

ul.plainSelect:hover li,
ul.plainSelect:hover li.unselected {
    /* ensures that the 'li' elements pop-up when the list is hovered over, */
    /* and act/display like 'li' elements */
    display: list-item;
}

JS Fiddle demo.

我不是你的备胎 2024-10-17 05:56:14

以您所描述的简单方式打开选择框是不可能的。您提供的图像看起来一点也不像普通的选择框,这并非巧合。这是因为它实际上可能是一个 ul 列表,其样式看起来就像它一样,在悬停时显示自己,这实际上是可能的。

我在 jsfiddle 上创建了一个示例 over on jsfiddle 来说明如何完成此操作。

It is impossible to open a select box in the plain way your are describing. It is no coincidence that the image you have provided looks nothing like a normal select box. This is because it is probably actually a ul list which is styled to look as it does, revealing itself on hover, which is actually possible.

I created an example over on jsfiddle of how it could be done.

愁杀 2024-10-17 05:56:14

如果您有兴趣这样做,我有一个简单的非 JavaScript 方法可以在我当前的项目 实际上(查看顶部的“我想要”菜单)。就像@Marcus所说,这不是使用选择框,而是使用无序列表(

    )完成的。

html 很简单:

<div id="iWantToMenuContainer">
<ul id="i-want-to" class="menu">
    <li><a href="http://cumberlandme.info/contact">contact the town office</a></li>
    <li><a href="http://cumberlandme.info/upcoming-events">find out what’s happening</a></li>
    <li><a href="http://cumberlandme.info/online-services">get permits and services applications</a></li>
</ul>
</div>  

重要的部分是 css,本质上只是前 2 条规则。由于 :hover 上的 overflow:visible,div 似乎展开了。

#iWantToMenuContainer {
    overflow:hidden;
}
#iWantToMenuContainer:hover {
    overflow:visible
    }
#iWantToMenuContainer ul {
    border:1px solid #b6c2b9;
    background:#fff;
    padding:1px 20px 3px 5px
    }
#iWantToMenuContainer a:link,#iWantToMenuContainer a:visited {
    display:block;
    background: #fff;    
}
#iWantToMenuContainer a:hover {
    background:#e6e6e6
    }

If you're interested in doing it this way, I've got a simple, non-javascript way of doing it on my current project actually (look at the "I Want To" menu at the top). Like @Marcus said, this is not with a select box, but is done with a unordered list (<ul>).

The html is straightforward:

<div id="iWantToMenuContainer">
<ul id="i-want-to" class="menu">
    <li><a href="http://cumberlandme.info/contact">contact the town office</a></li>
    <li><a href="http://cumberlandme.info/upcoming-events">find out what’s happening</a></li>
    <li><a href="http://cumberlandme.info/online-services">get permits and services applications</a></li>
</ul>
</div>  

the important part is the css, essentially just the first 2 rules. The div appears to expand because of the overflow:visible on :hover.

#iWantToMenuContainer {
    overflow:hidden;
}
#iWantToMenuContainer:hover {
    overflow:visible
    }
#iWantToMenuContainer ul {
    border:1px solid #b6c2b9;
    background:#fff;
    padding:1px 20px 3px 5px
    }
#iWantToMenuContainer a:link,#iWantToMenuContainer a:visited {
    display:block;
    background: #fff;    
}
#iWantToMenuContainer a:hover {
    background:#e6e6e6
    }
猫烠⑼条掵仅有一顆心 2024-10-17 05:56:14

目前正在工作,所以无法检查 youtube,但从样式来看,我猜测“选择”控件不是实际的选择控件。它很可能像导航下拉菜单一样实现,但不是在单击时导航到 url,而是替换输入标签的内容和值。然后在表单提交时它可以获取标签的值。

At work at the moment so can't check youtube but from the styling I am guessing that that "select" control is not an actual select control. Most likely it is implemented like a navigational drop down menu but instead of navigating to a url on click it replaces the contents and value of an input label. Then on form submit it can pick up the value of the label.

以酷 2024-10-17 05:56:14

链接到更新的 jquery 插件 分叉 $.selectUI 插件

  • 修复传入的多个元素的迭代

Link to the updated jquery plugin Forked $.selectUI plugin

  • Fixes iteration over multiple elements passed in
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文