vivian blog


  • 首页

  • 归档

  • 标签

  • 简历

  • 搜索
close
vivian blog

session,

发表于 2017-05-29

session是什么

http是一个无状态协议,所以server和client不会一直保持连线状态,也不会有双方状态的即时更新,所以sever并不知道client的状态(像是是否已经登入),由此引入了session,代表服务器与浏览器的一次会话过程,其被存储在服务器端。

session的原理

Session 的机制就像是你去飲料店下了單以後,得到号码牌,然後你走开几步,店員就忘了你是誰。所以,如果你想去取飲料,你就得靠這張號碼牌,去跟店員領,店員會跟據這號碼牌,認定你是顧客、是否點過餐、知道你點了什麼東西,然後可以接著給你屬於你的飲料。

理解之后,回到http上就是一样,在网络领域中,有两种方法让client取得号码牌,一个是用cookie,另一个是直接输出并嵌入页面当中的方法,即直接把号码背下来。
拿号码牌去sever拿资料,亦分为两种方法,cookie和运用标准的query string /post body

cookie-based session

事实上,在最原始的session设计当中,开发者是将资料存储在sever,或是usb或数据库当中,每当顾客来买东西,店员就输入你的号码来得知你是否点过餐。
这种方案在小型网站是完全行得通的,只是在现在超大流量的网络服务来看,直接将资料存储在sever,就意味着大容量的数据库,以及存放和共享资料的技术,加之兼顾效能以及方便维护而言,这就是相当大型的问题
而cookie-based-session就提出将资料暂时存放在cookie当中,让client自己存放,其原理通常是使用 Query String 或 POST body 等方法,把資料往 Server 傳之後,在 Server 端將 Client 上傳的資料存在 Session 之中,简单地说,

你点什么饮料,统统直接写在号码牌上,sever就可以直接看你的号码牌,而无须发大量的是将去建立大规模的server来处理session

只是cookie只有4k容量的限制,所以网站有时候会采用cookie-based-session和服务器端session并行的策略。

session传值

利用session机制来储存资料,让不同页面之间可以传递资料。之后的连接或开启其他页面是,因为你拿的号码牌是同一个,所以在不同页面当中,仍然可以读到迁移所储存在session的状态。

session会在浏览器关闭后消失嘛

不会的,浏览器关闭后其所创建的sessionid就会随之消失。而seesion只会在其expire到期时,会是直接在服务器端强制清除,才会使session消失。

vivian blog

未命名

发表于 2017-05-25

前言

前些天一直在学习nodejs,现在来总结一下Nodejs该项目中的要点吧

目录结构

  • config - 里面存放着的端口配置信息,以及express-session的一些配置,引申知识:session

  • lib - 存放着数据库的一些表(定义里面有什么数据结构,诸如User,Comment,post)这些表,还在其中自定义了插件,是根据Id来生成创建时间的

  • middleware - 存放中间件(在客户端和服务器端发送请求起作用,本项目是用于检查用户是否登录,并进行后续的处理)

  • models - 存放一些对于表所进行的操作,诸如增删改查

  • public - 用于存放静态文件,比如css文件啊,img之类的

  • routes - 用于存放路由文件,里面主要是调用http方法后进行处理

  • views - 存放一些模板文件

这里遵循了MVC开发模型,model(模型) - view(视图) - controller(控制器routes)

安装依赖模块

  1. express: web框架
  2. express-session: session 中间件
  3. connect-mongo: 将session存储于mongodb,结合express-session使用
  4. connect-flash: 页面通知提示的中间件,基于session实现
  5. ejs: 模板
  6. express-formidable: 接收表单即文件的上传中间件,基于session实现
  7. config-lite: 读取配置文件
  8. marked: markdown 解析
  9. moment: 时间格式化
  10. mongolass: mongodb驱动
  11. object-to-timestamp: 根据ObjectId生成时间戳
  12. sha1: sha1密码加密
  13. winston: 日志
  14. express-winston: 基于winston的用于express的日志中间件

安装使用mongodb

教程
推荐使用robotmongo这个可视化Ui界面

配置文件

顾名思义配置文件则是,定义一些可配置的变量,从而使你的项目可以在不同的环境下运行。

功能与路由设计

vivian blog

todoApp

发表于 2017-05-20

todoApp思路

这个App使用了MVC的设计思想,现在具体说一下三个层的具体实现方式。

  • view层

    • 使用了ejs动态模板,可以将后台传来的数据动态地写入html文件,而无须使用js来获取选择器,从而填充,但是本app每次请求成功后,都需要重绘整个页面,这是硬伤,学术解释为

      界面设计人员进行图形界面设计。

  • controller层

    • controller主要功能是进行路由选择,向服务器发出请求之后,给客户端的响应,突然感觉这样功能没有分的很明晰,因为我们使用了express模块,所以不需要额外设置一个server模块和一个route模块。一言以蔽之

      负责转发请求,对请求进行处理

  • Model层

    • 应用的业务逻辑层,主要负责功能的实现,但是此处的功能主要是添加和删除,而恰好http方法中有delete和post方法,可以直接使用,所以这里的app就没有特地设立一个model层。学术解释为

      程序员编写程序应有的功能(实现算法等等)、数据库专家进行数据管理和数据库设计(可以实现具体的功能)。

以及模块的导出和导入方式,注意模块不需要将整个文件都设为一个模块(因为模块是一个封装所需功能的能访问并记住其所在词法作用域的代码片段)

app具体实现

controller

controller层的主要难点是连接数据库,在mlab中新建完数据库之后,要再新建一个账户和密码,来连接云mongodb。

1
2
3
4
5
6
7
8
9
10
//text是账户名,第二个text则是密码
mongoose.connect('mongodb://text:text@ds147681.mlab.com:47681/todolist');
//create a Schema,tell the db what properties it should contain
var todoSchema = new mongoose.Schema({
item: String
});
//what schema was base in the model
var Todo = mongoose.model('Todo',todoSchema);

然后连接完数据库便就可以对请求进行处理了,主要是向数据库发出查找请求,并执行相对的操作(删除/新增)

view层

使用ejs模板,ejs语法<% %>即可嵌入js语法,其和java开发中jsp语法是差不多的,现在想来我公司的代码很多时候都是重绘整个子页面的,感觉性能上就做得不是那么到位

vivian blog

Nodejs框架归类

发表于 2017-05-19

前言

前些天一直在youtube逛nodejs的教程,然后我发现了ninjas这个教程,里面的视频内容很赞哦,比较全面的介绍了nodejs的内容,从对文件的操作,到express,nodemon,body-parser等框架的应用场景,以及Middleware的概念让我受益匪浅,现在让我粗略总结一下关于nodejs的东西吧

nodejs是什么

nodejs是基于google chrome v8 engine写的c++程序,它是javascript应用服务器端的语言

npm 模块管理包

以下,我主要讲述npm的一些指令,而不是讲述其底层的工作原理,鉴于我知识面的限制。

  • npm i express 安装express模块
  • npm i express -g 全局安装express模块,并express写入环境变量,这样在全机都可以运行express模块
  • npm i express -save 安装express模块,并将此依赖保存在package.json文件中
  • npm uninstall express 写在express模块,注意package.json文件中并不会将对应的dependencies删除
  • npm install 此时会查找你的package.json文件中的dependencies,并将里面的模块都安装在你所在的目录之下

对象的继承

nodejs中的inherits方法,能够让一个对象继承另一个对象的属性(底层操作应该也是复制对象),i.e

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
var events = require('events'),
util = require('util');
var Person = function (name) {
this.name = name;
}
util.inherits(Person,events.EventEmitter);
var james = new Person('james');
var mary = new Person('mary');
var ryu = new Person('ryu');
var people = [james,mary,ryu];
//person就已经继承了eventEmitter中的特性
people.forEach(function (person) {
person.on('speak',function(msg){
console.log(person.name+' said: '+msg);
});
});
james.emit('speak','hey dudes');

文件操作

mkdirSync是创建folder的同步操作,这是阻塞性的操作。
rmdirSync是删除folder的同步操作

mkdir, 基于nodejs是单线程,非阻塞的工作模式,故其是非阻塞式的异步操作,i.e.

1
2
3
4
5
var fs = require('fs');
var file = fs.readFile('input.txt','utf8',function(err,data){
fs.writeFile('writeme.txt',data);
console.log(data);
});

rmdir,删除folder的异步操作

unlink 删除file

writeFile先创建文件,再写字符串进去(string/stream),如果是json格式,则需要json.stringify()来将该对象转换为字符串
同理readFile则是读文件,他们都具有异步和同步两种方法

stream & buffer

stream 是对buffer的高级封装,其操作的底层仍是buffer对象

buffer 是数据缓存对象,类似数组对的数据结构,其主要作用是

将少量的数据存储在buffer中,当buffer中的数据已经装满后,就将其运输到目的地,然后,再重新前面的步骤,知道所有的数据都运输完成为止

现在让我先创建一个myReadStream出来

1
2
3
4
5
6
7
var myReadStream = fs.createReadStream(__dirname+'/readMe','utf8');
var myWriteStream = fs.createWriteStream(__dirname+'/writeMe.txt');
myReadStream.on('data',function (chunk) {
console.log('new chunk received.');
myWriteStream.write(chunk);
});

pipe

另一种更加简洁的写法是使用pipe,其原理与上面的所写的差不多

1
myReadStream.pipe(myWriteStream);

express 快速处理不同的路由/跳转到不同的url

说到路由,现在列出http的方法

  • app.listen(3000);
  • app.get(‘route’, fn);
  • app.post(‘route’, fn);
  • app.delete(‘route’, fn);
1
2
3
4
5
var app = require('express')();
app.get('/',function (req,res) {
res.send('this is the home page');//注意这里只能传入字符串和stream流;
//如果想要传入json对象,要使用json.stringify()转换成字符串
});

然后另一种是动态的路由 route param

1
2
3
4
//:id是url传入的参数
app.get('/profile/:id',function (req,res) {
res.send('you requested id' + req.params.id);
});

ejs template

ejs是一个模板引擎用来渲染动态的html

1
app.set('view engine','ejs');//设置view层的模板引擎为ejs

<% %>这是ejs的语法,而它的参数通常是通过ajax来获取的,另外一种表达式则是<%= %>

而后台的传送则是通过

1
2
3
app.get('/profile/:name',function (req,res) {
res.render('profile',{person:req.params.name});//第二个参数则是传输的参数
});

ejs还有另外一种语法,而此语法有助于模块化的开发

1
<% include partials/nav.ejs %>

这样子就相当于将nav封装在nav.ejs中,而其他页面若想要调用可以直接写上这条代码即可

middleware

middleware的含义便是中间件,可以解释为将具体业务与底层逻辑解耦的组件,目前我所接触到的middleware有body-parser,express中的static方法

  • express.static是用于共享资源的,比如说,当你在ejs文件当中引入了一个css文件,然后你在localhost中无法访问到那个css文件,这说明在服务器的文件结构并不像你本地文件的结构,所以此时就可以向服务器指定你资源的准确位置,这样ejs才能访问到你的css文件,代码如下

    1
    2
    3
    app.use('/assets',express.static('asstets'));
    //注意即便你将你本地那个文件重命名,你再浏览器中访问/assets,仍然能够访问到那资源
    //注意第一个就是你所指定的路由
  • body-parser
    body-parser是一个请求体解析中间件,在实际应用中,不同路径(路由)可能会要求用户所以不同的内容类型,body-parser还支持为单个express路由添加请求体解析:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    var express = require('express'),
    bodyParser = require('body-parser'),
    app = express(),
    //创建application/json解析
    jsonParser = bodyParser.json(),
    //创建application/x-www-form-urlencoded解析
    urlencodedParser = bodyParser.urlencoded({extend:false});//extend不知道是什么
    //POST/login 获取url编码的请求体
    app.post('/login',urlencodedParser, function (req,res) {
    //req.body获取请求体
    if(!req.body) return res.sendStatus(400);
    res.send('welcome, '+req.body.username);
    });
    //POST /api/users获取json编码的请求体
    app.post('/api/users',jsonParser,function (req,res) {
    if(!req.body) return res.sendStatus(400);
    //create user in req.body
    })

nodemon 监控框架

nodemon可用于监控文件是否有所改动,后台js文件有所改动,nodemon都会重启node,然后直接在浏览器就可以浏览到已经修改的结果,若改动的是前端的js文件,则需要使用rs指令来重启服务器,nodemon app.js是运行app.js文件的指令

mongodb & mongoose

看到mongodb和mongoose发现,这真的是很简洁的创建数据库,以及操作数据库的方式,比起oracle来说,真的简单许多
现在来说一下mongodb在云端上的存储mlab。

vivian blog

线上部署heroku

发表于 2017-05-16

目标

将爬虫部署上heroku,成为一个线上项目,
我部署的在这里

知识点

学习heroku的线上部署heroku

课程内容

heroku可以让你只专注与页面逻辑,而不需配置服务器和装载数据库,大大地提高开发效率。

好了,我们先git clone https://github.com/alsotang/node-lessons/tree/master/lesson3,然后注意每一个nodejs都需要有一个package.json去表明自己的身份(nodejs程序),这样可以让heroku知道你哪一个程序是nodejs主程序。package.json可通过npm init添加,至于里面的git repository则需要填写heroku remote -v里得出的值

首先先去注册,然后去下载,再在命令行通过heroku login登录,注意这里的邮箱填写最好是填写你github登录的邮箱。

然后要git add .添加文件,或者也可只添加一个,详细命令请上网查询,然后git commit -m "first commit",-m后面是双引号,最后git push heroku master,然后window会弹出一个登录窗口,注意这里的用户名和密码请参见C:\user\user\netrc文件,可用记事本打开查看,然后输入git的账号密码,然后即可push成功啦,注意若出现Failed to detect app matching https://codon-buildpacks.s3.amazonaws.com/buildpacks/heroku/nodejs.tgz buildpack,说明heroku它无法识别你的nodejs程序,这时候需要添加package.json文件,如上所述。git add package.json,git commit -m "track package.json",这样我们heroku的部署便算成功。

最后输入heroku open后,浏览器便会自动打开,并能访问到部署到heroku的线上应用啦。

vivian blog

company-html's trick

发表于 2017-04-17

知识点

  • 建立树形结构时,使用dl,dt,dd标签,而不是使用ul li标签,如此便不需要另外为第一个li设置title样式

  • 若顶栏和侧边栏固定时,内容栏可使用iframe进行异步加载,若该内容栏中有诸如新建这种需要跳转别的页面的功能,则可使用div嵌套iframe来实现异步加载。(即有两个iframe)

    • 具体做法:加载内容页时,嵌套的iframe的父层设为display:none;,且嵌套的iframe的src="",当点击新建btn时,再向iframe的父层设为display:block;,并将嵌套的iframe的src=对应的html路径
  • 呈现表格的时候,要将表头,和表身分开成两个div嵌套table,并把表身定高,这样做是为了当表身内容无限多的时候,可产生滚动条,这样子,表头便固定在表格的顶部,用户体验就会更加好

  • 弹窗的时候,其主要的html是

    1
    2
    3
    4
    5
    6
    7
    <div class="overlay-window">
    <iframe></iframe>
    <div class="caption"></div>
    <div class="content">
    <iframe></iframe>
    </div>
    </div>

    第一个iframe的src值为空,其目的是为了遮住视频控件,因为视频控件的z-index是相当高的,而第二个则是加载另外一个页面

  • 要灵活运用自定义属性,以达到Js的扩展性

  • 段落元素无法包裹块级元素,这样会大大降低在chrome浏览器的可读性,span是可以包裹住span的。

  • 要熟练使用w3c标准,多使用语义化标签

  • 要注意主次之分,使用pd10这些bootstrap的class只是为了不影响其他类名,切不可滥用这些类名,这会导致调试不方便(每次都要修改的时候都要在html上进行修改

  • 可使用overflow: auto,使其在内容超出范围时产生滚动条。

  • 啊,我又忘记了要好好思考那个html,css布局了,!important,如果思考的不仔细的话,可能会影响到日后的Js的编码,绝对不能重复,回去之后一定要改回来!

  • 自适应布局,主要特点是:不设定高度,当内容超出容器范围时,出现滚动条。解决方法:将其设为绝对定位布局,并且设定其位置,其父级亦设成绝对定位position: absolute;,并设定其具体位置(top,left之类的),以避免内部文本超出文本流(即将父级与子级在同一层)

  • 每当刷新页面时,有时候,页面会突闪(抖动)纵向滚动条(出现后立即消失,且内容很少,不足以出现滚动条),先说说解决方法,直接在<body></body>上设置overflow: hidden;(只要不设高度,overflow:hidden;便不会将超出的内容隐藏掉),便可解决这问题。

  • 让文字只在一行当中呈现,不断行,使用class="text-overflow"(bootstrap的class),与此同时,该元素需要设置宽度,这样便能呈现出该文字便能在一行当中呈现,而超出的部分用...展示,为了使该元素做到自适应宽度,还有另外两种更优的方法:

    1. 让该元素的display:block;,原因是在正常文本流当中,该元素的宽度是由其祖先元素撑开,(由于checkbox和其右边的文本不在同一水平线),故将其父级元素设为position: relative;,并将checkbox设为position: absolute;,然后再通过top,left之类的元素调整它的位置

    2. table的特点是左列固宽,右列自适应table剩余的宽度,故该思路为将其父级元素设为display: table;,该元素及其同级元素设为display: table-cell;,这样亦可完成需求。

  • 不能让用户的信息量的多少影响你的排版,而预先固定一个最大高度,然后在那个元素上添加纵向滚动条。

  • 两端对齐的时候,然后信息很多的话,如何做到不影响排版呢?


感想

2017/4/25

感觉最近想法不正确,以为直接将对方的代码copy下来,就可以提高开发效率,却没有去思考该代码是否优化,甚至乎,很多时候,在人家冗杂的代码当中纠结许久,浪费自己的时间。而正确的提高写页面效率的思路应当是:

每当看到一个页面,应当先自己思考一下该布局如何实现,然后再去参考别人的代码是否已经实现了你的想法,若有,则可直接复用,若没有,则需要自己编写!千万要注意,复制糟糕的代码还不如自己编写的代码的开发效率快!

而我自己呢,却只是一味地复制粘贴别人的代码,丝毫没有去思考!长此以往,你永远都不能建起属于自己的代码库,而你也只会变成一个不会独立思考的人!

2017/4/26

今天在地铁上思考了一下接下来的计划,首先在公司里,若没有什么任务的时候便可以刷leetcode,然后晚上便在宿舍进行当天的工作总结,随后开始看算法书籍,然后做算法题,可将做题的内容放在github上进行版本管理,这样可以看到你解题思路的历程。

然后,今天在公司里没什么任务,于是我便刷起了leetcode,每每做完一道题,且当其呈现为绿色的Accepted的时候,我便感觉有一种自豪感驱使我继续闯关答题,嗯,所以我更要执行我的计划,让自己成为一个更加强的人。

2017/5/3

最近总是将自己的整块时间碎片化,每当复习算法的时候,就想着要不要做做前端的项目啊,然后又开始谷歌搜索前端项目。然后搜到一些很不错的项目之后,就添加为标签,然后继续浏览其他页面,至于之前积聚的项目却都不予以理会。我忽然想起了先前在公众号看到的一篇文章:

在看书的事情上,很多人都会在微信上列出自己的一大堆书单,可是你又真正看了几本书呢?

是啊,我觉得我陷入了一种怪异的自我满足情绪,就是每当看到一些成功的案例,或是一些有助于前端知识积累的列表,我就会毫不犹豫地去收藏,去添加标签,心里还沾沾自喜地想着,啊,有了这些干货,我肯定会变得很厉害,然后便开始心有旁骛地去干这干那的,可是这样子的效率真不是一般地低,每每想到9月份就要秋招了,可也许那时的我跟现在的我在前端上的距离却也没有拉开多少,这不正是别人所说的:

三个月的经验重复了5到6年

哦,这是多么让人沮丧的事情啊,想想那时候,别人也许已经成为了前端架构师,而你还在做着什么,前端页面仔!哦,我不要做这样的人!所以说从现在开始,我要好好管理自己的时间:

  • 工作日学一个章节的算法(1.1为一个章节),与此同时要刷leetcode(linklist),一定要学会调试 Linklist,每天在leetcode做2~3题,然后就总结:
    • 解题思路
    • 排序的思想
  • 学习《你不知道的js–(中卷)》看一个小节
  • Node.js,了解基本概念,然后跟着做一些web应用,然后了解一些框架和插件,然后慢慢摸索吧。

今天在公司刷leetcode的题,发现自己其实对链表的原理并不熟练,于是便想着要调试一下从而明白其原理。但是当我写测试用例的时候,发现并没有现成的函数让我去观察它的结果,然后我便一筹莫展,当我用谷歌搜索发现,人家早已经建立了自己的代码工具库,对啊,这种思维,这种独立的精神正是我所缺乏的,没有相应的函数库的时候,便自己去编写。忽然想起别人所说的:

linux思维和window思维,用window的人大多希望有现成的代码,让自己直接套用,而用linux的人则不同,他们很有Geek精神,当没有现成的代码库的时候,他们便自己去编写个性化的代码库,乐于分享,开源,尊重他人的劳动成果。

嗯,看来我得学习linux,这是对我Geek精神的培养。

2017/5/11

最近发现自己很容易就跳进自己所挖的坑,比如说刚开始的时候,容易

vivian blog

辞职感受

发表于 2017-04-15

自我感受

刚开始的时候进入方遒,觉得在方遒里前端做项目的感觉,应该是跟在学校里和他人组队完成项目的过程是差不多的性质,我们可以互相讨论问题,相互解决问题,从而完成项目,这也是一个自学过程,而且期间还有实习补贴,所以应该能够适应和得到提升的,但是经过这几天的工作,我发现方遒是没有一位正职的前端开发工程师,带我的那个也是一位应届毕业生,这个让我有点失望

然后我发现,公司的项目很赶,每当我遇到问题后,并且经过谷歌和百度搜索及个人调试后没找到解决方案,苦思不得其解,正想询问师兄解决方法之时,发现他们也很忙,我也不好继续打扰,耽误他们的开发进度。照这样发展下去项目太干了,自己边没有太多时间去整理思路,便可能会直接上网复制代码,也没有时间去理解其实现思路,更勿论代码可复用性及性能优化

而此时,佳都公司亦打电话说,他们想要录取我入职,那是一家比较正式大规模的,与公安机关合作的公司,其有自己开发的组件,以及模块化的代码思路(可扩展性和代码复用性),这是相当不错的公司,于是我便毫不犹豫地转向该公司了。

vivian blog

jquery事件委托方法

发表于 2017-04-13

前言

前些天做了个点赞的效果,那时候没有用到事件委托的方法,想来相比起用事件委托方法,性能锐减,所以现在记录一下jquery中不同的事件绑定,触发,解绑的方法以及用途

定义

事件代理是指将事件绑定到父级元素中,然后等待事件通过DOM冒泡到该元素再执行,事件侦听中有事件冒泡和事件捕获两种方法,而jquery中通过事件冒泡方式来实现事件代理,分别有bind(),live(),delegate(),on('click'function)方法来实现事件的绑定

  • 事件冒泡:从发生事件的元素向其祖先元素冒泡
  • 事件捕获:事件在DOM中寻找子元素

现在介绍一下事件绑定有那些方法

最普通的事件绑定click()

1
2
3
$("#div1").click(function() {
console.log("点击后触发");
});

不提供解绑定方法,且要每个元素逐一绑定

可解绑定的on(‘click’,function)

1
2
3
$("#div1").on('click',function() {
console.log("点击后触发");
});

可使用$('#div1').off('click');解除绑定

bind()方法(使用冒泡的形式)

1
2
3
$("#div1").bind('click',function consoleMe() {
console.log("点击后触发");
});

可使用unbind()解除绑定
注意:bind()仅适用于为DOM中已经存在的元素绑定事件处理函数,动态生成的DOM元素,则不起作用
eg:

1
2
3
4
5
$(document).ready(function(){
$('.box').bind('click',function(){
$(this).clone().appendTo('.container');
});
});
1
2
3
<div class="container">
<div class="box">click me</div>
</div>

运行结果,单击第一个链接,会追加元素,但是除了第一个链接,其余都没有被绑定click事件

live()

live()在jquery1.9以后已被丢弃,但现在仍记录一下其用法,live()与bind()的最大区别在于live()不仅作用于已经存在的DOM元素,还作用于将来动态生成的元素

1
2
3
4
5
$(document).ready(function(){
$('.box').live('click',function(){
$(this).clone().appendTo('.container');
});
});
1
2
3
<div class="container">
<div class="box">click me</div>
</div>

注意live()使用了事件委托的方法,但是它有所下几个缺点:

  1. $()函数会找到当前页面的所有.box元素并创建jquery对象,但在确认事件明白时却不用这个.box元素的组合,而是使用选择符表达式与event.target或其祖先元素进行比较,所以生成jquery对象会导致不必要的开销
  2. live()默认把事件绑定到$(document)元素,如果DOM嵌套很深,事件冒泡通过大量祖先元素会导致性能缺失
  3. 只有$('.container .box')才能使用live(),$('.container').find('.box')不行。
    hack手段,早委托方式,其必须在head元素中进行加载,放在尾部则不管用
1
2
3
(function($){
$("#info_table td").live("click",function(){/显示更多信息/});
})(jQuery);//jQuery对象

delegate()

1
2
3
4
$('.container').delegate('.box','click',function(){
$(this).clone().appendTo('.container:first');//若没有涉及到数值的改变,则可以这般写,否则的话,其便会共用一个作用域,
//解决方法有两个,一个是创建闭包,另一个是通过绑定一个Id选择器来获取该元素,并进行事件委托
});

delegate()使用了事件委托的方法,其根元素是具体绑定的元素,由此看来,使用delegate()要比live()效率更高。

提示:使用事件委托时,如果注册到目标元素上的其他事件处理程序使用.stopPropagation()阻止了事件传播,那么事件委托就会失效。

on(‘click’,’.box’,function)是比较新的方法

1
2
3
4
$('.container').on('click','.box',function(){
$(this).clone().appendTo('.container:first');//若没有涉及到数值的改变,则可以这般写,否则的话,其便会共用一个作用域,
//解决方法有两个,一个是创建闭包,另一个是通过绑定一个Id选择器来获取该元素,并进行事件委托
});
vivian blog

Repeated Substring Pattern

发表于 2017-04-10

需求

需求链接

Given a non-empty string check if it can be constructed by taking a substring of it and appending multiple copies of the substring together. You may assume the given string consists of lowercase English letters only and its length will not exceed 10000.

解决思路

问题给了我们一个字符串,问能否拆成n个重复的子串。因此既然能拆分,那么每个子串的长度不能大于原字串长度的一半,那么我们可以从源字符串长度的一半遍历到1,如果当前长度能被总长度整除,说明可以分成若干个字符串,我们将这些子字符串拼接起来看跟原字符串是否相等。 如果拆完了都不相等,返回false。

解决方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
var repeatedSubstringPattern = function(s) {
var len = s.length;
if(s.length===1){
return false;
}
for(var i = Math.ceil(len/2);i>=1;i--) {//至少得两个元素,才能看看是不是重复
if(len%i===0) {
//如果能被整除,说明能分成若干个字符串,然后将这若干字符串拼接起来后的字符串,跟源字符串相等的话,那就说明相等,否则不等
var c = len/i,t='';
for(var j = 0;j<c;j++){
t+=s.substr(0,i);
}
if(t===s) {
return true;
}
}
}
return false;
};
vivian blog

intern-experience

发表于 2017-04-07

实习情况

今天是上班的第二天了,这几天我做了2个静态页面和一些Js效果。最大的感触大概就是公司需求变动还是挺大的,首先是table布局不被允许,他们说是因为table现在没什么人知道其特性,但是我觉得既然只是显示数据,那么table就是最好的布局啊。。。可是最后还是改成了ul li布局。

第一次不用bootstrap框架和normalize.css来写静态页面,发现很多页面上有很多潜在的错误是我之前没有发现的,比如用display: inline-block可能会导致html上的元素和有js生成的相同标签的元素会有不同的间隙,这个时候就需要用到float:left来解除潜在的错误!

然后的话,还有一个错误我没有找出来,那就是在jquery中,当我点击button后,然后将该button删除,接着再添加同样的button,当再次点击的时候jquery就找不到那个button,然后我就不知道为什么了。

不过今天get到一个tip,那就是,hover元素的时候之后,会弹出tooltip,鼠标移去tooltip后,tooltip仍是display:block;,解决方法就是,让hover的元素放置在一个透明的父级里,让该父级的宽度要涵盖tooltip和hover元素,便可实现该效果。

再然后就是,当提交有冲突的时候,我好像没有解决那些冲突问题,每次都是叫人帮忙解决,下次得自己解决一下那些问题。


继续更新,周末去加班了,感觉今天的状态真的不太好,头晕,今天的任务主要是实现点赞反对的动态效果。现在说说今天遇到的问题。

遇到的问题

  1. 以为元素只有一个,所以就没有考虑元素的扩展性,后来我就花了一倍的时间去完成那个效果。以后写代码之前,一定要先看清楚页面,问清楚需求,然后考虑js的扩展性

  2. 今天小组内所有人都在写着几个页面,所以在提交的时候,代码就发生了冲突,然后怎么搞都搞不定,最后就只能自己将自己修改的那部分,复制到记事本中,然后等明天复制粘贴过去。日后的解决方法便是每次要写其他文件时,要先询问其他人用没有做,然后进行提交,亦或是当天每个人写了的页面,其他人不许修改,这样子才能够避免冲突

  3. 交互逻辑出现了点问题,刚开始的时候是以样式来判断点赞或去点的,然后样式的改变是在ajax请求成功以后才执行,然而这是一个错误的思路,正确的思路是应该在元素上自定义属性,然后根据该属性的值,进行ajax请求,最后再改变其样式以及要渲染的数据!

  4. 要看清楚接口文档中的url,千万不要搞错,不然会被搞死的

总结

  1. 以前自己自学前端的时候,没有跟后台进行交互,不会遇到现在这些问题,所以才说,业务的实践是自身所遇瓶颈的下限。但是不管如何都要巩固自己的基础,不然的话,你永远都只是一个页面仔,无法成为一个架构师!

  2. 要多点考虑元素的扩展性啊,这是相当重要的一件事情,还有代码的规范啊。

  3. 要多写js,这样的话,写css/html的时候,就会想着要为日后写js的时候,获取更方便的获取元素。

123
vivian

vivian

23 日志
25 标签
Github Weibo Codepen Freecodecamp
© 2016 - 2017 vivian
由 Hexo 强力驱动
主题 - NexT.Mist