让 select 的 option 标签支持事件监听(如复制操作)

这标题,让option支持事件监听,应该不难的呀,有什么好讲的? 其实还是有的,默认在浏览器代码是无法直接对option标签进行操作的,不仅包括JS事件监听,还是CSS样式设置 查了一些资料,姑且认为它是系统OS级别处理的

想自定义option的样式,很多人会建议用 <ul> <li> 标签来辅助同步操作与值

想对option进行事件监听,有一个tip:当给select显示设置了size 属性且值 大于1 时,才能监听

近来产品也提了个鼠标操作复制option值的需求,就利用这个size属性实现一番吧

先看图

实现小析

因为select的size属性表示默认展示多少个option,并设置这个高度

不过有了size之后,默认select右侧就会出现滚动条式样,加个 overflow:hidden 处理就行了

此外,功能操作与原select也有一些些不同,也要模拟处理

右键后生成一个复制按钮,点击复制则调用浏览器自身的复制命令

HTML

    <p>
        <input type="text" id="select-val" placeholder="值" size="1">
        <input type="text" id="copy-test" placeholder="测试复制">
    </p>

    <select style="overflow:hidden;">
        <option value="1">one</option>
        <option value="2">two</option>
        <option value="3">three</option>
        <option value="4">four</option>
        <option value="5">five</option>
    </select>

复制按钮的模板

要注意一个点,id为myCopyVal放在此处是为了方便定位元素,再调用文本select()方法,调用此方法时要求dom元素不能隐藏

所以需用 opacity:0 代替 type="hidden" | display:none | visibility:hidden

    <script type="text/template" id="btn-tpl">
        <p id="myCopy" style="position:fixed;z-index:1000;top:{{Y}}px;left:{{X}}px;margin:0;">
            <input type="button" id="myCopyBtn" style="border:1px solid #999;border-radius:3px;cursor:pointer;" value="复制"/>
            <input type="text" id="myCopyVal" style="opacity:0" value="{{val}}"/>
        </p>
    </script>

JS部分

    <script type="text/javascript" src="jquery.min.js"></script>
    <script type="text/javascript">
        // 模拟size的变化
        $('select')
            .focus(function() {
                // 动态设置size支持option的事件监听
                this.size = this.children.length;
            })
            .blur(function() {  
                // 恢复
                this.size = 1;
            })
            .change(function() {
                // 上下快捷键操作时,隐藏按钮
                $('#myCopy').remove();
                $('#select-val').val(this.value);
            });
        
        $('option')
            // 右键展示复制按钮
            .contextmenu(function(e) {
                $('#myCopy').remove();

                $('body').append($('#btn-tpl').html()
                    // 设置按钮位置
                    .replace('{{Y}}', e.pageY)
                    .replace('{{X}}', e.pageX + 10)
                    .replace('{{val}}', e.target.textContent || e.target.innerText)
                );

                return false;
            })
            // 点击操作恢复正常select
            .click(function() {
                $('#myCopy').remove();
                $(this).parent().blur();
            });

         
        $(document)
            // 直接Enter键 模拟select选择
            .keydown(function(e) {
                if (e.keyCode === 13) {
                    $('#myCopy').remove();
                    $('select').blur();
                }
            })
            // 点击外部区域,隐藏按钮
            .click(function(e) {
                if (e.target.id !== 'myCopyBtn') {
                    $('#myCopy').remove();
                }
            });

        // 执行复制操作
        $(document).on('click', '#myCopyBtn', function() {
            var $this = $(this);
            // 复制
            $this.next().select();
            document.execCommand('Copy');

            // 这里先不直接remove,防止循环引用
            $this.parent().hide();
            // 再次展示select下拉
            $('select').focus();
        });
    </script>

当然了,这个execCommand方法可能在某些浏览器上不支持,这里还没做兼容,复制功能也还有些简陋

就酱

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏上善若水

010HTML页面加载和解析流程详细介绍

2085
来自专栏极乐技术社区

微信小程序开发小技巧合揖(53个)

微信小程序:wx.navigateTo中url无法跳转问:链接 微信小程序布局之行内元素和块级元素:链接 小程序端JS加密,传输PHP端解密:链接 小程序开发干...

4329
来自专栏Theo Tsao

Ionic3学习笔记(五)动画之使用 animate.css

animate.css 是一款强大的、跨浏览器的预设CSS3动画库,内置了很多典型的CSS3动画,兼容性好使用方便,可以应用于我们的基于Ionic3的Hybr...

3171
来自专栏ionic3+

【Appetite】ionic3实录(二)UI分析及总体配置

首先,如果你是初学者,我强力建议你先看完我这篇文章: 【开发指南】(四)Ionic3快速上手并了解这些

1113
来自专栏BestSDK

Mockplus教程:2钟搞定APP首页原型设计,3000个免费素材库

创建项目 ? 打开Mockplus,点击新建项目,选择“手机”项目类型与合适的页面尺寸,点击“确定”即创建成功,是不是不能更简单!无需任何文件创建操作,无需输入...

3085
来自专栏崔庆才的专栏

腾讯云Ubuntu搭建Selenium+PhantomJS环境过程

前言大部分网页可以直接请求爬取,但是如果页面是JS渲染的该怎么办呢?如果我们单纯去分析一个个后台的请求,手动去摸索JS渲染的到的一些结果,那简直没天理了。所以,...

7880
来自专栏进击的君君的前端之路

JS相关概念

1392
来自专栏做全栈攻城狮

游戏开发7天快速入门(3)-GUI图形用户界面及NGUI详解

其实想一下OnGUI方法是在每一帧重绘时进行调用。所以在每一帧的时候就会重新绘制文本框的内容。所以导致哪怕我们进行删除重新输入,则导致又被重新绘制了。所以这个时...

1043
来自专栏jiajia_deng

react-router 环境使用锚点的方法

1982
来自专栏移动端开发

这个断点可以帮你检查布局约束

前言:     在现在iOS布局中,估计有很多很多开发者会使用到 Masonry 或者用到 SDAutoLayout 或者Storyboard或者还有Xib等等...

2169

扫码关注云+社区

领取腾讯云代金券