一个简单js select插件
现在,通过一个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插件的更多相关文章
- 编写一个简单的Jquery插件
1.实现内容 定义一个简单的jquery插件,alert传递进来的参数 2.插件js文件(jquery.showplugin.js) (function ($) { //定义插件中的方法 var me ...
- 实现一个简单的Vue插件
我们先看官方文档对插件的描述 插件通常会为 Vue 添加全局功能.插件的范围没有限制--一般有下面几种: 1.添加全局方法或者属性,如: vue-custom-element 2.添加全局资源:指令/ ...
- 使用jQuery.extend创建一个简单的选项卡插件
选项卡样式如图,请忽略丑陋的样式,样式可以随意更改 主要是基于jquery的extend扩展出的一个简单的选项卡插件,注意:这里封装的类使用的是es6中的class,所以不兼容ie8等低版本浏览器呦! ...
- 大前端工程化之写一个简单的webpack插件
今天写一个简单的webpack插件,来学习一下webpack插件 webpack插件机制可以使开发者在webpack构建过程中加入自己的行为,来针对自己项目中的一些需求做一些定制化 首先我们得知道一个 ...
- 手把手制作一个简单的IDEA插件(环境搭建Demo篇)
新建IDEA插件File --> new --> Project--> Intellij PlatForm Plugin-->Next-->填好项目名OK 编写插件新建工 ...
- 开发一个简单的babel插件
前言 对于前端开发而言,babel肯定是再熟悉不过了,工作中肯定会用到.除了用作转换es6和jsx的工具之外,个人感觉babel基于抽象语法树的插件机制,给我们提供了更多的可能.关于babel相关概念 ...
- 【酷Q插件制作】教大家做一个简单的签到插件
酷Q插件已经有很多了,社区分享一大堆,不过还是自己写才有乐趣,哈哈.不得不吐槽一下,酷Q竟然不更新了,出了个酷Q pro,还收费!!诶.不过这也影响不了咱写插件的心情,今天教大家写一个酷Q签到插件,虽 ...
- 搜索引擎快捷导航:一个简单的chrome插件(教程)
一.如何通过练习来提高学习新框架的最好姿势是:基于现有的业务来学习.即从工作中学习,从实践中学.但是,如果一直只使用新的框架来重写旧的业务,成长也会趋近于0.第一次,使用新框架时收获可能颇丰:第二次, ...
- 开发一个简单的chrome插件-解析本地markdown文件
准备软件环境 1. 软件环境 首先,需要使用到的软件和工具环境如下: 一个最新的chrome浏览器 编辑器vscode 2. 使用的js库 代码高亮库:prismjs https://prismjs. ...
随机推荐
- 最锋利的Visual Studio Web开发工具扩展:Web Essentials详解(转)
Web Essentials是目前为止见过的最好用的VS扩展工具了,具体功能请待我一一道来. 首先,从Extension Manager里安装:最新版本是19号发布的2.5版 然后重启你的VS开发环境 ...
- sass+compass+bootstrap三剑合璧高效开发记录
1. 先搭建环境,下载node.js,rubyinstaller,安装, 安装rubyinstaller时,要选上include system path,这样就会自动将node.js执行添加到wind ...
- 09_Sum游戏(UVa 10891 Game of Sum)
问题来源:刘汝佳<算法竞赛入门经典--训练指南> P67 例题28: 问题描述:有一个长度为n的整数序列,两个游戏者A和B轮流取数,A先取,每次可以从左端或者右端取一个或多个数,但不能两端 ...
- jenkins 更换主数据目录
工作中,由于Jenkins默认的主目录空间太小,导致需要将Jenkins默认的主目录修改到其它目录.本文针对更改Jenkins的主目录详细介绍. 注意:在Jenkins运行时是不能更改的. 请先将Je ...
- VMware + OpenStack: 从 Plugin 到 VIO (VMware Integrated OpenStack)的演进
VMware 做为实际上的企业虚拟化领导者,对 OpenStack 的态度一直在变化.一开始,VMware 表达出与 OpenStack 的竞争态度.随着 OpenStack 的逐步壮大并且一步一步进 ...
- 自定义input[type="radio"]的样式
对于表单,input[type="radio"] 的样式总是不那么友好,在不同的浏览器中表现不一. 为了最大程度的显示出它们的差别,并且为了好看,首先定义了一些样式: <fo ...
- MIT jos 6.828 Fall 2014 训练记录(lab 1)
注: 源代码参见我的github:https://github.com/YaoZengzeng/jos Part 1: PC Bootstrap +------------------+ <- ...
- spring加载xml
加载文件顺序 情形一:使用classpath加载且不含通配符 这是最简单的情形,Spring默认会使用当前线程的ClassLoader的getResource方法获取资源的URL,如果无法获得当前线程 ...
- HDU 4568 Hunter 最短路+状压DP
题意:给一个n*m的格子,格子中有一些数,如果是正整数则为到此格子的花费,如果为-1表示此格子不可到,现在给k个宝藏的地点(k<=13),求一个人从边界外一点进入整个棋盘,然后拿走所有能拿走的宝 ...
- 获取本机的IP地址(局域网)与主机名称
编写内容保存为bat @echo off &setlocal enabledelayedexpansion Rem '/*========获取本机的IP地址(局域网)=========*/ e ...