现在,通过一个select插件,来介绍一下js插件的构建过程。

1.先上效果图


2.目录构建


(1)这个select插件,我给它起名交hongselect,所以呢,首先建个hongselect的文件夹。

(2)接着建一个src目录来放源码。

(3)我想把源代码托管到github上,所以呢,再建一个README.md文件,来写这个插件的一个说明文档。

(4)然后建一个.gitignore文件,来说明那些文件或文件夹是不需要加入代码版本管理的。

(5)该插件依赖于jQuery,我们要下载它,对于js依赖,我们可以使用bower来管理,并使用bower来发布我们的插件。

(6)使用bower,新建一个bower.json来配置。

(7)最后代码的打包工作,使用grunt来对js,css,和img文件进行压缩。

(8)使用grunt,新建一个package.json来配置。

最终的目录结构如下(上面没提到的文件接下来会介绍):

3.源码书写


在src中,再建两个文件夹,一个css文件夹,用来放样式文件;一个img文件夹,用来放图片文件。

(1)JavaScript部分

在src中,新建一个hongselect.src.js文件。

源码如下:

(function ($) {
    var defaultOptions = {
        theme: "default"
    };

    //select object
    var HongSelect = function (element, options) {
        var that = this;
        that.origin = $(element);
        that.origin.hide();
        that.options = $.extend({}, defaultOptions, options);
        that.render();
    };

    HongSelect.prototype = {
        render: function () {
            var that = this;
            var theme = that.options.theme;
            that.container = that.container || that.origin.after("<div>").next();
            that.container.addClass(theme + "_hongselect");
            that.container.empty();
            var infoSpan = that.container.append("<span>").find("span");
            infoSpan.addClass(theme + "_info_span");
            var dl = that.container.append("<dl>").find("dl");
            dl.addClass(theme + "_dl");
            $(that.origin).find("option").each(function (i, option) {
                if (i == 0) {
                    infoSpan.text(option.text);
                }
                dl.append("<dd data-val=" + option.value + ">" + option.text + "</dd>");
            });

            //show selected value
            infoSpan.text($(that.origin).find('option:selected').text());

            //hide dd items
            dl.hide();
            var dd = dl.find("dd");
            dd.addClass(theme + "_dd");
            dd.hover(function () {
                $(this).addClass(theme + "_dd_hover");
            }, function () {
                $(this).removeClass(theme + "_dd_hover");
            });

            //show and hide
            infoSpan.click(function (e) {
                e.preventDefault();
                e.stopPropagation();
                dl.show();
            });
            dd.each(function () {
                $(this).click(function () {
                    infoSpan.text($(this).text());
                    $(that.origin).val($(this).attr("data-val"));
                    $(that.origin).trigger("change");
                });
            });

            //click blank hide
            $(document).click(function () {
                dl.hide();
            });
        },
        setSelectVal: function (value) {
            this.origin.val(value);
            this.render();
        },
        refresh: function () {
            this.render();
        }
    };

    $.fn.hongselect = function (option) {
        var args = Array.apply(null, arguments);
        args.shift();
        this.each(function () {
            var $this = $(this),
                data = $this.data('hongselect'),
                options = typeof option == 'object' && option;
            if (!data) {
                $this.data('hongselect', (data = new HongSelect(this, options)));
            }
            if (typeof option == 'string' && typeof data[option] == 'function') {
                data[option].apply(data, args);
            }
        });
        return this;
    };

})(jQuery);

  代码解释:

1)全局隔离函数

(function ($) {
    //...
})(jQuery);

  使用这样的一个立即执行的function的作用是什么呢?这样做是为了把我们插件的代码与全局代码隔离开,全部都在function这个作用域里,从而防止全局变量的污染。

2)扩展jQuery

 $.fn.hongselect = function (option) {
        var args = Array.apply(null, arguments);
        args.shift();
        this.each(function () {
            var $this = $(this),
                data = $this.data('hongselect'),
                options = typeof option == 'object' && option;
            if (!data) {
                $this.data('hongselect', (data = new HongSelect(this, options)));
            }
            if (typeof option == 'string' && typeof data[option] == 'function') {
                data[option].apply(data, args);
            }
        });
        return this;
    };

  这个是个jQuery扩展一个hongselect的方法。$.fn这个是什么呢?这个fn既是JavaScript中的prototype,jQuery只是用fn来替代prototype,这样你就能明白为什么$.fn.hongselect这样就能够使用$('选择器').hongselect()这样的方式来使用了。

其他的代码就比较简单,不一一详解了。

(2)接下来是写css了

在css中新建一个hongselect.css文件。

.default_hongselect {
    width: 150px;
    position: absolute;
}

.default_info_span {
    cursor: pointer;
    text-indent: 10px;
    color: #666;
    display: block;
    padding-right: 20px;
    height: 30px;
    line-height: 25px;
    background: url(../img/arrow.png) no-repeat right center;
    position: relative;
    border: 1px solid #ccc;
    text-overflow: ellipsis;
    overflow: hidden;
}

.default_dl {

    border-bottom: 1px solid #ccc;
    margin: 1px 0 0;
}

.default_dd {
    cursor: pointer;
    height: 30px;
    line-height: 25px;
    color: #666;
    white-space: normal;
    padding: 0 10px;
    background: #f1f1f1;
    margin: 0;
    border-left: 1px solid #ccc;
    border-top: 1px solid #ccc;
    border-right: 1px solid #ccc;
    text-overflow: ellipsis;
    overflow: hidden;
}

.default_dd_hover {
    background: #fff;
}

  (3)将图片放入img文件

OK,代码书写完毕。

4.测试


配置bower.json

{
  "name": "hongselect",
  "version": "0.0.1",
  "homepage": "https://github.com/smallyard/hongselect",
  "authors": [
    "smallyard <smallyard@live.cn>"
  ],
  "description": "A simple web select.",
  "main": "src/hongselect.src.js",
  "keywords": [
    "select"
  ],
  "license": "MIT",
  "ignore": [
    "node_modules",
    "bower_components"
  ],
  "devDependencies": {
    "jquery": "2.1.4"
  }
}

  在命令行使用命令下载jQuery,具体使用方法见bower官网。

bower install

  调用命令后,就会在当前目录下创建一个bower_components的文件夹,并将我们依赖的js下载到该目录。

  然后我们就可以引用它来做测试了,我们建一个doc/example来放我们的测试文件。

<html lang="en">
<head>
    <meta charset="utf-8">
    <title>HongSelect</title>
    <link rel="stylesheet" type="text/css" href="../../src/css/hongselect.src.css">
    <script type="text/javascript" src="../../bower_components/jquery/dist/jquery.min.js"></script>
    <script type="text/javascript" src="../../src/hongselect.src.js"></script>
    <script type="text/javascript">
        $(function(){
            $("#myselect").hongselect();
            $("#btn_setval").click(function(){
                $("#myselect").hongselect("setSelectVal","1");
            });
        });
    </script>
</head>
<body>
    <select id="myselect">
        <option value="1">one</option>
        <option value="2" selected>two</option>
        <option value="3">three</option>
        <option value="4">four</option>
        <option value="5">five</option>
    </select>
    <button id="btn_setval">set value = 1</button>
</body>
</html>

5.打包


好了,项目测试好之后我们就可以打包插件了。

我们用grunt来打包它,grunt配置如下,具体使用方法见官网。

1)package.json

{
    "name": "hongselect",
    "version": "0.0.1",
    "description": "A simple web select.",
    "dependencies": {
		"grunt": "^0.4.5",
		"grunt-contrib-uglify": "~0.2.2",
		"grunt-contrib-clean":"~0.6.0",
		"grunt-contrib-cssmin":"~0.10.0",
		"grunt-contrib-imagemin": "~0.7.0"
	}
}

 2)Gruntfile.js

module.exports = function (grunt) {
    grunt.initConfig({
        pkg: grunt.file.readJSON("package.json"),
        clean: {
            build: {
                src: ["dist/**"]
            }
        },
        uglify: {
            build: {
                src: "src/hongselect.src.js",
                dest: "dist/hongselect.min.js"
            }
        },
        cssmin: {
            build: {
                src: "src/css/hongselect.src.css",
                dest: "dist/css/hongselect.min.css"
            }
        },
        imagemin: {
            build: {
                src: "src/img/arrow.png",
                dest: "dist/img/arrow.png"
            }
        }
    });

    //注册插件
    grunt.loadNpmTasks("grunt-contrib-clean");
    grunt.loadNpmTasks("grunt-contrib-uglify");
    grunt.loadNpmTasks("grunt-contrib-cssmin");
    grunt.loadNpmTasks("grunt-contrib-imagemin");
    // 默认被执行的任务列表。
    grunt.registerTask("default", ["clean", "uglify", "cssmin", "imagemin"]);
};

  用命令行调用grunt就会将压缩好的js、css、img放入dist目录。

grunt

6.发布


通过bower命令发布

bower register <my-package-name> <git-endpoint>

  

发布后可以在bower.io上查找到:

7.托管


通过git将代码托管到github上。

git add
git commit
git push

  

地址:https://github.com/smallyard/hongselect

一个简单js select插件的更多相关文章

  1. 编写一个简单的Jquery插件

    1.实现内容 定义一个简单的jquery插件,alert传递进来的参数 2.插件js文件(jquery.showplugin.js) (function ($) { //定义插件中的方法 var me ...

  2. 实现一个简单的Vue插件

    我们先看官方文档对插件的描述 插件通常会为 Vue 添加全局功能.插件的范围没有限制--一般有下面几种: 1.添加全局方法或者属性,如: vue-custom-element 2.添加全局资源:指令/ ...

  3. 使用jQuery.extend创建一个简单的选项卡插件

    选项卡样式如图,请忽略丑陋的样式,样式可以随意更改 主要是基于jquery的extend扩展出的一个简单的选项卡插件,注意:这里封装的类使用的是es6中的class,所以不兼容ie8等低版本浏览器呦! ...

  4. 大前端工程化之写一个简单的webpack插件

    今天写一个简单的webpack插件,来学习一下webpack插件 webpack插件机制可以使开发者在webpack构建过程中加入自己的行为,来针对自己项目中的一些需求做一些定制化 首先我们得知道一个 ...

  5. 手把手制作一个简单的IDEA插件(环境搭建Demo篇)

    新建IDEA插件File --> new --> Project--> Intellij PlatForm Plugin-->Next-->填好项目名OK 编写插件新建工 ...

  6. 开发一个简单的babel插件

    前言 对于前端开发而言,babel肯定是再熟悉不过了,工作中肯定会用到.除了用作转换es6和jsx的工具之外,个人感觉babel基于抽象语法树的插件机制,给我们提供了更多的可能.关于babel相关概念 ...

  7. 【酷Q插件制作】教大家做一个简单的签到插件

    酷Q插件已经有很多了,社区分享一大堆,不过还是自己写才有乐趣,哈哈.不得不吐槽一下,酷Q竟然不更新了,出了个酷Q pro,还收费!!诶.不过这也影响不了咱写插件的心情,今天教大家写一个酷Q签到插件,虽 ...

  8. 搜索引擎快捷导航:一个简单的chrome插件(教程)

    一.如何通过练习来提高学习新框架的最好姿势是:基于现有的业务来学习.即从工作中学习,从实践中学.但是,如果一直只使用新的框架来重写旧的业务,成长也会趋近于0.第一次,使用新框架时收获可能颇丰:第二次, ...

  9. 开发一个简单的chrome插件-解析本地markdown文件

    准备软件环境 1. 软件环境 首先,需要使用到的软件和工具环境如下: 一个最新的chrome浏览器 编辑器vscode 2. 使用的js库 代码高亮库:prismjs https://prismjs. ...

随机推荐

  1. Oracle与SQL SERVER编程差异分析(入门)

    网上有关Oracle与SQL SERVER性能差异的文章很多,结论往往是让你根据数据量与预算来选择数据库.但实际项目中,特别是使用 .Net 开发的系统,支持以上两种数据库或者更多已经成为Boss的普 ...

  2. Google自定义搜索引擎

    本文主要介绍如何通过Google的API来定义自己的搜索引擎,并将Google搜索框嵌入到自己的web页面.另外,分析了自定义搜索引擎请求数据的url,模拟请求并获取搜索的结果. 1 写在前面 前段时 ...

  3. C#拖放实现餐饮系统转台操作

    转台是餐饮系统中常用的操作,一般系统都是右键选择弹出目标台界面,然后选择目标台确定,现在我们把需要转的台通过拖动到目标台图标上面就可以实现前面的操作,简单快捷. 转台操作时: 转台成功后: /// & ...

  4. 虚拟机LVM扩容

    1.先在Vmware上,把虚拟机硬盘做扩展 2.现在打开虚拟机发现系统的磁盘空间已经扩了,但是硬盘分区可用空间没变,还是原来的30G [root@localhost ~]# fdisk -l Disk ...

  5. Web性能优化之图片延迟加载

    来源:微信公众号CodeL 对于一些图片多,页面长的网页来说,如果每次打开页面加载全部的网页内容,页面加载速度势必会受到影响,如果每次打开网页只将网页可视区域的内容加载给用户 ,将大大提高网页浏览速度 ...

  6. 不会UML的程序员不是好构架师?

    情况描述 我已经工作两年半, 参加过一个网页游戏项目和一个IOS应用项目, 自以为参与度非常高, 也经常涉及到底层引擎和主逻辑业务. 目前想更快的向构架师方向发展. 最近在看\<Learning ...

  7. -bash: rz: command not found

    rz,sz是Linux/Unix同Windows进行ZModem文件传输的命令行工具.优点就是不用再开一个sftp工具登录上去上传下载文件. sz:将选定的文件发送(send)到本地机器rz:运行该命 ...

  8. C#往线程里传递参数

    Thread (ParameterizedThreadStart) 初始化 Thread 类的新实例,指定允许对象在线程启动时传递给线程的委托. Thread (ThreadStart) 初始化 Th ...

  9. Android Studio系列教程三--快捷键

    Android Studio系列教程三--快捷键 2014 年 12 月 09 日 DevTools 本文为个人原创,欢迎转载,但请务必在明显位置注明出处!http://stormzhang.com/ ...

  10. js中接口的声明与实现

    实现接口,必须实现接口里的所有方法. function Interface(name,fns){//声明一个接口类            this.name = name;            th ...