范洋

范洋 查看完整档案

厦门编辑成都信息工程大学  |  网络工程 编辑  |  填写所在公司/组织填写个人主网站
编辑
_ | |__ _ _ __ _ | '_ \| | | |/ _` | | |_) | |_| | (_| | |_.__/ \__,_|\__, | |___/ 个人简介什么都没有

个人动态

范洋 回答了问题 · 2018-04-28

解决vue @click无效

v-for里面不需要写括号的,然后就是楼上兄弟说的打印少写了一半引号。其他貌似没有什么问题

关注 3 回答 4

范洋 收藏了文章 · 2018-04-28

四月份面试题汇总(一)

1.理解原型、原型链?

每创建一个函数,函数上都有一个prototype的属性,他是一个对象。这个对象的作用就是当使用它创建实例的时候,这些实例都会共享原型上的属性和方法。
当我们访问对象中的某个属性时,如果这个对象内部不存在这个属性,那么他就会去__proto__里面去找这个属性,这个__proto__又会有自己的__proto__,
就这么一直找下去直到最后一个__proto__值为null。

var A = function(){};
var a = new A();
console.log(a.__proto__); //A {}(即构造器function A 的原型对象)
console.log(a.__proto__.__proto__); //Object {}(即构造器function Object 的原型对象)
console.log(a.__proto__.__proto__.__proto__); //null

2. __proto__和prototype的关系?

__proto__是每个对象都有的一个属性,而prototype是函数才会有的属性。

举例:var p = new Person();
其中p.__proto__ == Person.prototype。

3. 如何鉴别属性是自有属性还是原型属性?

hasOwnProperty()方法返回true即为自有属性,返回false有两种可能

  • 1.为原型属性;
  • 2.跟本不存在该属性

所以判断是否是原型属性,要先用in判断该对象中是否存在此属性:

function hasPrototypeProperty(obj, name){
        return name in obj && !obj.hasOwnProperty(name);
    }

4.如何判断某个对象是否是另一个对象的原型对象?

isPrototypeOf();
例:function Cat(name,color){}
var cat1 = new Cat();
alert(Cat.prototype.isPrototypeOf(cat1)); //true

5. ES6箭头函数注意点 ?

  • 1.函数体内的this,是定义时所在的对象,而不是使用时所在的对象,始终指向自身外的第一个this。
  • 2.不可以做构造函数,也就是说不可以使用 new 命令,否则会抛错。
  • 3.不可以使用arguments对象,不存在,可以使用Rest代替。
使用Rest:
    var foo=(...arguments)=> {console.log(arguments);
}

6. 让你开始一个项目,你会选择用 vue 还是 React?

  • 1如果你喜欢用模板搭建应用,请使用 vue。
  • 2如果你的应用需要尽可能小和快,请使用 vue。
  • 3如果你计划构建一个大学型应用,请使用 React。
  • 4如果你想要同时适用于Web端和原生App的框架,请使用 React。
  • 5如果你想要更大的生态圈(论坛等),请使用 React。

7. React创建组件的三种方式及其区别 ?

  • 1.函数式定义(无状态组件):function 组件名(props,/context/){}
  • 2.ES5之var 组件名= React.creatClass({})
  • 3.ES6之class 组件名 extends React.Components{}

8. React 中 keys 的作用是什么 ?

keys 是用于追踪哪些元素被修改、被添加、被删除的辅助标识。在开发过程中,需要保证某个元素的 key 在其同级元素中具有唯一性。

9. 为什么接下来这段代码不是 IIFE(立即调用的函数表达式)?

function foo(){ }();

以function关键字开头的语句会被解析为函数声明,而函数声明是不允许直接运行的。
只有当解析器把这句话解析为函数表达式,才能够直接运行,

    解决1.
    (function foo(){
            // code..
    })()
    解决2.
    var foo =  function(){};
    foo();

10. js中如何判断null和undefined ?

    if(typeof(a)=="undefined"){
        console.log('undefined')
    }
    if(typeof(a)!="undefined"&&a!=0&&!a){
        console.log('null')
    }

11. 实现一个数组乱序排列 ?

    var a = [1, 2, 3, 5, 4];
    function fn(a, b) {
        return Math.Random() - 0.5
    }
    a.sort(fn);//[5,1,2,4,3]
    
    
    var a = [1, 2, 3, 5, 4];
    function fn(a, b) {
        return a - b
    }
    a.sort(fn);//[1, 2, 3, 4, 5]
    
    
    var a = [1, 2, 3, 5, 4];
    function fn(a, b) {
        return b - a
    }
    a.sort(fn);//[5, 4, 3, 2, 1]

js如何区分数组还是对象 ? (代表:实现深拷贝函数)

第一种:Object.prototype.toString.call(a).slice(8,-1) == 'Array' ? [] : {}

    var a = {};

    Object.prototype.toString.call(a);//"[object Object]"

    var a = [];

    Object.prototype.toString.call(a);//"[object Array]"

第二种:

    var a=[];
    var b={};
    typeof a === 'object' && !isNaN(a.length)//true
    typeof b === 'object' && !isNaN(b.length)//false

第三种:

    var a=[];
    var b={};
    Array.isArray(a);//true
    Array.isArray(b)//false

实现一个深拷贝函数:

function clone(obj) {
    if(typeof(obj)=='object'&&obj){//&&obj是排除obj=null
        //区分是数组还是对象,建立空数组或空对象
        var o = Array.isArray(obj) ? [] : {};
        for(var k in obj) {
            if(typeof(obj[k])=='object'){
                o[k] = clone(obj[k]);
            }else{
                o[k] = obj[k];
            }
        }
    }else{
        return obj;
    }
    return o;
}

...

微信公众号:前端实习日记
查看原文

范洋 回答了问题 · 2018-04-27

解决如何获取不同级的元素

$('#del1').click(function(){
        console.log($(this).parent().parent().parent().find($('#price1')).html())
})
$('#add1').click(function(){
        console.log($(this).parent().parent().parent().find($('#total1')).html())
})

find是返回当前元素的后代元素选择的结果。里面填选择器。

关注 5 回答 4

范洋 回答了问题 · 2018-04-26

解决console.log是同步还是异步?

这个应该没有异步之说。就算打印出来有某些值,也是不可用的。
clipboard.png

关注 10 回答 8

范洋 回答了问题 · 2018-04-26

这种效果怎么实现的呢

在显示文本的上方有一个遮罩,这个遮罩是从上到下的渐变色,从不透明到透明,就是这样的效果了,你可以自己去试试。

关注 6 回答 6

范洋 回答了问题 · 2018-04-26

vue数据已经变动,界面未变动

随便试了试,点击按钮把数据变为另一组,但是页面option选项是会跟着改变的,所以并不知道你的问题在哪里,也许你触发事件之后数据并没有改动,也许根本没有触发事件。你可以自行学会用console.log来测试代码,清楚的了解自己写的代码执行了哪一步,在不同的位置打印不同的东西,代码是否根据你的想法在执行,如果不是,自己找找问题所在。

关注 5 回答 4

范洋 赞了文章 · 2018-04-26

从输入url开始能做哪些优化

长文。

此文主要讲的事情是如何让用户快点看到首屏页面,其主要影响因素是延迟和解析渲染耗时。有关安全部分其实也是优化的一部分。我们着重说下网络部分。

大致过程:DNS域名解析、建立TCP连接、下载资源、解析页面。文章描述的优化会尽量限制在当时的分析的过程下。

参考

1.DNS域名解析

一般来讲,我们输入的url是域名,而为了识别一个实体,TCP/IP使用IP地址来唯一确定一台主机到因特网的连接,DNS会帮助我们完成域名到IP地址映射的工作。以www.aaa.com为例,解析过程大致如下:

过程

  • 浏览器

    • 浏览器查询浏览器缓存,没有。
  • 本机层

    • 浏览器客户端向系统询问服务器IP地址,调用本机内的DNS解析程序,检查自己本地的hosts文件是否有这个域名映射关系,没有。
    • 查找本机的DNS解析器缓存,没有。
  • 路由器缓存

    • 可能还存在路由器缓存这一层
  • 本地DNS服务器

    • 本机的DNS解析程序向本地的DNS服务器发起请求,一般为TCP/IP参数中设置的首选DNS服务器,是知道IP地址的,一般会UDP协议。
    • 本地DNS服务器查询是否在本地区域文件中,没有。
    • 本地DNS服务器查询DNS缓存中是否存在,没有。
    • 本地DNS服务器会根据是否设置转发器判断是向上一级DNS服务器(其解析规则同理)还是直接向根DNS服务器(知道根DNS服务器的IP地址)发送请求。
  • 与DNS服务器

    • 收到请求后,根DNS服务器并不直接解析地址,但是知道每个顶级域中的一台服务器的地址(如com域名服务器)。如果为迭代查询方式,此顶级域DNS服务器的ip被返回给本地DNS服务器。
    • 本地DNS服务器提取到顶级域DNS服务器信息后,会再向其发出请求。顶级域DNS服务器收到请求后,会先查询自己的缓存,没有,则将负责的二级域名服务器(如aaa.com域名服务器)返回给本地DNS服务器,以此类推直到查到目标域名的映射信息或查询失败。
    • 查到映射信息后返回到本机,中间各层会进行缓存。
  • 查询方式:

    • 递归方式:一路查下去中间不返回,得到最终结果才返回信息。
    • 迭代方式:就是上面的本地DNS服务器与其他域名服务器直接的查询方式,查到一个可能知道的服务器地址,将此地址返回,重新发送解析请求。
    • 一般默认的方式从本机到本地DNS服务器是递归,DNS服务器之间是迭代查询。

优化

当然针对DNS的优化就是减少DNS解析的时间,由于浏览器缓存机制的存在,我们只需要对首次访问进行优化(虽然我们现在只是请求了一个html文件,但是html文件里还会有我们后续要请求的css/js/img等),即适当减少要解析的域名个数,考虑到其他优化机制可以将页面及页面内资源发布到2-4个域名上。

2.建立连接

TCP连接

好了,浏览器终于拿到服务器IP了,客户端想要与服务器间通信并传递消息需要开启TCP(一种传输层协议)连接。

过程

  • 客户端创建socket,向服务器目标端口发送连接建立请求,数据段包含位码SYN(建立联机标志位) = 1,随机数seq(顺序号码)= x,和其他TCP标志和选项。
  • 服务器有一个专门处理连接请求的welcome socket,接收到连接建立请求,置位码SYN和ACK(确认标志位)为1,ack(确认号码)= x + 1,随机数seq = y,并返回。
  • 客户端检查ack是否等于x + 1,等于时,将ACK置为1,SYN置为0,将ack置为y + 1发送至服务器端。
  • welcome socket检查ack等于y + 1和ACK等于1后,创建新的socket,此socket由源IP/源端口、目标IP/目标端口标识,之后客户端发送的数据都被引导向此新的socket,至此,TCP连接建立。

简单来讲:

// client: 
send({SYN: 1, seq: x, ...others})
                    |
                    ↓
//server: 
send({SYN: 1, ACK: 1, ack: x + 1, seq: y, ...others})
                    |
                    ↓
//client: 
ack === x + 1 ? send({ACK: 1, SYN: 0, ack: y + 1, ...others}) : 'hehe'
                    |
                    ↓
//server: 
ack === y + 1 && ACK === 1 ? new Socket() : ''

SSL/TLS

如果启用了HTTPS进行加密,在使用TLS前还需要协商建立加密信道。

过程

  • 客户端:TCP连接建立之后,再以纯文本形式发送一些规格说明,随机数Random1,TLS协议版本,支持的加密套件列表,支持或希望使用的其他TLS选项。
  • 服务器:

    1. 取得TLS协议版本以备将来通信使用,从客户端提供的加密套件列表中选择一个,生成随机数Random2发送给客户端;
    2. 附上自己的证书,将响应发送给客户端;
    3. 同时,也可发送一个请求,要求客户端提供证书以及其他TLS扩展参数。
  • 客户端:

    1. 同上,可能会向服务器发送自己的证书。
    2. 客户端收到服务器的证书后,通过证书链关系从根CA(证书的签发机构)验证证书的合法性,验证通过后取出证书中的服务器公钥,生成随机数Random3,再用服务器公钥加密Random3(pre master key),发送给服务器;
    3. 告诉服务器可以开始加密透明信了;
    4. 客户端用三个随机数约定的加密方法生成对话密钥。将前面的握手信息生成完成摘要,使用对话密钥加密,发送告诉服务器我已完成握手。
    • 除了服务器公钥加密的新对称密钥外,所有的数据都是明文形式发送。
  • 服务器:

    • 用私钥解密出客户端发来的随机数,通过验证消息的MAC检测消息完整性,用相同的方式生成对话密钥
    • 解密客户端发送的完成报文,验证对话密钥是否正确。
    1. 告诉客户端,要开始加密了;
    2. 同样再返回给客户端一个加密的完成消息。
  • 客户端用它之前生成的对话密钥解密这条消息,确定对话密钥是否正确,正确则建立信道并且开始发送应用数据。

其中:

  • 对话密钥又可称为协商密钥
  • 对话密钥对称密钥,对称加解密速度很快。
  • 服务器公钥和私钥是非对称密钥,非对称加解密速度很慢。
  • 使用非对称加密生成可靠的对称密钥,使用对称密钥进行后续数据的加密。
  • 上述带序号报文可能一次发送,也可能分次连续发送。
  • SSL和TLS可以当作一个东西。
  • 服务器也可以不使用CA颁发的证书,而使用自己的证书。

优化

我们要对TCP和SSL/TLS握手耗时进行优化。有以下几个因素:

  • 数据往返延迟:主要受地理位置影响,使用较近的服务器进行数据传输会减少数据往返的时间,我们可以通过在不同的地区部署服务器(如:CDN,其也会用到DNS解析,可能在DNS解析阶段就完成了对客户端访问域名到距离最近的服务器的映射),将数据放到接近客户端的地方,可以减少网络往返时间。
  • 证书链:其实数据往返延迟优化不只是针对TCP握手阶段的,后续基于TCP的数据传输都会收益,如SSL/TLS握手和后续的请求响应。那么证书链是影响SSL/TLS握手的一个重要因素,证书链是服务器向客户端发送的证书内的信息,由站点证书、中间证书颁发机构的证书、根证书组成(比较类似DNS域名解析服务器之间的关系)。

    • 原因:

      1. TCP慢启动:由于TCP慢启动(为避免拥塞,TCP连接初始只能发送较少的分组,然后等待客户端确认,然后翻倍,经过几次往返直至到达阈值)和TLS/SSL握手数据发送一般位于TCP连接慢启动阶段的关系,证书数据过多会超过TCP连接的初始值,会造成数据往返次数的成倍增加。
      2. 证书链验证过长:由于客户端浏览器在验证证书可靠性时,会递归验证链条中的每个节点至根证书,也会增加握手时间。
    • 方法:

      1. 减少中间证书颁发机构的数量,优化至只有站点证书和一个中间证书颁发机构。
      2. 不要添加根证书信息,浏览器内置信任名单中有根证书。
  • 握手次数:前两点优化都是针对的握手时间的优化,握手次数也是影响延迟的重要因素。我们在后面谈到大量请求的时候再说这一点。
  • 初始拥塞窗口:适当增大初始拥塞窗口大小,即增大TCP连接初始可发送的分组大小。

3.获得页面响应

重定向响应

如果服务器返回了跳转重定向(非缓存重定向),那么浏览器端就会向新的URL地址重新走一遍DNS解析建立连接
所以应该避免不必要的重定向。

页面资源响应

在获得了html响应之后,浏览器开始解析页面,进入准备渲染的阶段。下载优化同样放在后面谈到大量请求的时候再说这一点。

4.解析渲染页面

我们需要将这个过程先分为两个部分来看,页面资源加载渲染

页面资源加载

浏览器在解析页面的过程中会去请求页面中诸如js、css、img等外联资源。

建立连接

同样这些资源的加载也是需要建立TCP连接的,直接使用也需要进行DNS解析和握手。

优化

此处的请求次数与频率相对于第一次请求页面资源时要高很多,所以这里着重阐述下成批量的请求的优化。

浏览器目前使用的HTTP协议版本大多是1.1和2,二者有些不同,但是底层都是使用TCP进行数据传输。由于TCP握手耗时,和SSL/TLS更加耗时,我们需要减少整个加载过程中需要建立的连接的次数和耗时。

  • 复用:针对HTTP1.1的最好方法是启用长连接:HTTP 1.1提供了默认开启长连接功能,相对于短连接(每请求一个资源建立然后断开一次TCP连接),同一客户端socket(浏览器可能会开多个端口并行请求)针对同一socket(域名+端口)后续请求都会复用一个TCP连接进行传输,直到关闭这个TCP连接。
  • 加速:针对SSL/TLS握手有会话恢复机制,验证通过后,可以直接使用之前的对话密钥,减少握手往返。

加载之前

在服务器返回响应时,又存在几种情况,如:服务器负载大,服务器宕机,无法及时或较快响应请求,服务器地理位置过远或跨运营商导致延迟很高。

优化

这里跟建立连接部分的优化其实是公用的,但是单纯的正常建立连接消耗资源较少,所以我们在这个再较完成的阐述一下。

  • 增加带宽:但是大部分情况下服务器带宽并不是影响延迟的主要因素。
  • 智能DNS解析:根据客户端的IP地址,将域名解析为最近的或不跨运营商的服务器的IP地址,解决地理位置和跨运营商的延迟问题。
  • CDN:使用某种分析方式根据节点服务器的地理位置、负载情况、资源匹配情况从遍布各地的节点服务器中找出最合适的静态资源服务器。
  • 负载均衡:使用DNS负载均衡、IP负载均衡、反向代理负载均衡等方式从一堆服务器(集群相同职责)或一组服务器(分布式职责区分)中选择最合适的服务器处理请求。
  • 这几种技术可能是相互结合的,比如CDN会用到DNS智能解析和负载均衡等。
  • 其中使用了跳转重定向方式的会重新进行DNS解析和握手,其中一部分优化实际是在域名的DNS解析部分完成的。

开始加载

好了,服务器终于可以愉快的返回数据了。

HTTP 1.1

过程

  • 虽然HTTP 1.1有长连接,一个TCP连接可以用来请求多个资源,但是这些资源的下载是串行的,比如使用这个TCP通道请求1.css、2.css、1.js,只有在前者传输成功完整完成后才会进行下一个的传输。
  • 虽然浏览器一般会请求建立多个TCP连接(多个端口向服务器一个端口请求资源,新的TCP连接的建立会进行新的握手),去并行的请求页面资源加快整体的下载速度,然而对每个域名的并行连接是有数量限制的(保护服务器负载,并受主机端口限制),所以我们还是要进行一些优化。

优化

  • 减少

    • 减少页面中需要发起的请求总数,如我们常规使用的代码合并,雪碧图(精灵图/Sprite合并小图标),将图片转为base64写入其他文件,避免空的img src属性等。
    • 切割拆分数据,让首屏数据优先加载等。
  • 增加:增加资源的分布域名,部署在不同域名下,“突破”浏览器并行连接限制(结合DNS部分,不易过于分散,且过多连接会共享带宽,且移动端的解析更加缓慢)。

HTTP 2

由于HTTP 2提供了多路复用的功能,基于二进制数据帧和流的传输,使通过一个TCP连接进行数据分散、乱序、并行传输成为现实,即我们所有的资源都可以通过一个TCP连接不阻塞的并行传输。
所以我们针对HTTP 1.1的减少请求数量所做的合并优化、增加资源分布域名都成为了无效优化,可以丢掉。同时由于文件不用合并,进行文件更新时我们也不用再修改单个开发模块更新所有(合并文件)模块了。

加载中

总的来说是很简单的过程,客户端接收服务器传输返回的响应。

优化

传输的数据大小越小,那么传输就越快,延迟就越小。

  • 更小

    • Gzip:启用Gzip可对响应体进行压缩,可减少70%大小的数据体积。
    • 减少cookie:去除不必要的cookie,设置合适过期时间。
    • 舍弃cookie:对于静态文件请求我们可以不要cookie,即HTTP1.1中提到的,分布在其他域名下,子域名设置合理的domian(cookie作用域)。
    • 首部压缩:HTTP2还提供了首部压缩功能,即通过双方共有的一些字典,将首部信息(状态行、请求/响应头)“映射”为更简短的数据。
    • 图片:使用合适的图片大小和图片格式,可以节省大小。
  • 缓存:小到最小的情况当然是不接受数据传输,使用本地缓存。一般使用服务器前一次返回的响应头部字段进行控制。

    • 强缓存:强缓存不会向服务器发送请求。

      • Expires:http1.0字段,使用服务器时间做标识。
      • Cache-Control:max-age=seconds,使用相对于请求的时间,不超过这个时长,直接使用缓存。还有其他的值。
    • 协商缓存:

      • Last-Modified/If-Modified-Since:资源最后修改时间,秒。浏览器客户端发送If-Modified-Since字段,服务器响应Last-Modified字段。
      • ETag/If-None-Match:资源的标识符,客户端发送If-None-Match字段,服务器响应ETag字段,并比较两者,决定返回缓存重定向还是其他,这个标识只比较内容,不关心资源时间。
  • 合理拆分页面资源,比如外联js和css就可以独立于html进行缓存。

关闭TCP

在资源下载完毕之后,需要关闭TCP连接。这段没有什么可以优化的。

过程:

  • TCP客户端发送一个FIN = 1(结束标志位)和随机数seq = a,用来关闭客户到服务器的数据传送。
  • 服务器收到这个关闭请求,返回ACK = 1 ,ack = a + 1,此时服务器之前的数据可能还没有传输完成。
  • 数据传输完成后,服务器发送一个FIN = 1和随机数seq = b给客户端。
  • 客户端返回ACK = 1,ack = b + 1,并等待一段时间,确保服务器没有返回没收到确认报文的重传申请,后关闭连接。
  • 服务器收到确认报文后,验证关闭连接。

总结

HTTP2 真好用。合理使用缓存。

页面解析渲染

上述的资源加载是发生在页面解析过程中的。那么浏览器的页面解析渲染是怎么样的一个过程呢?

过程

简要来讲就是:

  • 处理HTML标记,构建DOM树。
  • 处理CSS标记,构建CSSOM树。
  • 将DOM树和CSSOM树融合成渲染树(会忽略不需要渲染的dom)。
  • 根据渲染树来布局,计算每个节点的几何信息。
  • 在屏幕上绘制各个节点。
  • 中间遇到各种资源时,会进行资源的下载。

问题

  • 资源下载

    • css下载时会阻塞渲染(带有media属性除外)。
    • 遇到 script 标签时,DOM构建停止,此时控制权移交至js,直到脚本(下载)执行完毕,此时浏览器有优化一般会下载其他资源,但是不会解析。如果js中有对CSSOM的操作,还会先确保CSSOM已经被下载并构建。
    • 图片资源下载不会产生阻塞。
  • 重绘重排导致重新进行渲染树的生成

    • 重排(回流):会重新计算布局,通常由元素的结构、增删、位置、尺寸变化引起,如:img下载成功后,替换填充页面img元素,引起尺寸变化;也会由js的属性值读取引起,如读取offset、scroll、cilent、getComputedStyle等信息。
    • 重绘:简单外观的改变会引起重绘,如颜色变化等。
    • 重排一定重绘。

优化

  • dom

    • 简化dom结构,减少DOM树和渲染树构建成本,减少页面元素个数,如使用列表表格数据分页,简单表格不要使用复杂第三方组件等方式。
  • js

    • 将js脚本标签放在页面body底部,减少对其他过程的阻塞。
    • 延迟执行:对不修改页面的外链script使用defer属性,使脚本并行下载不阻塞,下载后不立刻执行,而在所有元素解析之后执行。
    • 减少和合并不必要的dom相关操作,如使用DocumentFragment、修改classname而不是各项style等,减少对重绘和重排的触发。
  • css

    • 将css放入head中,提前加载,并防止html渲染后重新结合css引起页面闪烁。
    • 减少css层级和css选择器复杂度,提高解析速度,虽然浏览器有优化。
    • 使用更高性能的css样式,如flex代替float。
    • 开启复合层,如使用3d变换、opacity等,使该元素及其子元素不导致外部的重排,但是也有坑
    • 合理使用脱离文档流的样式,减少对外部重排的影响,如absolute。
  • 文件数量

    • 减少首次下载的文件数量大小,使用图片懒加载,js的按需加载等方式,也可以节省用户流量,甚至使用storage存储进行js、css文件的缓存。
    • 拆分页面资源,首屏数据优先加载等。

5.其他优化措施

我们还可以采取一些和延迟、渲染无关的优化措施:

  • 使用PWA,让用户在没有得到数据时也能看到页面。
  • 对页面某些ajax请求数据进行storage存储。
  • 加载进度、骨架图、占位图等类似让用户感觉好一点的措施。
  • 及时更新升级服务器,优化措施依赖于服务器支持。
查看原文

赞 58 收藏 132 评论 1

范洋 回答了问题 · 2018-04-26

解决vue 传参数的问题

你应该看了v-router了吧,了解了编程式导航,如何从url中获取参数。根据ID请求数据是指你使用ajax或者axios向后台给你的某个接口发送请求的同时传入这个ID,然后返回什么数据由后台根据ID筛选,然后你得到数据写到页面上。模拟的话可以自己写个json数据,然后根据根据id匹配到数据。for循环。如截图,你可以写在一个json文件中,或者直接在js里面也行。要注意json对格式要求严格,如果有什么格式不对的都会报错。

clipboard.png

关注 4 回答 3

范洋 发布了文章 · 2018-04-26

如何把滑动条变好看一点

一直知道html5 input有个新类型range,可以有个滑动条的效果,但是感觉丑不拉几的,又不知道如何美化,所以一直没用过。最近在网上瞅了瞅,发现滑动条还是可以美化的,所以掏出来给大家摆摆~~

默认样式

首先写出一个滑动条,用法就像写一个输入框一样简单:

<input type="range">

没有美化的滑动条(谷歌)就是这样的:
默认样式

相信应该没人会选择直接用这个样式吧。

如何美化

其实可以把滑动条分为3块:滑块,滑轨,进度条。然后针对不同的块调整样式。大致步骤如下:

  1. 去除默认样式
    每个元素都是有自己默认样式的,有些样式不清除的话自定义的样式就不会生效。

       input[type=range]{
           -webkit-appearance: none;
           width: 300px;
           border-radius: 10px;
       }

    此处要说说这个 -webkit-appearance是个啥,该属性专门用于改变按钮和其他控件的外观。像button,input之类的有自己外观的就是默认有这个属性,当然span之类的是没有的。但是我们可以自己设置,比如span标签,默认下就是个文本,想要什么样式需要自己添加,这时如果你想给span一个按钮的样式,

       span{
           -webkit-appearance:button;
       }

    它能快速地把一些按钮的特效设置上去:
    按钮样式

    当然,这没有什么用处,非要把驴唇接到马嘴上是很奇怪的~
    还有滑块的默认样式:

       input[type=range]::-webkit-slider-thumb{   /*设置滑块*/
           -webkit-appearance:button;
       }

    轮廓线也要去掉:

       input[type=range]:focus{
           outline:none;
       }
  2. 给滑块设置样式

       input[type=range]::webkit-slider-thumb{
           -webkit-appearance: none;     //以下样式随个人喜好
           width: 25px;   
           height: 25px;
           margin-top: -5px;     //让滑轨在滑块中间
           cursor: pointer;
           border-radius: 50%;
           background: #DEF3F8;
           box-shadow: 0 0 10px #63A35C inset;    
       }
       

    滑块

  3. 给滑轨设置样式

       input[type=range]::-webkit-slider-runnable-track{   /*滑动条样式*/
           height: 15px;
           border-radius: 10px;
           border: 1px solid currentcolor;
       }
       

    滑轨

  4. 填充进度条
    作用两边随滑块变化长度,所以需要JS:

       $('input[type=range]').css('background','linear-gradient(to right, #63A35C 0%, #ccc 50%, antiquewhite)');
       $('input[type=range]').mousemove(function(){
           $(this).css('background','linear-gradient(to right, #63A35C 0%, #ccc ' + this.value + '%, antiquewhite)');
       })     //样式随心~

    然后样式就是这样的:
    结果

至于第五步就是兼容其它浏览器啦,在下这里就不介绍了,有兴趣的喷油可以看我学习的地址:

https://blog.csdn.net/u013347...

写后感

关于-webkit-appearance,::-webkit-slider-thumb,::-webkit-slider-runnable-track这些如果不是网上看到可能一直都不会知道有这么个属性可以设置o(╯□╰)o,看来还有很多东西有待探索啊~

查看原文

赞 7 收藏 7 评论 3

范洋 收藏了文章 · 2018-04-25

前端每日实战:2# 视频演示如何用纯 CSS 创作一个矩形旋转 loader 特效

图片描述

效果预览

按下右侧的“点击预览”按钮在当前页面预览,点击链接全屏预览。

https://codepen.io/zhang-ou/pen/vjLQMM

可交互视频教程

此视频是可以交互的,你可以随时暂停视频,编辑视频中的代码。

请用 chrome, safari, edge 打开观看。

https://scrimba.com/c/cJMkwH9

源代码下载

请从 github 下载。

https://github.com/comehope/front-end-daily-challenges/tree/master/002-rectangular-rotating-loader-animation

代码解读

定义 dom,一个包含 3 个 span 的容器:

<div class="loader">
    <span></span>
    <span></span>
    <span></span>
</div>

居中显示:

html, body {
    height: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
    background-color: black;
}

设置容器的尺寸:

.loader {
    width: 150px;
    height: 150px;
    position: relative;
}

设置矩形的边框样式:

.loader span {
    position: absolute;
    box-sizing: border-box;
    border: 10px solid dimgray;
    border-radius: 2px;
}

设置 3 个矩形的尺寸:

.loader span:nth-child(1) {
    width: 100%;
    height: 100%;
}

.loader span:nth-child(2) {
    width: 70%;
    height: 70%;
    margin: 15%;
}

.loader span:nth-child(3) {
    width: 40%;
    height: 40%;
    margin: 30%;
}

用伪元素绘制左上和右下的装饰条:

.loader span::before,
.loader span::after {
    content: '';
    position: absolute;
    width: 10px;
    height: 50%;
    background-color: gold;
}

.loader span::before {
    top: -10px;
    left: -10px;
}

.loader span::after {
    bottom: -10px;
    right: -10px;
}

定义动画效果:

@keyframes rotating {
    from {
        transform: rotateY(0deg);
    }

    to {
        transform: rotateY(360deg);
    }
}

把动画应用到 3 个矩形上:

.loader span {
    animation: rotating linear infinite;
}

.loader span:nth-child(1) {
    animation-duration: 4s;
}

.loader span:nth-child(2) {
    animation-duration: 2s;
}

.loader span:nth-child(3) {
    animation-duration: 1s;
}

最后,设置一下 3 个矩形的堆叠顺序:

.loader span:nth-child(1) {
    z-index: 3;
}

.loader span:nth-child(2) {
    z-index: 2;
}

.loader span:nth-child(3) {
    z-index: 1;
}

大功告成!

知识点

查看原文

认证与成就

  • 获得 28 次点赞
  • 获得 4 枚徽章 获得 0 枚金徽章, 获得 0 枚银徽章, 获得 4 枚铜徽章

擅长技能
编辑

开源项目 & 著作
编辑

(゚∀゚ )
暂时没有

注册于 2018-03-15
个人主页被 719 人浏览