>

又不清楚怎么命名class了,express搭建服务端框架

- 编辑:云顶娱乐yd2221 -

又不清楚怎么命名class了,express搭建服务端框架

class命名到底有多难

首先,class跟id不一致等,class本来便是规划用来能够重复使用的,而id才是设计唯意气风发的(借使信守BEM,class差不离也都以唯意气风发的了)。

第二,样式是能够覆盖的,何况先依照权重,再依据定义的前后相继顺序。恐怕你花了十分钟两全概念的八个class样式,人家分分钟就给您干掉了,那得多恼火;大概那几个页面好好的,跑到另三个页面就跟原先的样式有了冲突。

所以class命名的难就难在既要重复使用,又要幸免样式的冲突。假诺要重复使用,那么自然是越简单越好,越抽象可用的地点越大,太现实了就夭亡了。而只要要幸免样式矛盾。BEM的诀要最简便,class都独一了,那还冲突个毛线;其次正是经过父成分限制效用域,能够搞多少个层级,并不是独自一个class定义样式;还应该有正是追加class,来贯彻差距化;最终分歧的页面分化的文书,你用你的自个儿用自个儿的。

CSS

// BEM .imgslide__item__img{} // 父元素约束 .imgslide .item .img{} // 追加class .img{} .img--special{} // 分化页面差异文件 // a.html & a.css .img{} // b.html & b.css .img{}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// BEM
.imgslide__item__img{}
 
// 父元素限定
.imgslide .item .img{}
 
// 追加class
.img{}
.img--special{}
 
// 不同页面不同文件
// a.html & a.css
.img{}
// b.html & b.css
.img{}

由此可以知道,不管有多难,我们照旧得尝试去消除难题,去搜索一些规律。

至于小编:winty

云顶娱乐yd2221 1

后面一个工程师,前端爱好者。博客: 个人主页 · 笔者的稿子 · 1 ·  

云顶娱乐yd2221 2

用“MEAN”工夫栈开辟web应用(二)express搭建服务端框架

2015/11/14 · 基础技巧 · MEAN

初藳出处: 吕大豹   

云顶娱乐yd2221,上一篇笔者们讲了怎么样运用angular搭建起项指标前端框架,前端抽象出几个service层来向后端发送诉求,后端则赶回相应的json数据。本篇大家来介绍一下,怎么着在nodejs情状下行使express来搭建起服务端,使之不易的响应前端的乞请。本文所讲的示范依然遵照大家的上学项目QuestionMaker()

简轻便单的 canvas 翻角效果

2017/12/07 · HTML5 · Canvas

原稿出处: 敖爽   

鉴于事业供给 , 需求写八个翻角效果;云顶娱乐yd2221 3

demo链接

右上角须要从无的气象撕开一个标记 , 且有动画进度 , 上海教室是兑现的功能图 , 不是gif

对这几个翻角效果的难处在于未有翻动的时候露出的是dom上面的剧情 , 达成角度来讲 纯dom + css动画的技术方案并从未相出三个好的心路 ; 于是捡起了长久以前学的入门级其他canvas;

上面说一下达成思路:

  1. 卡通拆分 :
    将此动画分解成两部分 , 生机勃勃部分是翻页现身的北京蓝三角区域 , 另二个是发泄的橘色体现内容
    对于橘色的来得内容区域相对好一些 , 因为是一个平整图形 , 而深红区域绝对较难;

先从基础canvas使用形式谈到 :

<div class="container"> <canvas class="myCanvas" width="100" height="100"></canvas> </div>

1
2
3
<div class="container">
    <canvas class="myCanvas" width="100" height="100"></canvas>
</div>

布局如上 , 这里要说一点踩过的坑是 , canvas必定要安装上width 与 height , 此处并不是为css中的width与height;而是写在dom上的属性 ; 因为dom上的width与height标记了canvas的分辨率(个人领会); 所以此canvas画布分辨率为100*100 , 而展示尺寸是能够透过css控制;

js中第后生可畏要做的是收获canvas对象 ,

var canvas = document.querySelector('.myCanvas'); //获取canvas对应dom var ctx = canvas.getContext('2d'); //此方法相比基础 , 意为获得canvas水墨画2d内容的工具(上下文) var cw = 100; //分辨率 , 其实直接从dom上得到可能越来越好些 var ch = 100; //分辨率 , 其实直接从dom上赢得大概更好些

1
2
3
4
var canvas = document.querySelector('.myCanvas'); //获取canvas对应dom
var ctx = canvas.getContext('2d'); //此方法较为基础 , 意为获取canvas绘画2d内容的工具(上下文)
var cw = 100; //分辨率 , 其实直接从dom上获取可能更好些
var ch = 100; //分辨率 , 其实直接从dom上获取可能更好些

ctx那几个美术上下文在这里个科目中起到的作用重大 ; 它提供了万分苍劲的api , 譬喻用于画线 , 填充 , 写文字等 , 那样看来理解为画笔会越发分明一些;

此地效果要求使用的api如下 ( 不做详细解释 , 可w3c自行查询 );

ctx.save() //保存上下文状态 (比方画笔尺寸 颜色 旋转角度) ctx.restore() //再次来到上次保存的上下文状态 ctx.moveTo(x,y) //上下文移动到具体地方ctx.lineTo(x,y) //上下文以划线的款式活动到某地方 ctx.stroke() // 画线动作 ctx.quadraticCurveTo() //上下文(画笔)按贝塞尔曲线移动(简单理解为可控的曲线就能够) ctx.arc() //画圆 ctx.beginPath() //开启新的画笔路线 ctx.close帕特h() //关闭当前画笔路线 ctx.createLinearGradient() //创设canvas渐变对象 ctx.fill() //对闭合区域开展填充 ctx.globalCompositeOperation //画笔的重合格局

1
2
3
4
5
6
7
8
9
10
11
12
ctx.save() //保存上下文状态 (比如画笔尺寸 颜色 旋转角度)
ctx.restore() //返回上次保存的上下文状态
ctx.moveTo(x,y) //上下文移动到具体位置
ctx.lineTo(x,y) //上下文以划线的形式移动到某位置
ctx.stroke() // 画线动作
ctx.quadraticCurveTo() //上下文(画笔)按贝塞尔曲线移动(简单理解为可控的曲线即可)
ctx.arc() //画圆
ctx.beginPath() //开启新的画笔路径
ctx.closePath() //关闭当前画笔路径
ctx.createLinearGradient() //创建canvas渐变对象
ctx.fill() //对闭合区域进行填充
ctx.globalCompositeOperation //画笔的重叠模式

唯恐方法列举的远远不足详尽 , 见谅.

先是是绘制水绿翻出的局地 , 图形分解为如下几片段(请遵照上海教室脑补)

  1. 左上角向右下的半弧 ╮
  2. 接下来是竖直向下的竖线 |
  3. 接下来是向右的半圆 ╰
  4. 再接下来是向右的横线
  5. 紧接着依然向右下的半弧 ╮
  6. 说起底是将线连接会源点

于是第一步 我们要先将画笔移动到 伊始地点

ctx.moveTo(50,0);

1
ctx.moveTo(50,0);

然后

ctx.quadraticCurveTo(55 , 5 , 55 , 25); // 能够知晓为从(50,0)那个点划线到(55,25)这一个点 , 中间会境遇(55,5)这么些点将直线想磁铁相近"吸"成曲线;

1
ctx.quadraticCurveTo(55 , 5 , 55 , 25); // 可以理解为从(50,0)这个点划线到(55,25)这个点 , 中间会受到(55,5)这个点将直线想磁铁一样"吸"成曲线;

于是乎第三个向右下的半弧完结 , 那时canvas上从不任何绘制内容 , 因为还从未实施过绘制方法举个例子stroke或fill,

接下去直线向下正是简约的移位

ctx.lineTo(55 , 40);

1
ctx.lineTo(55 , 40);

以那个时候候我们接下去应该画向右的半圆 , 当时再用贝塞尔曲线绘制 实在有一点点不太合适 , 因为从图上来看 , 这里完全部是55%的圆 , 所以要采取canvas提供的画圆的api

ctx.arc(60 , 40 , 5 , Math.PI , Math.PI / 2 , true);

1
ctx.arc(60 , 40 , 5 , Math.PI , Math.PI / 2 , true);

上述画圆的代码意为 : 以(60,40)点为圆心 , 5为半径 , 逆时针从 180度绘制到90度 , 180度就是圆心的品位向左 达到点(55,40) , 与上一步连接上 , 然后又因为显示屏向下为正 , 90度在圆心正下方 , 所以绘制出此半圆

于是乎依照同等的步调 水平向右

ctx.lineTo(75 , 45);

1
ctx.lineTo(75 , 45);

然后重新行使贝塞尔曲线用第一步的思路画出向右下的弧;

ctx.quadraticCurveTo( 95 , 45 , 100 , 50 );

1
ctx.quadraticCurveTo( 95 , 45 , 100 , 50 );

同理 上述贝塞尔曲线能够明白为一条从( 75 , 45 ) 到 ( 100 , 50 )的线被 ( 95 , 45 )”吸”成曲线

谈起底链接源点 , 闭合绘画区域

ctx.lineTo(50 , 0);

1
ctx.lineTo(50 , 0);

其临时候米色区域的翻页就画完了 , 然后那个时候开班填写颜色 ;

var gradient = ctx.createLinearGradient(50 , 50 , 75 , 75); gradient.addColorStop(0 , '#ccc'); gradient.addColorStop(0.7 , '#111'); gradient.addColorStop(1 , '#000');

1
2
3
4
var gradient = ctx.createLinearGradient(50 , 50 , 75 , 75);
gradient.addColorStop(0 , '#ccc');
gradient.addColorStop(0.7 , '#111');
gradient.addColorStop(1 , '#000');

笔者们透过上述代码创立二个 从( 50 , 50 )点到(75 , 75)点的线性渐变 , 颜色从 #ccc 到 #111 到 #000 ; 创制强光效果;
然后填充:

ctx.fillStyle = gradient; ctx.fill();

1
2
ctx.fillStyle = gradient;
ctx.fill();

于是翻页效果的50%纵然成功了。

至此 , 作者要说一点本身精晓的canvas的作画”套路”;

对此上述教程中 , 有一步大家运用了一个词叫做 闭合 , 闭合的概念在canvas中是真是存在的 , 对于fill方法来说填充的间隔是有贰个空间尺寸才得以的 , 比方大家描绘的那几个深丁香紫的三角形形 , 参加大家最后未有将终点与起源相接接 , 相近canvas会活动帮大家链接最后一笔绘画之处到源点 , 强制行程闭合空间 , 而那样大家想再多画多少个新的关闭空间就麻烦了 , 所以canvas提供了之类api 新建闭合路线:

ctx.beginPath(); //新建路线 ctx.closePath(); //闭合路线

1
2
ctx.beginPath(); //新建路径
ctx.closePath(); //闭合路径

因此对于大家接下去要绘制右上角橘色区域来讲 , 大家在绘制浅蓝区域早先率先要做的是

ctx.beginPath(); ...

1
2
ctx.beginPath();
...

下一场在fill以前 大家应该

ctx.closePath();

1
ctx.closePath();

约等于说beginPath 到 closePath之间标志着大家团结的八个生龙活虎体化的描绘阶段.

那么接下去绘制右上角的橘色区域就归纳超多了:

ctx.beginPath(); ctx.moveTo(50,0); ctx.lineTo(100,50); ctx.lineTo(100,0); ctx.lineTo(50,0); ctx.closePath(); ctx.fillStyle = '#ff6600'; ctx.fill();

1
2
3
4
5
6
7
8
ctx.beginPath();
ctx.moveTo(50,0);
ctx.lineTo(100,50);
ctx.lineTo(100,0);
ctx.lineTo(50,0);
ctx.closePath();
ctx.fillStyle = '#ff6600';
ctx.fill();

于是乎右上角的橘色区域大家就绘制达成了;

文字绘制

接下去绘制”new” , 实际上是应用canvas简单的文书绘制 , 代码如下:

var deg = Math.PI / 180; ctx.globalCompositeOperation = 'source-atop'; //canvas层叠形式 ctx.beginPath(); ctx.font = '14px Arial'; //设置字体大小 字体 ctx.textAlign = 'center'; // 字体对齐格局ctx.translate(78 , 22); // 移动canvas画布圆点 ctx.rotate(45 * deg); // 旋转画布 ctx.fillStyle = '#fff'; // 设置文字颜色 ctx.fillText('NEW' , 0 , 0); //文字绘制动作 ctx.closePath();

1
2
3
4
5
6
7
8
9
10
var deg = Math.PI / 180;
ctx.globalCompositeOperation = 'source-atop'; //canvas层叠模式
ctx.beginPath();
ctx.font = '14px Arial'; //设置字体大小 字体
ctx.textAlign = 'center'; // 字体对齐方式
ctx.translate(78 , 22);  // 移动canvas画布圆点
ctx.rotate(45 * deg);    // 旋转画布
ctx.fillStyle = '#fff';  // 设置文字颜色
ctx.fillText('NEW' , 0 , 0); //文字绘制动作
ctx.closePath();

对于上述代码中 , 文字的连锁api是属于还没难度的 , 只是安装而已 , 须要知道的有个别在于 translate和rotate,

那七个章程中 translate的意趣为移动canvas画布的( 0 , 0 )点到 (78,22),然后旋转45度, 再将文字渲染在原点 , 实际正是 ( 78 , 22 ) 那个点上, 那时我们对canvas的画笔做出了很大的改变

举例大家校勘了旋转角度以至画布圆点 , 这种操作可能只在我们须求绘制偏斜的new 的时候要求 , 早先时期可能就无需动用了 ,

万幸canvas的画笔是存在”状态”的, 通过ctx.save();能够保存当前画笔的景色 , 通过ctx.restore();能够过来到上次画笔保存的状态.

于是乎小编个人精通到 , 在支付canvas动画时 , 贰个较好的习惯正是 , 在begin帕特h此前先ctx.save();保存画笔状态 , 在closePath后ctx.restore();恢复生机早前的画笔状态 , 那样我们的每四个制图阶段对于画笔的纠正都将是不会有震慑的.( 个人经验 )

ctx.globalCompositeOperation = 'source-atop'; //canvas层叠情势

1
ctx.globalCompositeOperation = 'source-atop'; //canvas层叠模式

代码中那部分是指 大家绘制的文字new 与 橘色三角形区域的重叠关系 , 此方法取值比较多 , 此处不做过多介绍 , source-atop值能够使重叠区域保留 , 新绘制的开始和结果在重叠区域以外的片段消失 , 以此到达new在里头的功用

到那边我们就支出好了翻角效果的一丝一毫显示的意况 , 那么哪些让这些区域动起来吧?

此地必要动用h5提供的用于刷帧的函数 requestAnimationFrame ;

此措施可粗略明了为 16皮秒的沙漏 , 可是厉害的是能够再相继情形中自动相配到可完毕的相持顺遂的帧率 , 实际并非电磁打点计时器哈~

我们需求在此个轮回实施的函数中 , 将上述的绘图内容重复绘制 , 比如 :

function draw(){ drawMethod(); //绘制三角等情节window.requestAnimationFrame(function(){ draw(); }) } function drawMethod(){ //... }

1
2
3
4
5
6
7
8
9
function draw(){
    drawMethod(); //绘制三角等内容
    window.requestAnimationFrame(function(){
        draw();
    })
}
function drawMethod(){
    //...
}

这么我们就能够直达刷帧的职能了 , 于是任何时候我们要做的正是调控绘制时各样数值的参数.

举个例子我们是以 (50,0)为起源 , ( 100 , 50 )为终点那样的三个活动点为绘制标识的 , 假设我们将四个点开展仓库储存 , 並且每回施行drawMethod的时候更新点的职责 , 然后清空canvas ,再绘制新的点 那么就能够达成canvas动起来的目标了;

实效链接在此

在上头的demo链接中 , 本人定义了八个进程与加快度的关系 , 譬如每一遍绘制二回canvas后 , 将累积的点坐标进行追加四个speed值 , 然后speed值也加码 , 那样speed对应的定义便是速度 , 而speed的增添值对应的正是加快度. 所以就表现了后生可畏种加快移动的景观;

如上内容绝对个人驾驭内容 , 若果有哪儿知道错了 招待各位大大引导 , 另demo链接失效可私信.

1 赞 1 收藏 评论

云顶娱乐yd2221 4

有关参照他事他说加以考察资料

黄金时代种Sprite图自动化方案的假造

MDN:background-size

1 赞 2 收藏 评论

云顶娱乐yd2221 5

创立轻巧准绳:

  •  以中写道连接,如.item-img
  •  使用两个中划线表示特殊化,如.item-img.item-img--small表示在.item-img的底蕴上特殊化
  •  状态类直接动用单词,参照他事他说加以考查上边包车型地铁主要词,如.active, .checked
  •  图标以icon-为前缀(字体Logo接纳.icon-font.i-name艺术命名)。
  •  模块接受关键词命名,如.slide, .modal, .tips, .tabs,特殊化采纳地点两在那之中划线表示,如.imgslide--full, .modal--pay, .tips--up, .tabs--simple
  •  js操作的类统OPPO上js-前缀
  •  不要超越多少个class组合使用,如.a.b.c.d

最重要词及法规都有了,今后得以进去本文的为主的为主,实战操作。

打赏扶持本人写出更加多好文章,多谢!

任选意气风发种支付方式

云顶娱乐yd2221 6 云顶娱乐yd2221 7

1 赞 5 收藏 评论

运营起基于express的web服务器

express是多个web应用开发框架,它依照nodejs,扩张了大多web开采所需的功力,使得大家能够很便利的拜候和操作request和response。请留意它和nginx或然tomcat并不是三个定义,它是四个费用框架,并不是服务器。

运营起基于express的web服务器是特别轻松的,因为express都绑你封装好了。首先供给用npm安装好express,然后在项目根目录下新建四个server.js文件,内容如下:

JavaScript

var express = require('express'); var app = express(); app.listen(3000); var _rootDir = __dirname; var protectDir = _rootDir + '/protect/'; app.use(express.static(_rootDir)); //注册路由 app.get('/', function(req, res){ res.sendFile(_rootDir+'/src/index.html'); }); app.use(function(req, res, next) { res.status(404).sendFile(_rootDir+'/src/404.html'); }); app.use(function(err, req, res, next) { console.error(err.stack); res.status(500).send('500 Error'); });

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
var express = require('express');
var app = express();
app.listen(3000);
 
var _rootDir = __dirname;
var protectDir = _rootDir + '/protect/';
 
app.use(express.static(_rootDir));
 
//注册路由
app.get('/', function(req, res){
    res.sendFile(_rootDir+'/src/index.html');
});
 
app.use(function(req, res, next) {
     res.status(404).sendFile(_rootDir+'/src/404.html');
});
app.use(function(err, req, res, next) {
     console.error(err.stack);
     res.status(500).send('500 Error');
});

上述代码完毕了这个职能,首先成立了http服务器,监听在3000端口。

然后app.use(express.static(_rootDir));那大器晚成行是利用了静态文件服务的中间件,那样我们项目下的js、css以致图片等静态文件就都能够访谈到了。

接下去是挂号路由,此处只相当三个路由准绳,那正是”/”(网址的根目录),当相称到此路由后把首页文件index.html直接用res.sendFile方法给发送到浏览器端。那样浏览器用

可是在本项目中,我们用的是angular的前端模板,所今后端就没有必要模板了,未有实行计划。大家的路由机制也是一心接纳的ng的前端路由,所以在express中只计划一条就够了。

在最终还可能有两块代码,分别是404和500乖谬的破获。你大概会纳闷为啥是那般写吗?从上到下排下来就能够分别捕获404和500了呢?其实那就是express的中间件机制,在那机制下,对客商端诉求的拍卖疑似二个流程,把装有中间件串联起来,只要某当中间件把乞请再次回到了,就得了实践,不然就从上到下平昔管理此号召。

上边代码的流水生产线就是,先按路由法则来协作路线,倘使路由格外不到,则感到是发出404。500的谬误请留意八个细节,在回调函数的参数中,第1个会传播err,正是大谬不然对象,以此来标识是贰个500漏洞超级多。

抛荒一下,再考虑方案

不正是缩放么?background-size会扯出这么多难点,不是还会有个transform么?会并发同样的标题么? 那么要获取不错的效果的话,以推广两倍为例,必要实现: 恩?好像就加黄金时代行代码?

CSS

.message:after { ... transform: scale(2); }

1
2
3
4
.message:after {
    ...
    transform: scale(2);
}

好啊,便是那样。两个分别也很简短,因为八个功用在要素上,一个职能在7-Up图上,所今后人会带出n多副作用。

那么生龙活虎旦急需缩放到牢固尺寸时,还索要领悟原始尺寸,通过总计获得七个缩放周详,那样技能最后达到所需的效果。

class命名的上扬进程

有关class的命名,其实跟人名也大约,固然要想外人看得懂,那根本还是在于可识别性。到当前截止class的命名大致经历了下面几个根本阶段:

  •  混沌阶段,未有法则正是最棒的规规矩矩
  •  原子类阶段,聚焦神龙现身手
  •  模块阶段,以功能分开,增添前缀
  •  BEM阶段,准绳不改变

议论 JavaScript 的观看者格局(自定义事件)

2016/08/25 · JavaScript · 观看者格局, 设计形式

本文小编: 伯乐在线 - winty 。未经作者许可,幸免转发!
接待参与伯乐在线 专辑小编。

萧萧,后天列席了二个笔试,里面有大器晚成到JS编制程序题,那个时候看着主题材料就蒙圈。后来商量了一下,原本正是所谓的观看者格局。就记下来 ^_^

题目

JavaScript

[附加题] 请达成上边包车型客车自定义事件 伊夫nt 对象的接口,效率见注释(测验1) 该 伊夫nt 对象的接口供给能被此外对象开展复用(测验2) // 测验1 Event.on('test', function (result) { console.log(result); }); Event.on('test', function () { console.log('test'); }); Event.emit('test', 'hello world'); // 输出 'hello world' 和 'test' // 测量检验2 var person1 = {}; var person2 = {}; Object.assign(person1, Event); Object.assign(person2, 伊芙nt); person1.on('call1', function () { console.log('person1'); }); person2.on('call2', function () { console.log('person2'); }); person1.emit('call1'); // 输出 'person1' person1.emit('call2'); // 未有出口 person2.emit('call1'); // 没有出口 person2.emit('call2'); // 输出 'person2'<br>var Event = { // 通过on接口监听事件eventName // 若是事件eventName被触发,则进行callback回调函数 on: function (eventName, callback) { //你的代码 }, // 触发事件 eventName emit: function (eventName) { //你的代码 } };

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
[附加题] 请实现下面的自定义事件 Event 对象的接口,功能见注释(测试1)
该 Event 对象的接口需要能被其他对象拓展复用(测试2)
// 测试1
Event.on('test', function (result) {
    console.log(result);
});
Event.on('test', function () {
    console.log('test');
});
Event.emit('test', 'hello world'); // 输出 'hello world' 和 'test'
// 测试2
var person1 = {};
var person2 = {};
Object.assign(person1, Event);
Object.assign(person2, Event);
person1.on('call1', function () {
    console.log('person1');
});
person2.on('call2', function () {
    console.log('person2');
});
person1.emit('call1'); // 输出 'person1'
person1.emit('call2'); // 没有输出
person2.emit('call1'); // 没有输出
person2.emit('call2'); // 输出 'person2'<br>var Event = {
    // 通过on接口监听事件eventName
    // 如果事件eventName被触发,则执行callback回调函数
    on: function (eventName, callback) {
        //你的代码
    },
    // 触发事件 eventName
    emit: function (eventName) {
        //你的代码
    }
};

差非常少没把笔者看晕…

好啊,一步一步来拜望怎么回事。

①询问一下观看者方式

观看者格局

这是黄金时代种成立松散耦合代码的技术。它定义对象间 生机勃勃种生龙活虎对多的依靠关系,当一个指标的景况发生退换时,全体信任于它的靶子都将赢得料理。由入眼和观察者组成,主体担当公布事件,同一时候观望者通过订阅那一个事件来考查该核心。主体并不知寺庙望者的任何专门的学问,观望者知道主体并能注册事件的回调函数。

例子:

假定我们正在开采三个百货公司网址,网址里有header尾部、nav导航、音讯列表、购物车等模块。那多少个模块的渲染有多个合伙的前提条件,正是必得先用ajax异步央求获取客户的记名新闻。那是很正规的,例如客户的名字和头像要体现在header模块里,而那五个字段都来源于客户登入后赶回的新闻。这时,大家就足以把那几个模块的渲染事件都置于一个数组里面,然后待登陆成功之后再遍历这几个数组况兼调用每多少个主意。

基本格局:

JavaScript

function EventTarget(){ this.handlers = {}; } EventTarget.prototype = { constructor: EventTarget, addHandler: function(type, handler){ if (typeof this.handlers[type] == "undefined"){ this.handlers[type] = []; } this.handlers[type].push(handler); }, fire: function(event){ if (!event.target){ event.target = this; } if (this.handlers[event.type] instanceof Array){ var handlers = this.handlers[event.type]; for (var i=0, len=handlers.length; i < len; i++){ handlers[i](event); } } }, removeHandler: function(type, handler){ if (this.handlers[type]又不清楚怎么命名class了,express搭建服务端框架。 instanceof Array){ var handlers = this.handlers[type]; for (var i=0, len=handlers.length; i < len; i++){ if (handlers[i] === handler){ break; } } handlers.splice(i, 1); } } };

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
function EventTarget(){    
    this.handlers = {};
}
EventTarget.prototype = {    
    constructor: EventTarget,
    addHandler: function(type, handler){
         if (typeof this.handlers[type] == "undefined"){
              this.handlers[type] = [];
         }
         this.handlers[type].push(handler);
     },
    fire: function(event){
         if (!event.target){
             event.target = this;
         }
         if (this.handlers[event.type] instanceof Array){
             var handlers = this.handlers[event.type];
             for (var i=0, len=handlers.length; i < len; i++){
                 handlers[i](event);
            }
         }
     },
     removeHandler: function(type, handler){
        if (this.handlers[type] instanceof Array){
            var handlers = this.handlers[type];
            for (var i=0, len=handlers.length; i < len; i++){
                if (handlers[i] === handler){
                    break;
                 }
             }
             handlers.splice(i, 1);
          }
      }
};

大约意思正是,创制三个平地风波管理器。handles是三个积攒事件管理函数的指标。

addHandle:是加上事变的法子,该措施接纳多个参数,八个是要抬高的平地风波的体系,贰个是这些事件的回调函数名。调用的时候会率先遍历handles那么些目的,看看这么些项目标诀要是还是不是业已存在,如若已经存在则加多到该数组,假若空中楼阁则先创设四个数组然后增长。

fire方法:是实践handles那些目的里面包车型地铁某些项目标每贰个艺术。

removeHandle:是相应的去除函数的章程。

好啊,回到标题,剖判一下。

②标题中的测验风流倜傥:

JavaScript

// 测试1 Event.on('test', function (result) { console.log(result); }); Event.on('test', function () { console.log('test'); }); Event.emit('test', 'hello world'); // 输出 'hello world' 和 'test'

1
2
3
4
5
6
7
8
// 测试1
Event.on('test', function (result) {
    console.log(result);
});
Event.on('test', function () {
    console.log('test');
});
Event.emit('test', 'hello world'); // 输出 'hello world' 和 'test'

意思正是,定义三个叫’test’类型的事件集,并且注册了八个test事件。然后调用test事件集里面包车型地铁百分百主意。在这on方法等价于addHandle方法,emit方法等价于fire方法。此中第二个参数正是事件类型,第三个参数便是要传进函数的参数。

是或不是那一个回事呢?很好,那么大家要写的代码正是:

JavaScript

var 伊芙nt = { // 通过on接口监听事件eventName // 假若事件eventName被触发,则实施callback回调函数 on: function (eventName, callback) { //笔者的代码 if(!this.handles){ this.handles={}; } if(!this.handles[eventName]){ this.handles[eventName]=[]; } this.handles[eventName].push(callback); }, // 触发事件 eventName emit: function (eventName) { //你的代码 if(this.handles[arguments[0]]){ for(var i=0;i<this.handles[arguments[0]].length;i++){ this.handles[arguments[0]][i](arguments[1]); } } } };

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
var Event = {
    // 通过on接口监听事件eventName
    // 如果事件eventName被触发,则执行callback回调函数
    on: function (eventName, callback) {
        //我的代码
        if(!this.handles){
             this.handles={};    
        }      
       if(!this.handles[eventName]){
            this.handles[eventName]=[];
       }
       this.handles[eventName].push(callback);
    },
    // 触发事件 eventName
    emit: function (eventName) {
        //你的代码
       if(this.handles[arguments[0]]){
           for(var i=0;i<this.handles[arguments[0]].length;i++){
               this.handles[arguments[0]][i](arguments[1]);
           }
       }
    }
};

那样测量试验,完美地经过了测量试验一。

③测试二:

JavaScript

var person1 = {}; var person2 = {}; Object.assign(person1, 伊芙nt); Object.assign(person2, Event); person1.on('call1', function () { console.log('person1'); }); person2.on('call2', function () { console.log('person2'); }); person1.emit('call1'); // 输出 'person1' person1.emit('call2'); // 未有出口 person2.emit('call1'); // 未有出口 person2.emit('call2'); // 输出 'person2'

1
2
3
4
5
6
7
8
9
10
11
12
13
14
var person1 = {};
var person2 = {};
Object.assign(person1, Event);
Object.assign(person2, Event);
person1.on('call1', function () {
    console.log('person1');
});
person2.on('call2', function () {
    console.log('person2');
});
person1.emit('call1'); // 输出 'person1'
person1.emit('call2'); // 没有输出
person2.emit('call1'); // 没有输出
person2.emit('call2'); // 输出 'person2'

大致敬思就是为八个不等person注册自定义事件,而且多少个person之间是相互独立的。

直白测量检验,发掘输出了

云顶娱乐yd2221 8

以此相疑似主题素材供给某些出入呢,或许那才是难题的坑吧!

解释一下,Object.assign(person1, Event);

其一是ES6的新对象方法,用于对象的联合,将源对象(source)的兼具可枚举属性,复制到目的对象(target)。

情趣是将伊夫nt里面包车型地铁可枚举的对象和艺术放到person1里面。

云顶娱乐yd2221 9

约等于说,倘若源对象有些属性的值是指标,那么指标对象拷贝得到的是以此指标的援用。由于开展测量检验风流倜傥的时候调用了on方法,所以event里面早本来就有了handles这么些可枚举的习性。然后再分别合併到三个person里面的话,五个person对象里面包车型地铁handles都只是一个援用。所以就相互影响了。

设若assign方法要促成深克隆则要这样:

云顶娱乐yd2221 10

主题素材是,标题已经稳固了办法,大家不能够修正这些艺术。

据此,大家一定要将handles那个本性定义为不计其数的,然后在person调用on方法的时候再各自发生handles这么些指标。

也便是说准确的做法应该是:

JavaScript

var Event = { // 通过on接口监听事件eventName // 若是事件eventName被触发,则进行callback回调函数 on: function (eventName, callback) { //你的代码 if(!this.handles){ //this.handles={}; Object.defineProperty(this, "handles", { value: {}, enumerable: false, configurable: true, writable: true }) } if(!this.handles[eventName]){ this.handles[eventName]=[]; } this.handles[eventName].push(callback); }, // 触发事件 eventName emit: function (eventName) { //你的代码 if(this.handles[arguments[0]]){ for(var i=0;i<this.handles[arguments[0]].length;i++){ this.handles[arguments[0]][i](arguments[1]); } } } };

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
var Event = {
    // 通过on接口监听事件eventName
    // 如果事件eventName被触发,则执行callback回调函数
    on: function (eventName, callback) {
        //你的代码
        if(!this.handles){
            //this.handles={};
            Object.defineProperty(this, "handles", {
                value: {},
                enumerable: false,
                configurable: true,
                writable: true
            })
        }
      
       if(!this.handles[eventName]){
            this.handles[eventName]=[];
       }
       this.handles[eventName].push(callback);
    },
    // 触发事件 eventName
    emit: function (eventName) {
        //你的代码
       if(this.handles[arguments[0]]){
           for(var i=0;i<this.handles[arguments[0]].length;i++){
               this.handles[arguments[0]][i](arguments[1]);
           }
       }
    }
};

经过那道题,认为考得真的很玄妙况兼很考基础。好啊。作者要么好好复习去了。

打赏匡助本人写出越多好随笔,谢谢!

打赏作者

用“MVC”组织代码

用MVC的布局协会代码当然是黄金法规了。express能够用模板引擎来渲染view层,路由体制来公司controller层,不过express并未显明规定MVC结构应该怎么着写,而是把自由接收交给你,本身来协会MVC结构。当然你也足以团体别的格局,比方像Java中的“n层架构”。

在本项目中,咱们就以文件夹的款式来轻易组织一下。因为大家运用了后面一个模板,所未来端的view层就不设有了,独有controller和model。看一下品类的目录:

云顶娱乐yd2221 11

在protect下有多少个公文夹controllers和models分别放C和M。大家路由中使用的questionController对象就定义在questionController.js中,来看一下用以保存试题的save方法是什么样定义的:

JavaScript

var Question = require('../models/question'); module.exports = { //增添试题 save: function(req, res){ var data = req.body.question; Question.save(data, function(err, data){ if(err){ res.send({success: false, error: err}); } else{ res.send({success: true, data: data}); } }); } }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
var Question = require('../models/question');
module.exports = {
     //添加试题
     save: function(req, res){
          var data = req.body.question;
          Question.save(data, function(err, data){
               if(err){
          res.send({success: false, error: err});
     }
     else{
          res.send({success: true, data: data});
     }
          });
     }
}

questionController作为三个模块,使用正式的commonjs语法,大家定义了save方法,通过req.body.question,能够获得前台传过来的多少。在这里个模块中,大家require了坐落model层的Question模型,没有错,它正是用来操作数据库的,调用Question.save方法,这份数据就存入了数据库,然后在回调函数中,大家用res.send将json数据重返给前端。

概念好questionController后,我们就足以在server.js中把它给require进去了,然后就有了前头大家在路由中应用的

JavaScript

apiRouter.post('/submitQuestion', questionController.save);

1
apiRouter.post('/submitQuestion', questionController.save);

成套工艺流程就勾搭起来了。

models文件夹中放的就是模型了,用来管理与数据库的投射和相互,这里运用了mongoose作为数据库的操作工具,model层怎么样来编排,本篇就不做牵线了,在下大器晚成篇中大家再详尽批注。

末段再声美素佳儿下,本篇小说的代码是依附一个演习项目QuestionMaker,为了越来越好通晓文章中的陈述,请查看项目标源码:

1 赞 2 收藏 评论

云顶娱乐yd2221 12

最简便,最实用的利用办法

得益于伪成分的功劳,在不破坏页面结构,不增增加余标签的景观下,通过::after创设多个您所急需Logo大小的伪成分,并将所必要的Logo通过background-position定位到钦赐的半空中,对应的Logo变顺遂地显示出来。

CSS

.message:after { background: url(../img/sprite.png) scroll 0px -86px no-repeat transparent; content: ''; text-indent: -9999px; overflow: hidden; position: absolute; top: 0; left: 50%; margin-left: -10px; width: 20px; height: 22px; }

1
2
3
4
5
6
7
8
9
10
11
12
.message:after {
    background: url(../img/sprite.png) scroll 0px -86px no-repeat transparent;
    content: '';
    text-indent: -9999px;
    overflow: hidden;
    position: absolute;
    top: 0;
    left: 50%;
    margin-left: -10px;
    width: 20px;
    height: 22px;
}

云顶娱乐yd2221 13

通过伪成分达成的Logo

本文由云顶娱乐发布,转载请注明来源:又不清楚怎么命名class了,express搭建服务端框架