本文将带您了解关于javascript–滥用CSS类属性或有效的设计模式?的新内容,同时我们还将为您解释javascript操作css的相关知识,另外,我们还将为您提供关于CSS/Javascript
本文将带您了解关于javascript – 滥用CSS类属性或有效的设计模式?的新内容,同时我们还将为您解释javascript 操作css的相关知识,另外,我们还将为您提供关于CSS / Javascript使用CSS类显示/隐藏DIV?、javascript – 是否有管理并行AJAX查询的设计模式?、javascript 中的设计模式之代理模式、JavaScript 常用的设计模式之工厂模式的实用信息。
本文目录一览:- javascript – 滥用CSS类属性或有效的设计模式?(javascript 操作css)
- CSS / Javascript使用CSS类显示/隐藏DIV?
- javascript – 是否有管理并行AJAX查询的设计模式?
- javascript 中的设计模式之代理模式
- JavaScript 常用的设计模式之工厂模式
javascript – 滥用CSS类属性或有效的设计模式?(javascript 操作css)
$(".toolWindow").click(toolWindow_click); $(".toolWindow").keypress(toolWindow_keypress);
像往常一样,类“toolWindow”通常也在CSS中定义并与一些视觉样式相关联:
.toolWindow{ color:blue; background-color:white; }
class属性现在不仅要指示元素的外观(可视状态),还要指示行为.因此,我经常使用这种方法并将CSS类名称更多地定义为伪对象类,然后仅视觉化CSS类.换句话说,每个类都代表状态(CSS样式)和行为(事件).
在某些情况下,我甚至创建了没有视觉样式的类,只是使用它们作为向元素分配行为的便捷方式.
此外,jQuery LiveQuery插件(以及live()内置函数)通过自动将事件绑定到属于特定类的动态创建元素,使这种方法更加有效.
最近我主要使用类名来定义关联DOM元素的一组公共行为,并且稍后使用它们来定义视觉样式.
问题:这是一个可怕的滥用CSS“类”属性,如果是这样,为什么?
另一方面,也许这是进一步实现“关注点分离”和提高HTML / DHTML页面可维护性的完美有效方法?
解决方法
这就是为什么两者都可以使用的原因.
CSS / Javascript使用CSS类显示/隐藏DIV?
但他们使用ID的工作.
我想做同样的事情,但我想使用一个类而不是id,所以如果我想要20个DIV的切换…隐藏/显示我不必添加额外的代码.
这是一些代码:
<script language="javascript"> function toggle() { var ele = document.getElementById("toggleText"); var text = document.getElementById("displayText"); if(ele.style.display == "block") { ele.style.display = "none"; text.innerHTML = "show"; } else { ele.style.display = "block"; text.innerHTML = "hide"; } } </script> <a id="displayText" href="javascript:toggle();">show</a> <== click Here <div id="toggleText"https://www.jb51.cc/tag/dis/" target="_blank">display: none"><h1>peek-a-boo</h1></div>
有人可以帮忙吗?
谢谢
解决方法
http://api.jquery.com/toggle/
$(".class").toggle(); or $(".class").show(); $(".class").hide();
javascript – 是否有管理并行AJAX查询的设计模式?
var data1 = null; var data2 = null; $.ajax({ url : url1,success: function(data) { data1 = data; if(data2) perform(); },}); $.ajax({ url : url2,success: function(data) { data2 = data; if(data1) perform(); },}); function perform() { //do interesting stuff on data1 and data2 }@H_301_10@你也喜欢这样吗?
解决方法
检查:jQuery:api.jquery.com/jquery.when
我们可以使用jQuery的$.when()方法,该方法获取这些“Deferred”对象的列表(所有jQuery Ajax方法返回Deferred对象),然后提供单个回调.
句法
$.when( // Deferred object (probably Ajax request),// Deferred object (probably Ajax request),// Deferred object (probably Ajax request) ).then(function() { // All have been resolved (or rejected),do your thing });@H_301_10@示例:
$.when($.ajax("/page1.PHP"),$.ajax("/page2.PHP")) .then(myFunc,myFailure);@H_301_10@
javascript 中的设计模式之代理模式
一、定义
当客户不方便直接访问一个对象或者不满足需要的时候,提供一个对象来控制堆这个对象的访问。
二、举例
惰性单例模式的实现依靠缓存代理
三、结构
代理模式需要一个本体对象和一个代理对象。在代理模式下,对于本体对象的特定的操作通过代理对象进行。如图所示
这种模式的关键点在于:本体对象和代理对象接口的一致性。也就是说如果需要不通过代理进行操作,那么直接操作本体对象依然可以。
四、实现
代理模式分为很多类,其中经常用到的有保护代理、虚拟代理、缓存代理。
1. 保护代理
保护代理的作用是当对本体对象的属性进行访问和赋值时,代理对象可以对其进行拦截。
在 ES6 中,代理是一个已经被实现的知识点,如下:
var obj = {
_name: "JYY",
age: 29
};
var objProxy = new Proxy(obj, {
get: function(target, key){
if(key === "_name") return undefined;
return target[key];
},
set: function(target, key){
if(key === "_name") return;
}
});
objProxy._name; // undefined
objProxy.age; // 29
上面的代码中 obj 是本体对象,objProxy 是代理对象,这个代理实现了禁止访问和设置内部私有属性的功能。在这段代码中,我们使用代理对象对本体对象的 get 和 set 方法进行了代理,本体对象和代理对象都包含了这个 set 和 get 接口(obj 对象本身内部实现了 get 和 set),所以如果我们绕过代理对象直接访问和赋值本体对象也是可以的:
var obj = {
_name: "JYY",
age: 29
};
console.log(obj._name); //JYY
obj._name = "hah";
console.log(obj._name); // hah
保护代理的重点在于,代理对象保护外界对于本体对象的可访问和可操作性,也就是说在保护代理中,代理对象是用于禁止外界对本体对象的操作,防止本体对象的属性被外界进行操作
2. 虚拟代理
虚拟代理在我理解,就是用户认为已经执行了某个功能,事实上却时使用代理对象进行占位,待触发的时机到来,才会真正的执行本体对象的操作。也就是虚拟代理把一些开销很大的对象,延迟到真正需要他的时候才采取创建。因此虚拟代理的使用伴随的是性能的提升。
典型的虚拟代理的例子就是节流,如下所示:
var resizeProxy = function(fn){
let timer = null;
return function(){
if(!timer){
timer = setTimeout(function(){
fn && fn();
timer = null;
},1000)
}
}
};
var resizeChange = function(){
console.log(1);
};
window.onresize = resizeProxy(resizeChange);
这段代码是经典的使用节流控制窗体尺寸大小改变事件触发的例子,作用就是让 resize 事件的触发不那么频繁,自定义的控制触发的频率,这对于性能的提升很有帮助。
在这段代码里面,resizeChange 就是本体,resizeProxy 就是代理,如果不使用代理直接将 fn 复制给 window.onresize 依旧是可用的。而使用代理的作用就是首先进行占位,开发中代理内部的代码是不可见的(比如提供的是 api),利用 resizeProxy 的不可见性,让客户认为已经调用了功能代码,但是事实上是我们并未立即执行代码,因为我们作为开发者知道立即执行会带来性能的丧失,只有在合适的时机我们才会委托代理执行本地代码,执行真正的业务代码。
3. 缓存代理
缓存代理在单例模式中就已出现,用于创建惰性代理模式,其原理就是在需要时创建对象,并将该对象保存在闭包中,这样可以一次创建多次使用。
当然在惰性单例中使用是缓存代理最简单的实现方式。在实际开发中,我们可能会遇到这样的场景,在 tab 中每个 tab 页都包含多个图表,因此在点击 tab 的时候就需要获取这个 tab 对应的图表的数据,这些数据都需要从后端请求。比如以某个省的地市经济统计情况为例,我们需要的页面如下:
可见这样的情况下,用户很可能不断地点击 tab 切换城市,然后和其他城市进行对比。如果每次点击都请求数据,带给用户的体验会非常差。这样的情况下,我们就可以做个全局的缓存,当然你可以保存在组件的状态中,除此之外缓存代理也是个很棒的选择。代码如下:
// 请求数据
function requestData(regionName){
return new Promise(function(resolve, reject){
var rest = ajax({
type: "post",
params: {regionName: regionName}
})
resolve(rest);
})
}
// 初始化数据代理方法
var proxyInit = (function(){
var cache = {};
return async function(regionName){
if(cache[regionName]){
return cache[regionName];
}else{
return cache[regionName] = await requestData(regionName);
}
}
});
proxyInit("石家庄");
五、总结
三种类型虽然均为代理模式,但是各自的目的并不相同,保护代理是为了阻止外部对内部对象的访问或者是操作等;虚拟代理是为了提升性能,延迟本体执行,在合适的时机进行触发,目的是减少本体的执行次数;缓存代理同样是为了提升性能,但是为了减缓内存的压力,同样的属性,在内存中只保留一份。
JavaScript 常用的设计模式之工厂模式
工厂模式的介绍
一个类或对象中往往会包含别的对象。在创建这种成员对象时,你可能会使用常规方式,也即用new关键字和类构造函数。问题在于这会导致相关的两个类之间产生依赖性。工厂模式有助于消除这两个类之间的依赖性的模式,它使用一个方法来决定究竟决定要实例化哪个具体的类。简单工厂模式使用一个类(通常是一个单体)来生成实例,复杂工厂模式则使用子类来决定一个成员变量应该使用哪个具体的类的实例。
简单工厂
假设你准备开几个自行车商店,每个店都有几种型号的自行车出售,这可以用一个Bicycle类来标识,假如你要出售某种型号的自行车,只需要调用sellBicycle方法即可:
/*BicycleShop class*/
var BicycleShop = function(){};
BicycleShop.prototype = {
sellBicycle:function(model){
var bicycle;
switch(model){
case ''The Speedster'':
bicycle = new Speedster();
break;
case 2:
bicycle = ...;
break;
default:
bicycle = ...;
}
Interface.ensureImplements(bicycle,Bicycle);
bicycle.assemble();
bicycle.wash();
return bicycle;
}
};
/* The Bicycle interface*/
var Bicycle = new Interface(''Bicycle'',[''assemble'',''wash'',''ride'',''repair'']);
/*Speedster class*/
var Sppedster = function(){
// implements Bicycle
...
};
Speedster.prototype = {
assemble:function(){ ... },
wash: function(){ ... },
ride:function(){ ... },
repair:function(){ ... }
};
/* 出售The Speedster型号的自行车*/
var giantCruusers = new BicycleShop();
var myNewBike = giantCruusers.sellBicycle(''The Speedster'');
当我们需要在供货目录中新加入一款车型,我们不用修改BicycleShop的代码,只需要将sellBicycle方法中“创建新实例”的这部分工作转交给一个简单的工厂对象。BicycleFactory 是一个单体,将createBicycle方法封装在一个命名空间中,然后你可以照常进行组装和清洗。这个BicycleFactory对象可以提供各种类来创建新的自行车实例。
/* BicycleFactory namespace*/
var BicycleFactory = {
createBicycle:function(model){
var bicycle;
switch(model){
case ''The Speedster'':
bicycle = new Speedster();
break;
case 2:
bicycle = ...;
break;
default:
bicycle = ...;
}
Interface.ensureImplements(bicycle, Bicycle);
return bicycle;
}
};
/* BicycleShop class, improved*/
var BicycleShop = function(){};
BicycleShop.prototype = {
sellBicycle:function(){
var bicycle = BicycleFactory.createBicycle(model);
bicycle.assemble();
bicycle.wash();
return bicycle;
}
};
BiycleFactory就是简单工厂模式的例子,这种模式把成员对象的创建工作转交给一个外部对象。
工厂模式
真正的工厂模式和简单工厂模式区别在于,它不是另外使用一个类或对象来创建自行车,而是使用一个子类。现在我们打算让各自自行车店自行决定从哪个生产厂家进货。因此,单单一个BicycleFactory对象无法提供需要的所有自行车实例,我们把BicycleShop设计为抽象类,让之类根据各自的进货渠道实现其createBicycle方法:
/* BicycleShop class (abstract)*/
var BicycleShop = function(){};
BicycleShop.prototype = {
sellBicycle: function(model){
var bicycle = this.createBicycle(model);
bicycle.assemble();
bicycle.wash();
return bicycle;
},
createBicycle: function(model){
throw new Error(''Unsupported operation on an abstract class. '');
}
};
设计一个自行车生产厂家的子类需要扩展BicycleShop,重定义其中的createBicycle方法。其中一个是从Acme公司进货,另一个是从General Products公司进货。
/*AcmeBicycleShop class*/
var AcmeBicycleShop = function() {};
extend(AcmeBicycleShop, BicycleShop);
AcmeBicycleShop.prototype.createBicycle = function(model) {
var bicycle;
switch (model) {
case ''The Speedster'':
bicycle = new AcmeSpeedster();
break;
...
}
Interface.ensureImplements(bicycle, Bicycle);
return bicycle;
};
/*GeneralProductsBicycleShop class*/
var GeneralProductsBicycleShop = function() {};
extend(GeneralProductsBicycleShop, BicycleShop);
GeneralProductsBicycleShop.prototype.createBicycle = function(model) {
var bicycle;
switch (model) {
case ''The Speedster'':
bicycle = new GeneralProductsSpeedster();
break;
...
}
Interface.ensureImplements(bicycle, Bicycle);
return bicycle;
};
/*商店可以是Acme或General Products的自行车专卖店*/
var acmeCruisers = new AcmeSpeedster();
var myNewBike = acmeCruisers.sellBicycle(''The Speedster'');
var generalCruisers = new GeneralProductsSpeedster();
var myNewBike = generalCruisers.sellBicycle(''The Speedster'');
工厂模式的适用场合
1.动态实现
在考虑到返回的连接对象的类型取决于所探查到的带宽和网路延时等因素,通常要与一系列实现了同一个接口、可以被同等对待的类打交道。
2.节省设置开销
如果对象需要进行复杂并且彼此相关的设置,那么使用工厂模式可以减少每种对象所需的代码量。如果这种设置只需要为特定类型的所有实例执行一次即可,这种作用尤其突出。工厂模式可以在实例化所有需要的对象之前先一次性地进行设置。无论有多少不同的代码会被实例化,这种方法都可以设置代码集中在一个地方。如果使用的类要求加载外部库的话,尤其有用。
3.用许多小型对象组成一个大对象
工厂方法可以创建封装了许多较小单独的对象。大对象的构造函数不依赖于某种特定的小对象,保证对象自己的松耦合。
工厂模式的优劣
优势:
工厂模式的好处在于消除对象间的耦合。通过使用工厂模式而不是new关键字及具体类,你可以把所有的实例化代码集中在一个位置。简化更换所用类或在运行期间动态选择所用类的工作,在派生子类方面它提供了更大的灵活性。使用工厂模式,你可以先创建一个抽象的父类,然后再子类中创建工厂的方法,从而把成员对象的实例化推迟到更专业化的子类中进行。
面向对象设计的两条原则:弱化对象间的耦合;防止代码重复。在一个方法中进行类的实例化,可以消除重复性的代码,这是在用一个对接口的调用取代一个具体的实现,有助于创建模块化的代码。
劣势:
如果根本不可能另外换用一个类,或者不需要再运行期间在一系列可互换的类中进行选择,那就不应该使用工厂方法。大多数类最好使用new关键字和构造函数公开地进行实例化。
参考资料:
【美】Ross Harmes 、Dustin Diaz 著《JavaScript 设计模式》
转载时请注明:来自w-rain的个人博客
今天关于javascript – 滥用CSS类属性或有效的设计模式?和javascript 操作css的介绍到此结束,谢谢您的阅读,有关CSS / Javascript使用CSS类显示/隐藏DIV?、javascript – 是否有管理并行AJAX查询的设计模式?、javascript 中的设计模式之代理模式、JavaScript 常用的设计模式之工厂模式等更多相关知识的信息可以在本站进行查询。
本文标签: