这篇文章主要介绍了 JavaScript tab 选项卡插件实例代码的相关资料, 需要的朋友可以参考下
Javascript 是一种由 Netscape 的 LiveScript 发展而来的原型化继承的基于对象的动态类型的区分大小写的客户端脚本语言,主要目的是为了解决服务器端语言,比如 Perl,遗留的速度问题,为客户提供更流畅的浏览效果。
今天,先从最简单的开始,将已有的一个 Tab 选项卡切换功能改写成 javascript 插件形式。
原生函数写法
将一个 javascript 方法改写为 js 插件最简单的方式就是将这个方法挂载到 window 全局对象下面
我们先来看看最原始的使用函数写法的代码:
tab.html
- <!DOCTYPE html>
- <html>
- <head lang="en">
- <meta charset="UTF-8">
- <meta http-equiv="X-UA-Compatible" content="IE=edge">
- <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
- <meta name="renderer" content="webkit">
- <title>
- jquery_hjb_tab插件demo
- </title>
- <link rel="stylesheet" href="h.css" />
- </head>
- <body>
- <div id="tab">
- <div class="tabs">
- <ul>
- <li>
- <a href="#">
- tab1
- </a>
- </li>
- <li>
- <a href="#">
- tab2
- </a>
- </li>
- <li>
- <a href="#">
- tab3
- </a>
- </li>
- <li>
- <a href="#">
- tab4
- </a>
- </li>
- </ul>
- </div>
- <div class="tabCons">
- <section>
- 内容一
- </section>
- <section>
- 内容二
- </section>
- <section>
- 内容三
- </section>
- <section>
- 内容四
- </section>
- </div>
- </div>
- <script>
- window.onload = h_tab('tab');
- function h_tab(tabId) {
- var oLinks = document.getElementById(tabId).getElementsByTagName("a");
- var oCons = document.getElementById(tabId).getElementsByTagName("section");
- for (var i = 0; i < oLinks.length; i++) {
- oLinks[i].index = i;
- oLinks[i].onclick = function() {
- for (var j = 0; j < oLinks.length; j++) {
- oLinks[j].className = "";
- oCons[j].style.display = "none";
- }
- this.className = "cur";
- oCons[this.index].style.display = "block";
- }
- }
- }
- </script>
h.css
- @charset "utf-8";
- /*
- //author:hjb2722404
- //description:
- //date:2016/2/18
- */
- .tabs ul {
- width: 100 % ;
- list - style - type: none;
- }.tabs ul li {
- width: 48 % ;
- display: inline - block;
- margin: 0;
- padding: 0;
- }.tabs ul li a {
- border - bottom: 3px solid#cccccc;
- width: 100 % ;
- height: 100 % ;
- display: block;
- text - align: center;
- min - height: 40px;
- line - height: 40px;
- text - decoration: none;
- font - family: "微软雅黑";
- color: #a94442
- }.tabs ul li a.cur {
- border - bottom: 3px solid#f26123;
- }.tabCons section {
- display: none;
- }.tabCons section: nth - child(1) {
- display: block;
- }
上面两份代码为基本代码,之后我们后一步步在这份代码的基础上进行改进。
原生插件写法
好,现在,我们就来将这个方法改写成挂载在 window 对象下的插件:
tab.html
- ……
- // 下面是第一次改动
- <script type="text/javascript" src="h_tabs.js"></script>
- <script>
- H_tab("tab");
- </script>
- </body>
- </html>
h_tabs.js
- window.H_tab = function(tabId){
- var oLinks = document.getElementById(tabId).getElementsByTagName("a");
- var oCons = document.getElementById(tabId).getElementsByTagName("section");
- for(var i = 0; i<oLinks.length; i++){
- oLinks[i].index = i;
- oLinks[i].onclick = function () {
- for(var j =0; j<oLinks.length; j++){
- oLinks[j].className="";
- oCons[j].style.display = "none";
- }
- this.className="cur";
- oCons[this.index].style.display ="block";
- }
- }
- };
但是,我们发现这样的写法虽然很简单,但也有问题:window 作为一个全局对象,如果我们把自己的方法都挂载到它下面作为插件使用的话,插件一多,就容易产生命名空间冲突,另一方面,使用原生 js 虽然可以减少对外部的依赖,但代码量相对还是很大,写法比较繁琐。
jquery 写法
我们尝试引入 jquery 库,将此插件改写为 jquery 插件。
jquery 插件有三种形式:类级别的形式,对象级别的形式,jquery UI 组件的形式
jquery 类级别插件写法–单个方法
我们先来看类级别插件的形式。
第一种类级别插件的形式,直接把该方法挂载到 jquery 的根空间下,作为一个工具方法:
tab.html
- ……
- <script src="../jquery.js" type="text/javascript"></script>
- <script type="text/javascript" src="h_tabs.js"></script>
- <script>
- $.h_tab('tab');
- </script>
- </body>
- </html>
h_tabs.js
- $.h_tab = function(tabId){
- var oLinks = document.getElementById(tabId).getElementsByTagName("a");
- var oCons = document.getElementById(tabId).getElementsByTagName("section");
- for(var i = 0; i<oLinks.length; i++){
- oLinks[i].index = i;
- oLinks[i].onclick = function () {
- for(var j =0; j<oLinks.length; j++){
- oLinks[j].className="";
- oCons[j].style.display = "none";
- }
- this.className="cur";
- oCons[this.index].style.display ="block";
- }
- }
- };
jquery 类级别插件写法 - 多个方法
如果你想要将多个方法绑定到 jquery 根空间上面,那么像下面这样写:
tab.html
- ……
- <script src="../jquery.js" type="text/javascript"></script>
- <script type="text/javascript" src="h_tabs.js"></script>
- <script>
- $.h_tab('tab');
- $.h_hello('hjb');
- </script>
- </body>
- </html>
h_tabs.js
- $.extend({
- h_tab:function(tabId){
- var oLinks = document.getElementById(tabId).getElementsByTagName("a");
- var oCons = document.getElementById(tabId).getElementsByTagName("section");
- for(var i = 0; i<oLinks.length; i++){
- oLinks[i].index = i;
- oLinks[i].onclick = function () {
- for(var j =0; j<oLinks.length; j++){
- oLinks[j].className="";
- oCons[j].style.display = "none";
- }
- this.className="cur";
- oCons[this.index].style.display ="block";
- }
- }
- },
- h_hello :function(name){
- console.log("hello,",name);
- }
- });
虽然使用 $.extend() 工具方法将自己的功能函数直接挂载到 jquery 根命名空间下,简单,省事儿,但很不幸的是,这样的方式不能利用 jquery 强大的 sizzle 引擎,即你选择到的 DOM 元素无法运用这个方法。
所以我们要用到对象级别的插件开发方式。
jquery 对象级别插件写法
对象级别的插件开发方式是利用 $.fn.extend() 方法将自己的方法绑定到 jquery 原型上去,这样所有 jquery 对象队可以应用该方法来执行相应操作了
代码如下:
tab.html
- ……
- <script src="../jquery.js" type="text/javascript"></script>
- <script type="text/javascript" src="h_tabs.js"></script>
- <script>
- //对象级别的插件引用方法,注意和上面类级别插件的写法上的区分
- $('#tab').h_tab('tab');
- </script>
- </body>
- </html>
h_tabs.js
- (function($){
- $.fn.extend({
- h_tab:function(tabId){
- var oLinks = document.getElementById(tabId).getElementsByTagName('a');
- var oCons = document.getElementById(tabId).getElementsByTagName('section');
- for(var i = 0; i<oLinks.length; i++){
- oLinks[i].index = i;
- oLinks[i].onclick = function () {
- for(var j =0; j<oLinks.length; j++){
- oLinks[j].className="";
- oCons[j].style.display = "none";
- }
- this.className="cur";
- oCons[this.index].style.display ="block";
- }
- }
- }
- });
- })(jQuery);
这里,我们利用一个闭包封装了插件,避免了命名空间污染
在这里,还有一些问题,就是我们的方法必须传参数才可以运行,这就导致调用的时候我们使用 $('#tab') 选择了 id 为 tab 的 div,然后在插件里我们又根据传入的 ID 获取了一遍该元素。
既然我们已经使用了 jquery 的选择器,那么我们就可以引入 this 来解决重复获取元素的冗余问题。
jquery 对象级别插件写法 - 引入 this
tab.html
- ……
- <script src="../jquery.js" type="text/javascript"></script>
- <script type="text/javascript" src="h_tabs.js"></script>
- <script>
- $('#tab').h_tab();
- </script>
- </body>
- </html>
h_tabs.js
- (function($){
- $.fn.extend({
- h_tab:function(){
- //在这里引入this
- var oLinks = this.find('a');
- var oCons = this.find('section');
- for(var i = 0; i<oLinks.length; i++){
- oLinks[i].index = i;
- oLinks[i].onclick = function () {
- for(var j =0; j<oLinks.length; j++){
- oLinks[j].className="";
- oCons[j].style.display = "none";
- }
- this.className="cur";
- oCons[this.index].style.display ="block";
- }
- }
- }
- });
- })(jQuery);
这里需要注意的是,我们调用该插件的元素对象是 (′tab′),则此时直接使用 this.find() 就等价于('tab').find(),而不是 $(this).find(),注意使用代入法来区分这两种写法的差别。
作为一款插件,它应该是可以被开发者控制的,所以还应该提供给使用者一些配置接口。
jquery 对象级别插件写法 - 加入配置项
tab.html
我们这里把一开始的 "当前选项卡标签样式类名称" 由 "cur" 改为了 "current",并将其作为配置项传入插件
h.css
- .tabs ul {
- width: 100 % ;
- list - style - type: none;
- }.tabs ul li {
- width: 48 % ;
- display: inline - block;
- margin: 0;
- padding: 0;
- }.tabs ul li a {
- border - bottom: 3px solid#cccccc;
- width: 100 % ;
- height: 100 % ;
- display: block;
- text - align: center;
- min - height: 40px;
- line - height: 40px;
- text - decoration: none;
- font - family: "微软雅黑";
- color: #a94442
- }
- /*注意下面一行与之前的样式代码的对比变化之处*/
- .tabs ul li a.current {
- border - bottom: 3px solid#f26123;
- }.tabCons section {
- display: none;
- }.tabCons section: nth - child(1) {
- display: block;
- }
我们在样式表中做出了相应的改动。
h_tabs.js
- (function($) {
- $.fn.extend({
- //给方法传入一个对象作为参数
- h_tab: function(opts) {
- //定义默认的配置
- var defaults = {
- curName: 'cur'
- };
- //将传入的参数覆盖默认参数中的默认项,最终合并到一个新的参数对象上
- var Opt = $.extend({},
- defaults, opts);
- var oLinks = this.find('a');
- var oCons = this.find('section');
- for (var i = 0; i < oLinks.length; i++) {
- oLinks[i].index = i;
- oLinks[i].onclick = function() {
- for (var j = 0; j < oLinks.length; j++) {
- oLinks[j].className = "";
- oCons[j].style.display = "none";
- }
- //在这里使用配置项的值
- this.className = Opt['curName'];
- oCons[this.index].style.display = "block";
- }
- }
- }
- });
- })(jQuery);
在这里我们使用了 jquery 的 $.extend() 方法的合并对象的功能,使用用户传入的配置项覆盖默认配置项并最终合并到一个新的配置项供后面的程序使用。
来源: http://www.phperz.com/article/17/0219/267030.html