突破编程_前端_JS编程实例(工具栏组件)

news2024/11/18 2:28:31

1 开发目标

工具栏组件旨在模拟常见的桌面软件工具栏,所以比较适用于 electron 的开发,该组件包含工具栏按钮、工具栏分割条和工具栏容器三个主要角色,并提供一系列接口和功能,以满足用户在不同场景下的需求:

在这里插入图片描述

点击工具栏按钮后,可以回调用户传入的函数:

在这里插入图片描述

2 详细需求

2.1 工具栏按钮

(1)图标与标题: 工具栏按钮应包含一个可自定义的小图标和一个标题。图标和标题应清晰可见,且能够准确反映按钮的功能。

(2)点击动作: 用户点击工具栏按钮后,应触发相应的动作或事件。具体动作或事件由开发者在实现时定义。

(3)禁用接口: 工具栏按钮应提供禁用接口。当调用该接口后,按钮应变为禁用状态,具体表现为:

  • 小图标和标题变灰,以区分于正常状态的按钮。
  • 鼠标在禁用状态的按钮上移动时,不会变成手型图标。
  • 点击禁用状态的按钮不会触发任何动作或事件。

2.2 工具栏分割条

(1)视觉表现: 工具栏分割条应具有明确的视觉表现,用于区分不同组别的工具栏按钮。

(2)位置与布局: 工具栏分割条应位于一组工具栏按钮的两侧,帮助用户清晰地识别按钮组。

2.3 工具栏容器

(1)保存与渲染: 工具栏容器应负责保存工具栏按钮和工具栏分割条,并根据布局规则进行渲染,确保界面美观且易用。

(2)对外接口: 工具栏容器应提供一系列对外接口,以便开发者进行动态操作,如:

  • 动态增加一个工具栏按钮:提供接口允许开发者在运行时向工具栏容器中添加新的工具栏按钮。
  • 动态移除一个工具栏按钮:提供接口允许开发者在运行时从工具栏容器中移除已存在的工具栏按钮。
  • 动态调整工具栏按钮的位置或顺序:提供接口允许开发者在运行时调整工具栏按钮的布局。

3 代码实现

首先创建一个 neat_toolbar.js 文件,该文件用于本组件的工具类、目录处理函数的代码构建。

(1)在具体的业务代码编写之前,先实现一个工具类以及一些工具方法,方便后面调用:

class CommonUtil {

    // 设置 DIV 中的文字为水平与垂直居中
    static centerTextInDiv(container) {
        container.style.display = 'flex';
        container.style.textAlign = 'center';
        container.style.justifyContent = 'center';
        container.style.flexDirection = 'column';
    }

    // 设置 DIV 中的文字为垂直居中
    static centerYTextInDiv(container) {
        container.style.display = 'flex';
        container.style.justifyContent = 'center';
        container.style.flexDirection = 'column';
    }

    // 禁止文字选中
    static disableSelection(container) {
        if (typeof container.onselectstart != 'undefined') {
            container.onselectstart = function () { return false; };
        } else if (typeof container.style.MozUserSelect != 'undefined') {
            container.style.MozUserSelect = 'none';
        } else {
            container.onmousedown = function () { return false; };
        }
        container.style.cursor = 'default';
    }

    // 设置 DIV 为带图标的 label
    static setIconLabelInDiv(container, title, para) {
        container.style.display = 'flex';

        if (para.icon) {
            let divIcon = document.createElement('div');
            divIcon.style.height = '100%';
            if (para.iconWidth) {
                divIcon.style.width = para.iconWidth;
            }
            if (para.iconColor) {
                divIcon.style.color = para.iconColor;
            }
            if (para.iconSize) {
                divIcon.style.fontSize = para.iconSize;
            }
            container.appendChild(divIcon);
            CommonUtil.centerTextInDiv(divIcon);
            divIcon.innerHTML = '<i class="' + para.icon + '"></i>';
        }

        let divTitle = document.createElement('div');
        divTitle.style.height = '100%';
        if (para.fontSize) {
            divTitle.style.fontSize = para.fontSize;
        }
        container.appendChild(divTitle);
        CommonUtil.centerYTextInDiv(divTitle);
        divTitle.innerHTML = title;

        CommonUtil.disableSelection(container);
    }
}

(2)创建工具栏按钮类型:

class NeatToolBarItem {

    static NEATTOOLBARITEM_FONTSIZE = '14px';                     // 工具栏按钮标题字体大小
    static NEATTOOLBARITEM_ICON_WIDTH = '30px';                     // 工具栏按钮图标宽度
    static NEATTOOLBARITEM_FONT_COLOR = '#000';                     // 工具栏按钮标题字体颜色
    static NEATTOOLBARITEM_BACKGROUNDCOLOR = '#ffffff';           // 工具栏按钮默认背景颜色
    static NEATTOOLBARITEM_BACKGROUNDCOLOR_MOVE = '#e5f3ff';           // 鼠标划过时的颜色
    static NEATTOOLBARITEM_BACKGROUNDCOLOR_MOUSEDOWN = '#cce8ff';      // 鼠标按下时的颜色
    static NEATTOOLBARITEM_COLOR_DISABLE = '#888888';                 // 工具栏按钮禁用时的颜色
    static NEATTOOLBARITEM_COLOR_SPLITTER = '#dddddd';                 // 工具栏分割条颜色

    constructor(container, title, para) {
        this.container = container;                 // 本工具栏按钮的容器
        this.title = title;                         // 本工具栏按钮的标题
        this.para = para;                           // 配置参数,包含图标(为简便起见,使用font awesome)各种属性
        this.disableFlag = false;                   // 本工具栏按钮是否被禁用
        this.render();
    }

上面代码定义了 NeatToolBarItem 的一些默认属性与成员变量,并且创建构造函数,该函数接收调用者传入的 DIV 容器,并且调用 render 方法。
在 render 方法,需要渲染当前工具栏按钮,并且还要控制鼠标动作事件:

	render() {
        this.container.style.height = '100%';
        this.container.style.paddingRight = '10px';
        this.para.fontSize = NeatToolBarItem.NEATTOOLBARITEM_FONTSIZE;
        CommonUtil.setIconLabelInDiv(this.container, this.title, this.para);
        this.container.style.cursor = 'pointer';

        // 监听鼠标滑过事件  
        this.container.addEventListener('mouseover', function () {
            // 当鼠标滑过时,改变背景颜色 
            if (!this.disableFlag) {
                this.container.style.backgroundColor = NeatToolBarItem.NEATTOOLBARITEM_BACKGROUNDCOLOR_MOVE;
            }
        }.bind(this));

        // 监听鼠标滑出事件  
        this.container.addEventListener('mouseout', function () {
            // 当鼠标滑出时,改变背景颜色  
            if (!this.disableFlag) {
                this.container.style.backgroundColor = NeatToolBarItem.NEATTOOLBARITEM_BACKGROUNDCOLOR;
            }
        }.bind(this));

        // 监听鼠标按下事件  
        this.container.addEventListener('mousedown', function () {
            // 当鼠标按下时,改变背景颜色 
            if (!this.disableFlag) {
                this.container.style.backgroundColor = NeatToolBarItem.NEATTOOLBARITEM_BACKGROUNDCOLOR_MOUSEDOWN;
            }
        }.bind(this));

        // 监听鼠标释放事件来恢复颜色 
        this.container.addEventListener('mouseup', function () {
            // 当鼠标释放时,恢复背景颜色
            if (!this.disableFlag) {
                this.container.style.backgroundColor = NeatToolBarItem.NEATTOOLBARITEM_BACKGROUNDCOLOR_MOVE;
            }
        }.bind(this));

        // 处理点击回调函数
        if(this.para.onClick){
            this.container.addEventListener('click', this.para.onClick);
        }
        
    }

接下来需要定义工具栏按钮的启用和禁用状态,主要通过状态变量 disableFlag 来控制:

	// 启用
    setEnable() {
        this.container.style.color = NeatToolBarItem.NEATTOOLBARITEM_FONT_COLOR;
        if (this.para.iconColor) {
            this.container.childNodes[0].style.color = this.para.iconColor;
        }
        this.disableFlag = false;
        this.container.style.cursor = 'pointer';
    }

    // 禁用
    setDisable() {
        this.container.style.color = NeatToolBarItem.NEATTOOLBARITEM_COLOR_DISABLE;
        this.container.childNodes[0].style.color = NeatToolBarItem.NEATTOOLBARITEM_COLOR_DISABLE;
        this.disableFlag = true;
        this.container.style.cursor = 'default';
    }
}

(3)创建工具栏类型:

class NeatToolBar {
    constructor(container) {
        this.container = container;                 // 本工具栏的容器
        this.items = [];
        this.render();
    }

    render() {
        this.container.style.display = 'flex';
    }

    // 增加工具栏按钮
    addToolbarItem(title, para) {
        let itemContainer = document.createElement('div');
        this.container.appendChild(itemContainer);
        let item = new NeatToolBarItem(itemContainer, title, para);
        this.items.push(item);
        return item;
    }

    // 增加工具栏分割条
    addSplitter() {
        let splitterContainer = document.createElement('div');
        splitterContainer.style.margin = '2px';
        splitterContainer.style.border = '1px solid ' + NeatToolBarItem.NEATTOOLBARITEM_COLOR_SPLITTER;
        this.container.appendChild(splitterContainer);
    }
}

这是一个基础版的工具栏类,提供了添加按钮和分割条的基本功能。其包含两个核心方法:addToolbarItem(title, para) 以及 addSplitter()。

addToolbarItem(title, para) 主要作用在于:

  • 创建一个新的 div 元素 itemContainer 作为工具栏按钮的容器。
  • 将 itemContainer 添加到 container 中。
  • 创建一个新的 NeatToolBarItem 实例并将其添加到 items 数组中。
  • 返回新创建的 NeatToolBarItem 实例。

addSplitter() 主要作用在于:

  • 创建一个新的 div 元素 splitterContainer 作为工具栏分割条的容器。
  • 为 splitterContainer 设置样式,包括外边距(margin)和边框(border)。
  • 将 splitterContainer 添加到 container 中。

(4)完成工具栏组件的代码编写后,可以创建 neater_toolbar.html 文件,调用工具栏组件::

<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>header tab</title>
    <style>
        html {
            height: 100%;
        }

        body {
            margin: 0;
            height: 100%;
        }
    </style>
    <link rel="stylesheet" href="./font-awesome-4.7.0/css/font-awesome.css">
</head>

<body>
    <div id="divMain" style="height: 100%;width: 100%;">
        <div id="divToolbar"
            style="margin-top: 100px;margin-left: 100px; height: 30px;width: 600px;border: 1px solid #aaaaaa;"></div>
    </div>
</body>
<script src="./neat_toolbar.js"></script>
<script>

    let toolbar = new NeatToolBar(document.getElementById('divToolbar'));
    let para = {
        "icon": "fa fa-area-chart",
        "iconWidth": "30px",
        "iconColor": "#1e9f75",
        "onClick": function () { alert('hello toolbar') }
    }
    let toolbarItemChart = toolbar.addToolbarItem('查看曲线', para);

    para = {
        "icon": "fa fa-bar-chart",
        "iconWidth": "30px",
        "iconColor": "#d9534f",
    }
    let toolbarItemBar = toolbar.addToolbarItem('查看柱状图', para);
    toolbarItemBar.setDisable();

    toolbar.addSplitter();

    para = {
        "icon": "fa fa-picture-o",
        "iconWidth": "30px",
        "iconColor": "#4f9fcf",
    }
    let toolbarItemPic = toolbar.addToolbarItem('打开图片', para);

    toolbar.addSplitter();

    para = {
        "icon": "fa fa-info-circle",
        "iconWidth": "30px",
        "iconColor": "#777777",
    }
    let toolbarItemInfo = toolbar.addToolbarItem('关于', para);


</script>

</html>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1521802.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

中间件 | RPC - [Dubbo]

INDEX 1 Dubbo 与 web 容器的关系2 注册发现流程3 服务配置3.1 注册方式 & 订阅方式3.2 服务导出3.3 配置参数 4 底层技术4.1 Dubbo 的 spi 机制4.2 Dubbo 的线程池4.3 Dubbo 的负载均衡策略4.3 Dubbo 的协议 1 Dubbo 与 web 容器的关系 dubbo 本质上是一个 RPC 框架&…

leetcode代码记录(动态规划基础题(斐波那契数列)

目录 1. 题目&#xff1a;2. 斐波那契数列&#xff1a;小结&#xff1a; 1. 题目&#xff1a; 斐波那契数 &#xff08;通常用 F(n) 表示&#xff09;形成的序列称为 斐波那契数列 。该数列由 0 和 1 开始&#xff0c;后面的每一项数字都是前面两项数字的和。也就是&#xff1a…

基于高德地图JS API实现Vue地图选点组件

基于高德地图JS API2.0实现一个搜索选择地点后返回给父组件位置信息的功能&#xff0c;同时可以进行回显 目录 1 创建key和秘钥1.1 登录高德地图开放平台1.2 创建应用1.3 绑定服务创建秘钥 2 使用组件前准备2.1 导入loader2.2 在对应的组件设置秘钥2.3 引入css样式 3 功能实现…

【C语言】整型提升与算术转换

一、表达式求值 在我们平常的表达式求值的题目中&#xff0c;虽然看似是道很简单的题目&#xff1b;但是出题人总是会埋坑&#xff0c;其中最常见的就是整型提升与算术转换。 二、整型提升 C语⾔中整型算术运算总是⾄少以缺省(默认)整型(int)类型的精度来进⾏的&#xff1b;…

【MySQL基础】MySQL基础操作二

文章目录 &#x1f34e;1.数据库约束&#x1f350;约束类型&#x1f346;1.1NOT NULL&#x1f346;1.2UNIQUE&#x1f346;1.3DEFAULT&#x1f346;1.4PRIMARY KEY&#x1f346;1.5FOREIGN KEY &#x1f34f;2.查询操作&#x1f35f;2.1聚合查询&#x1f354;2.1.1聚合函数&…

视频号电商的风口来了!这个消息还有多少人不知道?

大家好&#xff0c;我是电商糖果 短视频做电商&#xff0c;这几年的热度真的是非常高&#xff0c;就是因为热度太高了&#xff0c;才让视频号也动了电商的心思。 腾讯推出的视频号是为了和抖音对打&#xff0c;这几年靠着微信输送的流量&#xff0c;视频号的日活已经渐渐有赶…

JavaSE-----认识异常【详解】

目录 一.异常的概念与体系结构&#xff1a; 1.1异常的概念&#xff1a; 1.2一些常见的异常&#xff1a; 1.3异常的体系结构&#xff1a; 1.4异常的分类&#xff1a; 二.异常的处理机制&#xff1a; 2.1 抛出异常&#xff1a; 2.2异常的捕获&#xff1a; 2.3try-catch-&…

JavaWeb一些开发问题

一、Restful package com.example.crudtest1.pojo;import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor;Data NoArgsConstructor AllArgsConstructor public class Result {private Integer code;//响应码&#xff0c;1 代表成功; 0 代表失…

浅易理解:卷积神经网络(CNN)

浅易理解卷积神经网络流程 本文的目录&#xff1a; 1 什么卷积神经网络 2 输入层 3 卷积层 4 池化层 5 全连接层 传统的多层神经网络只有 输入层、隐藏层、输出层 卷积神经网络&#xff08;CNN)&#xff1a; 在多层神经网络的基础上&#xff0c;加入了更加有效的特征学习部分…

315曝光黑灰产业链:主板机

关注卢松松&#xff0c;会经常给你分享一些我的经验和观点。 315晚会曝光主板机黑灰产业链&#xff0c;主板机是什么呢?可能很多人还不知道。在这里松松给大家普及一下&#xff0c;也欢迎大家关注卢松松哟! 主板机是什么呢? 通过报废手机的主板&#xff0c;拆出来后组装成主…

【Linux进程状态】

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 目录 前言 一、直接谈论Linux的进程状态 看看Linux内核源代码怎么说 1.1、R状态 -----> 进程运行的状态 1.2、S状态 -----> 休眠状态(进程在等待“资源”就绪) 1.3、T状…

NFTScan 正式上线 Blast NFTScan 浏览器和 NFT API 数据服务

2024 年 3 月 15 号&#xff0c;NFTScan 团队正式对外发布了 Blast NFTScan 浏览器&#xff0c;将为 Blast 生态的 NFT 开发者和用户提供简洁高效的 NFT 数据搜索查询服务。NFTScan 作为全球领先的 NFT 数据基础设施服务商&#xff0c;Blast 是继 Bitcoin、Ethereum、BNBChain、…

Linux 系统调用函数fork、vfork、clone详解

文章目录 1 fork1.1 基本介绍1.2 fork实例1.2.1多个fork返回值1.2.2 C语言 fork与输出1.2.3 fork &#x1f4a3; 2 vfork2.1 基本介绍2.2 验证vfork共享内存 3 clone3.1 基本介绍3.2 clone使用 1 fork 1.1 基本介绍 #include <sys/types.h> #include <unistd.h>p…

2024年【危险化学品经营单位主要负责人】找解析及危险化学品经营单位主要负责人模拟考试

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 危险化学品经营单位主要负责人找解析考前必练&#xff01;安全生产模拟考试一点通每个月更新危险化学品经营单位主要负责人模拟考试题目及答案&#xff01;多做几遍&#xff0c;其实通过危险化学品经营单位主要负责人…

Grok的开源的一些想法

Grok是埃隆马斯克的人工智能团队开发的大模型&#xff0c;自马斯克发布消息称将开源大模型&#xff0c;其热度就居高不下。Grok的开源能迅速帮助国内建立起AI应用的能力。 从xAI公布的数据来看&#xff0c;Grok在主流的测试方法中均已超过GPT-3.5&#xff0c;而其是开源发展速度…

如何使用Python进行数据可视化:Matplotlib和Seaborn指南【第123篇—Matplotlib和Seaborn指南】

如何使用Python进行数据可视化&#xff1a;Matplotlib和Seaborn指南 数据可视化是数据科学和分析中不可或缺的一部分&#xff0c;而Python中的Matplotlib和Seaborn库为用户提供了强大的工具来创建各种可视化图表。本文将介绍如何使用这两个库进行数据可视化&#xff0c;并提供…

高可用系统有哪些设计原则

1.降级 主动降级&#xff1a;开关推送 被动降级&#xff1a;超时降级 异常降级 失败率 熔断保护 多级降级2.限流 nginx的limit模块 gateway redisLua 业务层限流 本地限流 gua 分布式限流 sentinel 3.弹性计算 弹性伸缩—K8Sdocker 主链路压力过大的时候可以将非主链路的机器给…

性能测试工具——wrk的安装与使用

前言 想和大家来聊聊性能测试&#xff0c;聊到了性能测试必须要说的是性能测试中的工具&#xff0c;在这些工具中我今天主要给大家介绍wrk。 ​介绍 wrk是一款开源的性能测试工具 &#xff0c;简单易用&#xff0c;没有Load Runner那么复杂&#xff0c;他和 apache benchmar…

【Unity】读取Json的三种方法(JsonUtility,LitJson,Newtonsoft)

介绍 在Unity开发过程中&#xff0c;Json是比较常用的一种数据存储文本&#xff0c;尤其是在和第三方交互中&#xff0c;基本都是json格式。 先给出一个Json示例&#xff0c;我们来看看是如何解析的。 {"Player": [{"id": 1001,"name": "…

Linux网络编程: IP协议详解

一、TCP/IP五层模型 物理层&#xff08;Physical Layer&#xff09;&#xff1a;物理层是最底层&#xff0c;负责传输比特流&#xff08;bitstream&#xff09;以及物理介质的传输方式。它定义了如何在物理媒介上传输原始的比特流&#xff0c;例如通过电缆、光纤或无线传输等。…