0%

css三角关键在border的绘制:
先画一个width,height都为0的div,然后给他的四个边都加上一个粗实线。

效果是这样的:
image
就构成了4个不同方向的三角形。
需要哪个三角形,就把其他方向的border的颜色透明度设置为0,比如我要左边的这个三角形,就把上,下,右边透明度设置为0:

效果看起来就是:
image

二次请求一般是指发送正确请求之前,额外发送了一次OPTIONS请求。

OPTIONS请求,也叫预检请求和嗅探请求,目的是为了检测要发送的真正请求是否是服务器允许的请求,如果服务器不允许,则会停止发送真正的请求。
产生OPTIONS请求的原因,首先是这个请求是跨域请求,因为只有在CORS跨域资源共享场景下,服务器http header中会有一个叫“Access-Control-Allow-Origin”的字段,该字段规定了指定的客户端来源才能对服务器资源进行访问,那么在这个来源之内的所有请求,都是CORS跨域资源共享模式,但是在这个模式下,服务器也不是完全相信客户端的,对那些可能对服务器数据产生副作用的 HTTP 请求方法(特别是 GET 以外的 HTTP 请求,或者搭配某些 MIME 类型的 POST 请求),即非简单请求,浏览器必须首先使用 OPTIONS 方法发起一个预检请求,如果预检不通过,服务器还是会拒绝浏览器的请求。

非简单请求定义:

  1. 使用除GET、HEAD、POST方法之外的其他请求类型如PUT DELETE 等。
  2. 人为设置了下列列表之外的其他header字段:
  • Accept
  • Accept-Language
  • Content-Language
  • Content-Type (application/x-www-form-urlencoded、multipart/form-data、text/plain之外)
  • DPR
  • Downlink
  • Save-Data
  • Viewport-Width
  • Width

若发送了非简单请求,则会产生嗅探请求。
解决方式:

  1. 可以将发送的请求改为简单请求
  2. 或者将客户端与服务端部署在同一个ip地址下或者使用请求代理让其不产生跨域
  3. 或者在服务器CORS header中的Access-Control-Allow-Methods字段中,增加对OPTIONS的支持,后者只会让所有OPTIONS请求通过,而不会去除OPTIONS请求。

js 手动实现自定义事件监听

自定义事件监听,其实也是观察者模式的一种

我们在jquery中经常用

来注册事件监听,那么他具体是怎么实现的呢,其实背后就是观察者模式的一种实现。

观察者模式,有几个要素:

  1. 第一需要将需要观察的对象存放起来。

  2. 第二需要在需要的地方调用该观察者。

  3. 第三观察者需要分类,同一类的观察者可监听同一个事件,事件触发时,所有的观察者都需要被通知到。

下面来具体实现一个观察者模式。

上面代码里使用了es6 的Map对象来存储观察者。注册观察者的时候,每收到一个观察者注册,就按类型将他们分类存放,同一类的观察者存储在一个数组中。触发观察者的代码中,收到触发的命令后,找出触发的类型,调用所有已注册的同类的观察者。删除观察者,就将注册的所有观察者删除,return this方便链式调用。

调用示例如下:

如上便用观察者模式实现了一个事件监听机制。

源代码见github链接

闭包的那些事儿

  • 怎么写一个闭包
    闭包是什么就不解释了,直接写一个闭包函数:

    js中,函数是一等公民,定义一个函数f,它返回另一个可执行函数`function() {

    };`

    js中的作用域,都是一层一层向上找的,在f内部函数里面,他的num向上找到父函数的作用域。
    现在,我们执行一下:

  • 内存回收机制
    为什么上面执行结果不太对,因为执行f()()后,f函数已经执行完毕了,没有其他资源引用f,ta会被立即释放,也就是说,f()()执行完后,立即就释放了。
    如何才不释放呢?

这下就对了,num成了私有变量,f拥有了私有作用域。

完了吗?
f有了fn的引用,内存一直得不到释放,咋办呢?这样的函数多了是不是会造成内存溢出?
手动释放一下:

在git项目中我们提交代码的时候经常遇到这样的报错:

这时候提交会失败。
解决办法是,到.git目录下,删除index.lock文件,就能正常提交了。
那index.lock有什么作用呢?
官方是这么说的:

在进行某些比较费时的git操作时自动生成,操作结束后自动删除,相当于一个锁定文件,目的在于防止对一个目录同时进行多个操作。有时强制关闭进行中的git操作,这个文件没有被自动删除,之后你就无法进行其他操作,必须手动删除。

通俗讲,就是我们在commit的时候,会自动生成一个index.lock文件,操作完成后,会自动删除。如果在commit过程中,产生了意外,比如手动退出了,电脑死机了,断网了等等,导致操作失败,没有自动删除index.lock文件,那么下次再commit的时候,系统不知道你的index.lock没删除,它会傻傻的再去创建index.lock文件,这时候,发现已经目录下已经有一个index.lock文件了,懵逼了,不知道咋处理了,所以抛错给你:

字面意思就是,创建index.lock文件失败,因为File exists:文件已存在。
这就是这个报错的来源。

mongodb中连表查询很方便,mongoose中的populate可以很方便的实现

如下:我们有两个Model,User和File,User的avatar属性是关联着File的id:

现在,这两张表是关联表,查询User的时候如何关联查询出File中的所有属性呢?
如下是一个查询接口的实现,根据user name查询出user和关联的File所有数据:

返回数据如下:

可见,File通过连表查询populate查询出了File所有的数据。
populate函数还有其他参数:

表示只返回File的name属性,不返回其他属性。

今天在一个npm项目中需要添加一个运行脚本至bin字段

添加后大概张这样:
image.png

这样,在命令行中直接输入socketev就会执行后面的文件。
添加后执行却报错:

应该是环境没有这个脚本,查一下百度:

image.png

难道要重新install一次?
重新install一次之后
还是报上面的错。
查看了很多搜索结果,都是这一句话:

bin项用来指定各个内部命令对应的可执行文件的位置

上面代码指定,someTool命令对应的可执行文件为 bin 子目录下的 someTools.js。Npm会寻找这个文件,在 node_modules/.bin/目录下建立符号链接

都是csdn上面互相抄袭的东西,一点用没有。

果断google:
第一页就有结果:
image.png

好吧,执行一下npm link

执行成功了。
总结:远离百度
最后看一下npm link的作用

  1. 先在全局npm环境中创建了一个socketDev命令
  2. 再在全局环境创建一个socket-serve包,也就是当前我们npm包的name字段命名的包。
    3.再将全局socket-server 包的命令执行环境指向当前目录/workspace/socketProxy

这样,就在全局环境添加了一个可执行命令。

python函数传参跟js很像:

  • 直接传参方式:

形参实参按顺序一一对应,跟js一样

  • 指定传参

    参数顺序不用一一对应,js中也有类似的方式,通过obj实现:

    参数使用了解构赋值

  • 参数默认值:
    `
    def func (name, age = 18) {
    print(“name :” + name + “age: “ + age)
    }
    func(name=’zlx’)

// -> name: zlx age: 18

var func (name, age = 18) {
console.log(“name :” + name + “age: “ + age)
}
func(‘zlx’)
// -> name: zlx age: 18
`

react 表单  双向绑定的实现

view on github

在 react 开发中,经常遇到 input 输入框改变值的时候,要定义一个函数,该函数内部执行 setState 的操作,才能改变 input 的值。如果表单元素多了以后,就会定义很多的这种函数,使代码变得冗余。下面在 react 中实现一个类似于 vue 的表单双向绑定的逻辑。

修改表单的值,只需如下操作:

而且不用关心表单 onchange 的事件逻辑,表单 onchange 时会自动更新 state 中的值。

核心代码实现如下:

使用如下:

这样巧妙运用get,set方法来实现react表单双向绑定,就会在开发者简化很多代码。