后端学前端


  • Home

  • Archives

实现jquery的addClass和text方法

Posted on 2018-07-05

jquery的简介

又开始写博客啦。
jquery是最常用的js库。因为dom api过于难用,而jquery很好的完善了这一点,所以现有网站的有超过一半的页面引入了jquery。

jquery的原理

jquery是一个构造函数,构造函数返回了和查询参数匹配的节点,并在原型上实现很多好用的方法。
jquery的这种实现方式,另起炉灶,没有直接修改dom节点的原型,避免了潜在的冲突。

仿照jquery实现addClass和text

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
36
37
38
39
40
41
42
window.jQuery = function(nodeOrSelector) {
// 根据nodeOrSelector的类型构造伪数组,伪数组由匹配的dom元素组成
let nodes = {};
if(typeof nodeOrSelector == 'string'){
let temp = document.querySelectorAll(nodeOrSelector);
for(let i = 0; i < temp.length; i++){
nodes[i] = temp[i];
}
nodes.length = temp.length;
} else if(nodeOrSelector instanceof Node){
nodes = {
0: nodeOrSelector,
length: 1
};
}

// 实现addClass方法,jquery是利用原型实现的,这里直接绑定在对象上
nodes.addClass = function(classes) {
for(let i=0; i < nodes.length; i++){
classes.forEach(function(someClass) {
nodes[i].classList.add(someClass);
});
}
};
// 实现text方法,参数存在就设置节点的内容,参数不存在就显示节点内容
nodes.text = function(text){
if(text === undefined){
var texts = [];
for(let i=0; i<nodes.length; i++){
texts.push(nodes[i].textContent);
}
return texts.concat();
} else if(typeof text === 'string'){
for(let i=0; i<nodes.length; i++){
nodes[i].textContent = text;
}
}
};
return nodes;
};
// 给jQuery一个好用的别名
window.$ = window.jQuery

js的原型和原型链

Posted on 2018-06-20

js的原型和原型链

学习过ruby,一开始看到原型链的时候想着,哎,这不是ruby的对象模型么。后来发现,虽然功能是类似的,但js和ruby在细节上差别还是很大的。
js里的构造函数在创建对象的时候会将对象的proto属性指向原型对象
当在对象上访问某个方法时也会沿着proto对象访问
一般最后一个有意义的原型对象是Object.prototype
Object.prototype.proto就是null了

可以看出,原型对象里的方法和属性是所有new Constructor出来的对象共有的
原型链的顶端是Object.prototype, 其中有 toString 和 valueOf。因此所有对象都可以使用这两个方法

对js原型链的一些看法,

和ruby相比呢js的原型链是较短的,也没有类类型的概念。js通过原型链实现了方法的共享(通过ConstructorA.prototype.__proto = SomeProtoType可以改变改变原型链)。如果没学过其它语言,js的原型链其实是很直观方便的,学过其它语言反而可能会生搬硬套,这是很有趣的一个地方,哈哈哈。
总之js是很神奇的动态语言,它是随着网页开发发展起来的。它现在一些看起来不合理的地方也是早期设计目标和现代web需求变化造成的。应该客观看待。

js里的数据类型转换

Posted on 2018-06-20

任意类型转字符串

  1. 直接用String()构造函数

    1
    2
    3
    4
    5
    String(1)
    String(true)
    String(null)
    String(undefined)
    String({}) // "[object Object]"
  2. x.toString

    1
    2
    3
    4
    5
    (1).toString
    true.toString()
    null.toString() //error
    undefined.toString() //error
    ({}).toString() //"[object Object]"
    • ‘’, 加一个空字符串
      1
      2
      3
      4
      5
      1 + ''
      true + ''
      null + ''
      undefined + ''
      o + '' //"[object Object]"

任意类型转数字

1
2
3
4
5
Number(x)
parseInt(x, 10) //MDN
parseFloat(x) //MDN
x - 0
+x //

任意类型转布尔

1
2
Boolean(x)
!!x //取反两次就可以啦,吼吼吼

js的历史

Posted on 2018-06-20

js是门神奇的语言。它的历史和浏览器的发展紧紧的绑在一起。

1990年底,欧洲核能研究组织(CERN)科学家Tim Berners-Lee,在全世界最大的电脑网络——互联网的基础上,发明了万维网(World Wide Web),从此可以在网上浏览网页文件。最早的网页只能在操作系统的终端里浏览,也就是说只能使用命令行操作,网页都是在字符窗口中显示,这当然非常不方便。

1992年底,美国国家超级电脑应用中心(NCSA)开始开发一个独立的浏览器,叫做Mosaic。这是人类历史上第一个浏览器,从此网页可以在图形界面的窗口浏览。

1994年10月,NCSA的一个主要程序员Marc Andreessen联合风险投资家Jim Clark,成立了Mosaic通信公司(Mosaic Communications),不久后改名为Netscape。这家公司的方向,就是在Mosaic的基础上,开发面向普通用户的新一代的浏览器Netscape Navigator。

1994年12月,Navigator发布了1.0版,市场份额一举超过90%。

Netscape 公司很快发现,Navigator浏览器需要一种可以嵌入网页的脚本语言,用来控制浏览器行为。当时,网速很慢而且上网费很贵,有些操作不宜在服务器端完成。比如,如果用户忘记填写“用户名”,就点了“发送”按钮,到服务器再发现这一点就有点太晚了,最好能在用户发出数据之前,就告诉用户“请填写用户名”。这就需要在网页中嵌入小程序,让浏览器检查每一栏是否都填写了。

管理层对这种浏览器脚本语言的设想是:功能不需要太强,语法较为简单,容易学习和部署。那一年,正逢Sun公司的Java语言问世,市场推广活动非常成功。Netscape公司决定与Sun公司合作,浏览器支持嵌入Java小程序(后来称为Java applet)。但是,浏览器脚本语言是否就选用Java,则存在争论。后来,还是决定不使用Java,因为网页小程序不需要Java这么“重”的语法。但是,同时也决定脚本语言的语法要接近Java,并且可以支持Java程序。这些设想直接排除了使用现存语言,比如Perl、Python和TCL。

1995年,Netscape公司雇佣了程序员Brendan Eich开发这种网页脚本语言。Brendan Eich有很强的函数式编程背景,希望以Scheme语言(函数式语言鼻祖LISP语言的一种方言)为蓝本,实现这种新语言。

js的历史非常有趣,后续的可以去看阮一峰的博客。

js里的数据

Posted on 2018-06-20

基本数据类型

  • 数值(number):整数和小数(比如1和3.14)
  • 字符串(string):文本(比如Hello World)。
  • 布尔值(boolean):表示真伪的两个特殊值,即true(真)和false(假)
  • undefined:表示“未定义”或不存在,即由于目前没有定义,所以此处暂时没有任何值
  • null:表示空值,即此处的值为空。
  • 对象(object):各种值组成的集合。

数值、字符串、布尔值三种类型,合称为原始类型
对象是最复杂的数据类型 可以分为三个子类型

  • 对象
  • 函数
  • 数组

null和undefined是两个特殊值。null表示空对象,undefined表示未定义。

一些补充

number

  • 整数和小数:1 1.1 .1
  • 科学记数法:1.23e2
  • 二进制:0b11
  • 八进制:011(后来 ES5 添加了 0o11 语法)
  • 十六进制:0x11

string

  • ‘’ 和 “” 没有区别 可以方便的使用内插,而且不用使用转义就可以输入控制字符
  • 在单行字符串尾部使用\可以换行输入字符串,可以避免在编辑器里单行字符串过长,影响显示。

object

  • object 就是上面几种基本类型(无序地)组合在一起
  • object 的 key 一律是字符串,不存在其他类型的 key
  • object[‘’] 是合法的
  • object[‘key’] 可以写作 object.key
  • delete object[‘key’]
  • ‘key’ in object
  • for(key in object){}

typeof 操作符

object的类型 string number boolean symbol undefined null object function
typeof object的值 ‘string’ ‘number’ ‘boolean’ ‘symbol’ ‘undefined’ ‘object’ ‘object’ ‘function’

算法起步

Posted on 2018-06-04

最近工作学习遇到了瓶颈,过来扎实一下基本功。

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
//桶排序
//定义一个随机函数先
function randomInteger(maximum, minimum) {
randomnumber = Math.floor(Math.random() * (maximum - minimum + 1)) + minimum;
return randomnumber;
}
//生成一个随机数组
var a = []
for(var i=0; i < 100; i++){
a[i] = randomInteger(0, 99)
}

//入桶
var hash = {}
a.forEach(function(ele){
if(hash[ele] == undefined){
hash[ele] = 1
} else {
hash[ele] += 1
}

})

//出桶
sorted_a = []
Object.keys(hash).forEach(function(key){
times = hash[key]
for(var i=0; i < times; i++){
sorted_a.push(key)
}
})

ActiveStorage详细介绍

Posted on 2018-05-17

用rails新特性解决它们适合的问题

rails 5给我们提供了不少非常实用的新特性,使用它们替代旧方案,可以提高开发时抽象的层次,不必再考虑已经封装好的逻辑,将精力集中在和业务相关的代码开发上,减少bug,并降低维护的难度。
ActiveStorage就是这样的rails 5新特新之一。

ActiveStorage

ActiveStorage是rails框架内云端图片的上传方案。有直传和后端上传两种方式,并且支持不同大小的图片预览。使用起来非常简单。

后端上传

以创建带图片的消息为例:

  1. 创建一个消息模型, rails g scffold message title:string content:text
  2. rake active_storage:install 并执行 rake db:migrate 这一步会创建两张表 active_storage_attachments 和 active_storage_blobs
    active_storage_attachments 会将附件多态关联到其他记录上, 同时会关联 blob(blob并不存储实际的文件,而是存储文件的属性信息)
  3. 在模型上添加关联 has_many_attached :images

    1
    2
    3
    class Message < ApplicationRecord
    has_many_attached :images
    end
  4. 在form中使用辅助方法
    slim 版本

    1
    2
    3
    4
    5
    = form_with model: message do |form|
    = form.text_field :title, placeholder: "Title"
    = form.text_area :content
    = form.file_field :images
    = form.submit
  5. 在controller中将上传的图片绑定到message中

    1
    @message.images.attach params[:images]

大功告成了 文件可以通过active storage上传了
image.png-42.8kB
文件上传成功
image.png-37.8kB
可以看到后台把每个文件上传到了到了云端,并且创建了一个attachment和一个blob
image.png-97.3kB

直接上传云端

如果想要使用直传方案,只需要引入activestorage.js 并在视图端开启直传就可以了

1
2
//= require activestorage
#新建端rails项目会在全局默认引入

1
form.file_field :images, direct_upload: true

当点创建资源的时候可以看到,应用先去请求后端允许创建资源(1),紧接着将图片上传到云端(2, 3),最后将云端资源信息返回给服务器(4)
1,2,3,4对应下图中的四个请求

上传云端:
image.png-84.1kB
云端返回信息传递给rails:
image.png-53.2kB
rails利用返回的信息创建相应的attachment 和 blob:
image.png-70.7kB

ActiveStorage配置

配置ActiveStorage支持的云端服务非常简单,只需要提供身份认证信息就可以了。

1
2
3
4
5
6
# amazon:
# service: S3
# access_key_id: <%%= Rails.application.credentials.dig(:aws, :access_key_id) %>
# secret_access_key: <%%= Rails.application.credentials.dig(:aws, :secret_access_key) %>
# region: us-east-1
# bucket: your_own_bucket

同时在相应的开发环境配置文件文件中开启对应的服务就行,比如我想在development.rb中启用amazon服务,只需指定它就可以了

1
2
# development.rb
config.active_storage.service = :amazon

github地址: https://github.com/rails/activestorage/tree/archive

css_布局小技巧

Posted on 2018-04-19

左右布局

假设你想要一个左右布局,css有多种方式可以实习

使用背景梯度

如果只使用单个元素,那么可以使用背景梯度,使两种背景色在元素中各占一半。

1
2
3
4
5
6
7
8
9
.container {
background: linear-gradient(
to right,
#ff9e2c 0%,
#ff9e2c 50%,
#b6701e 50%,
#b6701e 100%
);
}


使用绝对定位

如果想使内容也分布在左右两边,一个直接的想法是让两个子元素相对父元素使用百分比绝对定位。这样每个子元素可以有自己的内容。
这种方法的缺点是父元素需要一个指定的高度,而指定高度对内容变化是不友好的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
.container {
display: table;
width: 100%;
}

.left-half {
background-color: #ff9e2c;
position: absolute;
left: 0px;
width: 50%;
}

.right-half {
background-color: #b6701e;
position: absolute;
right: 0px;
width: 50%;
}

left
right

使用float

使用绝对定位需要指定父元素的高度,很容易引起bug。在子元素上增加float可以实现左右分布,注意在父元素上加入clearfix,不然会有bug。

1
2
3
4
5
6
7
8
9
10
.left-half {
background-color: #ff9e2c;
float: left;
width: 50%;
}
.right-half {
background-color: #b6701e;
float: left;
width: 50%;
}


left
right

使用inline-block属性

对于内联元素可以使用inline-block来实现左右布局(块级元素使用float,亲)。inline-block简单来说就是将对象呈现为inline对象,但是对象的内容作为block对象呈现。之后的内联对象会被排列在同一行内。比如我们可以给一个link(a元素)inline-block属性值,使其既具有block的宽度高度特性又具有inline的同行特性。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
div {
display: inline-block;
vertical-align: top;
width: 50%;
padding: 1rem;
}

.left-half {
background-color: #ff9e2c;
}

.right-half {
background-color: #b6701e;
}

leftright

左中右布局

类似的可以使用float和inline-block,宽度设置为33.3%即可

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
.left {
display: inline-block;
background-color: #ff9e2c;
width: 33.3%;
}
.center {
display: inline-block;
background-color: #006CB2;
width: 33.3%;
}

.right {
display: inline-block;
background-color: #b6701e;
width: 33.3%;
}


left
center
right

水平居中

块级元素左右两边的margin设置为auto, 并给定一个固定宽度。内联元素的在父元素上设置text-align: center

块级div元素

内联span元素

垂直居中

对于单个元素,只需要设定上下margin相等即可垂直居中。
对于一行元素,css的vertical-align属性可以控制该行元素在竖直方向上如何对齐。垂直居中,只需要设定

1
2
3
.element{
vertical-align: middle
}


left
center
right

css_布局和定位

Posted on 2018-04-15

css的学习的困难点(日后补充)

开始学习前端三大基础的css了,css和js的学习方式完全不同,css有自己的特点。先了解一下css为什么难学。

  • CSS属性不正交

css的文档流

文档流(normal flow)

网页中的流就是对文档的读取和输出的顺序。其遵循从左到右,从上到下的读取,输出和显示顺序。
简单点说,内联元素依次从左到右水平排列,块级元素从上倒下竖直排列。
由此可以总结一个常用的结论: 块级元素的高度取决于内部文档流元素高度的总和。

脱离文档流

脱离文档流的元素的位置就不再受文档流的影响了。
脱离文档流的元素的位置由脱离文档流的方式决定。
常用的有

1
2
3
4
5
position: fixed //元素的位置相对于屏幕确定的

position: absolute //元素的位置相对于最近的position: relative元素确定的

position: float //待总结

css_style_引入

Posted on 2018-04-08

前端三件套各自的作用:html组织页面的结构,css负责网页的样式,js负责页面的行为。

css样式的引入方式

想要使用css改变网页的样式,首先得引入css,目前有四种引入css方式:

  • 通过内联的style属性
  • 通过style标签
  • link 标签css文件引入
  • 在css文件中通过@import url引入

写一个顶部导航nav先

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
36
a.css

.clearfix::after{
content: '';
display: block;
clear: both;
}
.topNavBar>nav>ul{
list-style: none;
margin: 0;
padding: 0;
border: 1px solid red;
}
.topNavBar>nav>ul>li{
float: left;
}

index.html

<div class="topNavBar">
<a href="#" class="logo" alt="logo">
<span class='rs'>rs</span>
<span class='card'>card</span>
</a>
<nav>
<ul style="list-style: none" class='clearfix'>
<li ><a href="#">关于</a></li>
<li ><a href="#">技能</a></li>
<li ><a href="#">作品</a></li>
<li ><a href="#">博客</a></li>
<li ><a href="#">日历</a></li>
<li ><a href="#">联系方式</a></li>
<li ><a href="#">其他</a></li>
</ul>
</nav>
</div>

这个导航条条里 li 元素用了浮动布局,不过浮动元素经常有奇怪的bug,给浮动元素的父元素加一个clearfix类。clearfix类的样式只有三行,这三行样式可以解决很多bug。

12

zcy4coding

18 posts
12 tags
© 2018 zcy4coding
Powered by Hexo
|
Theme — NexT.Muse v5.1.4