使用单体模式设计原生js插件
----------基于上次写的jquery插件进行改造 http://www.cnblogs.com/GerryOfZhong/p/5533773.html
背景:jQuery插件依赖jQuery库,虽然jQuery使用十分广泛,但是对于移动开发或者在其他带宽需求需要注意的时候,就得考虑,因为我不可能完成一项技术相对来说引用了一个更大的库,这样之不值得的。所以原生js是所有浏览器都支持的一种语言,原生js相对来说就very good了,但是原生js相对新手或者没有很强基础的人来说还是相对比较深奥晦涩一点的,毕竟要考虑一些额外的因素:
- 不能污染全局的变量,因为你不知道你的代码将会和其他库或者页面加载的广告代码进行冲突
- 一些高阶的设计模式,因为一些设计模式都是十分经典的思想的凝结,用语言实现也相对比较复杂
- 前端面向对象编程,因为js自由度比较高,没有和后台定义一样。比如模拟的接口,继承,封装等,来实现功能强大的架构或者需求
- ..........
设计模式:单体模式
好处:在使用单体模式的时候,你会享受到真正的私有成员带来的所有好处,而不必付出什么代价,因为单体泪只会被实例化一次单体模式之所以是javascript中最流行的、应用最广泛的模式之一
描述性命名增强代码的自我说明性
包裹单体中可以防止被其他人误改
与第三方库和广告隔离起来
后期进行优化,比如惰性加载
弊端:在使用单体模式的时候,必须要十分了解闭包等概念,而且以后结合其他设计模式共同使用的时候,复杂度和代码量相对来说要求更高,所以需要使用者自己进行衡量,值不值得使用,会不会增加项目开发难度等。如果值得就用,不值得就不建议使用
下面为闭包单体模式的骨架(用空专门讲设计模式和一些案例和使用):
var nameSpance= window.nameSpance|| {}; //声明一个空间 nameSpance.gerry=(function(){
//这里可以存放私有属性和私有方法,不对外开放,防止其他开发者私自改动
var privateAttr = false; function privateMethod (){
console.log("这是私有方法,不对外开放...");
} //这里为抛出对象,供开发者使用的
var publicObject = {
publicAttr : true,
publicMethod : function(){
console.log("这是抛出方法,供开发者使用...")
}
} return publicObject;
})()
原生代码设计:
- 声明空间然后搭建骨架
var gerry = window.gerry || {}; //声明
gerry.setBackgroundImage = (function(){ var publicMethods = {};return publicMethods;
})()
- 设置插件默认值(注明:该默认值不提供外部修改,不开放特权方法去set改变它的值)
var gerry = window.gerry || {}; //声明
gerry.setBackgroundImage = (function(){
//私有参数设置(不对外开放)
var config={
imgArr: [], //图片数组
imgSecond: 1000, //图片淡出的时间
isRandom:false //是否为随机图片
} //暴露给开发者使用的方法,可随意拓展
var publicMethods = {};
return publicMethods ;
})() - 封装一些tool,放在私有方法中,因为毕竟不是jQuery了,一些方法需要自己进行封装下
var tool = {
//ID选择器
id_selector:function (selector){
return document.getElementById(selector);
},
//创建节点
createElement:function(node){
return document.createElement(node);
},
//设置节点属性
attr:function(setArrObject){
for(var i = 0,len=setArrObject.attribute.length;i<len;i++){
setArrObject.node.setAttribute(setArrObject.attribute[i].key,setArrObject.attribute[i].value);
}
}
} - 设置一些需要使用的样式,放到一个css对象中
//设置的样式
var css = {
divT : 'position:absolute;left:0;top:0;z-index:-1;overflow:hidden;width:100%;height:100%',
ImgT:'position:absolute;left:0;top:0;z-index:-2;opacity:0;',
} - 封装一些私有方法处理一些常用的方法,比如参数处理呀啥的
//私有方法,不对外开放
var privateMethods = {
//对开发者的配置进行处理
paraHandling:function(option){
var configTemp ;
if(option.config != undefined){ //开发者设置了值
option.config.imgArr== undefined ? option.config.imgArr =config.imgArr:null;
option.config.imgSecond== undefined ? option.config.imgSecond = config.imgSecond:null;
option.config.isRandom== undefined ? option.config.isRandom = config.isRandom:null;
configTemp = option.config;
}else{
configTemp = config;
};
return configTemp;
},
//针对IE9处理淡出效果,因为IE9不支持transition
divFadeIn:function(option){
if(option.selector == undefined){
throw new Error("please select a id (div).")
}else{
var showTime = Number(option.config.imgSecond);
var opacityValue = 0; //设置opacity的属性值
var divSelector = tool.id_selector(option.selector); //获得div的ID
var temp = setInterval(function(){
opacityValue+=0.01;
divSelector.style.opacity = opacityValue;
if(opacityValue>1){
clearInterval(temp);
}
},showTime/100); //针对ie9 用opacity配合setInterval定时函数来实现淡出的效果,注意控制刷新的频率,给视觉上一种流畅的感觉
}
},
//创建内容主题
createContent:function(option){
//设置ID
var divImg = tool.createElement("div");
var object_div = {
node:divImg,
attribute:[
{
key:"id",
value:"divShow"
},
{
key:"style",
value:css.divT
}
]
};
tool.attr(object_div); //设置img属性
var img = tool.createElement("img");
var object_div = {
node:img,
attribute:[
{
key:"id",
value:"imgShow"
},
{
key:"style",
value:css.ImgT+"transition:opacity "+option.config.imgSecond/1000+"s ease",
}
]
};
tool.attr(object_div);
divImg.appendChild(img);
document.body.appendChild(divImg);
privateMethods.delayLoadImg(option.config.imgArr[0]);
},
//延迟加载图片
delayLoadImg:function(img_src){
var img = new Image();
img.src = img_src;
img.onload = function(){
var temp = {
node:tool.id_selector("imgShow"),
attribute:[
{
key:"src",
value:img_src
}
]
};
tool.attr(temp); tool.id_selector("imgShow").style.opacity = 1;
} }
} - 最后再抛出的供给开发者使用的init方法,里面检查一些参数和属性
//暴露给开发者使用的方法,可随意拓展
var publicMethods = {
init:function(option){
if(arguments.length == 0){ //检查参数
throw new Error("this method need a config object");
}else{
if(document.body.style.opacity == undefined){ //检测是否支持opacity属性 [即IE9及以上]
throw new Error("please use the browser of high version ");
}else {
option.config = privateMethods.paraHandling(option);
option.selector = "divShow";
//如果是IE9的话
if (document.body.style.transition == undefined) {
privateMethods.createContent(option);
privateMethods.divFadeIn(option);
} else {
privateMethods.createContent(option);
};
}
}
}
} - 测试代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
</body>
</html>
<script src="setBackgroundImage_js.js"></script>
<script>
+(function(){
var temp ={
config:{
imgArr:["http://z.k1982.com/show_img/201303/2013033012383895.jpg"],
imgSecond:3000
}
}
gerry.setBackgroundImage.init(temp);
})()
</script>
总结与说明:
因为IE8下面的滤镜比较麻烦,所以也没有对IE8做处理,就IE9+ 因为支持透明属性。移动端没做过测试,不过应该可以使用,因为针对移动端的话就更加简单了,因为现在移动端的趋势都是相对来说支持一些普遍的html5和css3的熟悉的。其实上面代码中主要讲的思想和对ie9做的兼容性,因为不可以使用第三方库了,所以就自己写了。整个代码我也不贴了,直接放到github上了,希望大家点颗星赞一个,得到人的赏识还是很有动力的。
github地址:https://github.com/GerryIsWarrior/setBackgroundImage_js
使用单体模式设计原生js插件的更多相关文章
- 原生JS插件(超详细)
作为一个前端er,如果不会写一个小插件,都不好意思说自己是混前端界的.写还不能依赖jquery之类的工具库,否则装得不够高端.那么,如何才能装起来让自己看起来逼格更高呢?当然是利用js纯原生的写法啦. ...
- 如何定义一个高逼格的原生JS插件
插件的需求 我们写代码,并不是所有的业务或者逻辑代码都要抽出来复用.首先,我们得看一下是否需要将一部分经常重复的代码抽象出来,写到一个单独的文件中为以后再次使用.再看一下我们的业务逻辑是否可以为团队服 ...
- 【原生JS插件】LoadingBar页面顶部加载进度条
先展示一下已经实现的效果: 预览地址:http://dtdxrk.github.io/js-plug/LoadingBar/index.html 看到手机上的浏览器内置了页面的加载进度条,想用在pc上 ...
- JS设计模式之单体模式(Singleton)
单体模式作为一种软件开发模式在众多面向对象语言中得到了广泛的使用,在javascript中,单体模式也是使用非常广泛的,但是由于javascript语言拥有其独特的面向对象方式,导致其和一些传统面向对 ...
- javascript中单体模式的实现
单体模式作为一种软件开发模式在众多面向对象语言中得到了广泛的使用,在javascript中,单体模式也是使用非常广泛的,但是由于javascript语言拥有其独特的面向对象方式,导致其和一些传统面向对 ...
- 封装js插件学习指南
封装js插件学习指南 1.原生JavaScript插件编写指南 => 传送门 2.如何定义一个高逼格的原生JS插件 =>传送门 3.手把手教你用原生JavaScript造轮子 => ...
- 如何做JS 单体模式的设计---->>js设计模式<<-------单体模式
1. 单体模式是js中最基本 单最有用的模式之一,非常常用. 单体模式的基本结构如下: var Person = { name: 'lilu', age:', sayHi: function(){ a ...
- js的命名空间 && 单体模式 && 变量深拷贝和浅拷贝 && 页面弹窗设计
说在前面:这是我近期开发或者看书遇到的一些点,觉得还是蛮重要的. 一.为你的 JavaScript 对象提供命名空间 <!DOCTYPE html> <html> <he ...
- JS设计模式——5.单体模式
JS设计模式——5.单体模式 http://www.cnblogs.com/JChen666/p/3610585.html 单体模式的优势 用了这么久的单体模式,竟全然不知!用它具体有哪些好处呢? ...
随机推荐
- 13、容器之间的link
很多时候我们的业务分为前台和后台,例如:"前台的代码需要连接数据库进行数据操作":但是在写代码的时候我们并不知道后台数据库的地址是什么,所以我们可以docker通过固定的名字来 ...
- struct timeval 计时问题
linux编程中,如果用到计时,可以用struct timeval获取系统时间.struct timeval的函数原型如下: struct timeval { __kernel_time_t tv_s ...
- Windows7 64位中出现的KERNELBASE.dll错误的解决方法
最近在服程序时遇到个问题,电脑是win764位,编译完的exe测试,偶尔总报错,报错是偶尔的,有时候报错很频繁,但是有一次测试,测试了半天都没有报错,我以为好,发布输出没一会儿又报错了,真是崩溃了,所 ...
- stack和stack frame
首先,我们先来了解下栈帧和栈的基本知识: 栈帧也常被称为“活动记录”(activation record),是编译器用来实现过程/函数调用的一种数据结构. 从逻辑上讲,栈帧就是一个函数执行的环境,包含 ...
- 初学Ionic
官网 https://ionicframework.com/ 如连接所示,可跳转到该前端框架的官网,在这里提供了两种方式可供大家学习: Code with the CLI Design with lo ...
- Python学习之全局变量与global
刚学习Python,遇到个问题:为什么有些定义在函数外的变量可以直接被函数使用,有些就不行呢? 如: count = 0 def change(): count += 1 change() # 报错 ...
- JAVA—编码问题
一.编码.(引用 百度百科) 编码是信息从一种形式或格式转换为另一种形式的过程也称为计算机编程语言的代码简称编码.用预先规定的方法将文字.数字或其它对象编成数码,或将信息.数据转换成规定的电脉冲信号 ...
- 未能加载文件或程序集“ICSharpCode.SharpZipLib, Version=0.86.0.518, Culture=neutral, PublicKeyToken=1b03e6acf116
最近项目新增需求批量通过Excel导入数据,果断想到NPOI,结果导入的时候突然跳出 未能加载文件或程序集“ICSharpCode.SharpZipLib, Version=0.86.0.518, C ...
- parseInt/类型转换/字符串
1.pa'rseInt整型 1.1parseInt必须以数字开头的 var topVal = parseInt("28px"); console.log(topVal); 1.2非 ...
- C# 键盘中的按键对应KeyValue
首先先看一下什麼情況下需要對按鍵進行識別: KeyPress事件響應函數中,有KeyPressEventArgs, 對應於e.KeyChar; KeyDown事件響應中有KeyEventArgs 求取 ...