图表懒加载插件实战

2016/07/28 · JavaScript
· 插件

本文作者: 伯乐在线 –
陈被单
。未经小编许可,禁绝转发!
应接参预伯乐在线 专栏撰稿人。

不胜枚举网址都会用到‘图片懒加载’这种措施对网址举办优化,即延迟加载图片或符合有个别原则才起来加载图片。于是灵机一动,决定本身手动写一下’图片懒加载‘插件。

  • 使用那么些技巧有哪些显明的帮助和益处?

举个例子叁个页面中有大多图形,如Tmall首页等等,三个页面有100多的图纸,纵然生龙活虎上来就发送这么多必要,页面加载就能够非常长久,借使js文件都献身了文书档案的最底层,恰巧页面包车型大巴头顶又借助那几个js文件,那就不佳办了。客商感到这一个页面就能够很卡。

  • 懒加载原理:浏览器会自动对页面中的img标签的src属性发送诉求并下载图片。通过动态改良img的src属性达成。

当访谈一个页面包车型大巴时候,先把img成分或是别的因素的背景图片路径替换到loading图片地址(那样就只需供给一回)

等到早晚原则(这里是页面滚动到自然区域),用实际寄存img地址的laze-load属性的值去替换src属性,就能够兑现’懒加载’。

//尽管img的src值为空,浏览器也会对服务器发送央浼。所以平日做项目标时候,若是img未有行使src,就不用现身src这一个本性

  • 先上几个至关主要的知识点

1.获得显示屏可视窗口大小:

document.documentElement.clientHeight 规范浏览器及低版本IE标准情势

document.body.clientHeight 低版本混杂形式

2.元素相对于文档document顶端

element.offsetTop

3.滚动条滚动的相距

document.documentElement.scrollTop   包容ie低版本的正规化形式

document.body.scrollTop 宽容混合情势;

滚动加载:当图片现身在可视区域时,动态加载该图片。

原理:当图片成分顶上部分是还是不是在可视区域内,(图片相对于文书档案document顶上部分-滚动条滚动的间距)

实现原理:

1.率先从具备相关因素中寻觅要求延时加载的要素,放在element_obj数组中。

JavaScript

function initElementMap() { var el =
document.getElementsByTagName(‘img’); for (var j = 0, len2 = el.length;
j < len2; j++) { //剖断当前的img是或不是加载过了,恐怕有lazy_src标志
[未完成] if (typeof (el[j].getAttribute(“lazy_src”))) {
element_obj.push(el[j]); download_count++; } } }

1
2
3
4
5
6
7
8
9
10
function initElementMap() {
      var el = document.getElementsByTagName(‘img’);
      for (var j = 0, len2 = el.length; j < len2; j++) {
  //判断当前的img是否加载过了,或者有lazy_src标志  [未完成]
          if (typeof (el[j].getAttribute("lazy_src"))) {
              element_obj.push(el[j]);
              download_count++;
          }
      }
}

2.论断数组中的img对象,若满意条件,则改动src属性

JavaScript

function lazy() { if (!download_count) return; var innerHeight =
getViewport(); for (var i = 0, len = element_obj.length; i < len;
i++) { //得到图片相对document的距上偏离 var t_index =
getElementViewTop(element_obj[i]); if (t_index – getScrollTop() <
innerHeight) { element_obj[i].src =
element_obj[i].getAttribute(“lazy-src”); delete element_obj[i];
download_count–; } } }

1
2
3
4
5
6
7
8
9
10
11
12
13
function lazy() {
    if (!download_count) return;
    var innerHeight = getViewport();
    for (var i = 0, len = element_obj.length; i < len; i++) {
//得到图片相对document的距上距离
        var t_index = getElementViewTop(element_obj[i]);    
        if (t_index – getScrollTop() < innerHeight) {
            element_obj[i].src = element_obj[i].getAttribute("lazy-src");
            delete element_obj[i];
            download_count–;
        }
    }
}

3.轮转的时候接触事件,1000微秒后实践lazy()方法。

JavaScript

window.onscroll = window.onload = function () { setTimeout(function () {
lazy(); }, 1000) }

1
2
3
4
5
window.onscroll = window.onload = function () {
    setTimeout(function () {
        lazy();
    }, 1000)
}

整片段代码位于闭包自试行函数中。相应的点子放在init中。

JavaScript

var lazyLoad = (function () { function init() { initElementMap();
lazy(); }; return { init: init } })();

1
2
3
4
5
6
7
8
9
var lazyLoad = (function () {  
    function init() {
        initElementMap();
        lazy();
    };
    return {
        init: init    
    }
})();

采纳格式
:src填暗中同意loading图片地址,真实的图样地址填在lazy-src属性里,切记需点名宽高。在外界调用
 lazyLoad.init();

 全部的代码以至例子已经上传到github上了,地址是:,欢迎star。

打赏协助自身写出越来越多好随笔,感激!

打赏笔者

钻探前端黑科学和技术——通过 png 图的 rgba 值缓存数据

2016/09/12 · JavaScript
· 1 评论 ·
缓存

初藳出处: jrainlau   

谈起前端缓存,超过伍分一个人想到的独自是多少个常规的方案,比方cookielocalStoragesessionStorage,只怕加上indexedDBwebSQL,以及manifest离线缓存。除此而外,到底还大概有未有其他艺术能够拓宽前端的多少缓存呢?那篇小说将会带你一同来查究,怎么着一步一步地因此png图的rgba值来缓存数据的黑科学技术之旅。

CSS进级:试试光彩夺目的 3D 视角

2016/09/08 · CSS · 1
评论 ·
3D,
CSS

本文小编: 伯乐在线 –
chokcoco
。未经小编许可,防止转发!
接待参预伯乐在线 专辑作者。

写那篇小说的来由是因为看见了这些页面:

戳笔者看看(移动端页面,使用模拟器阅览)

接收 CSS3 实现的 3D
视角,尽管有局地晕3D,可是使人投身于当中的交互体验感到那多少个棒,运用在移动端制作一些
H5 页面可谓十二分博人眼球。

同一时候精通规律之后营造起来也并不算废力,好好的研讨了风流洒脱番后将部分学学进程分享给大家。

下边步入正文:(一些 Gif 图片相当的大,要求等待一会)

打赏援助自己写出更加多好作品,多谢!

任选意气风发种支付方式

图片 1
图片 2

3 赞 11 收藏
评论

原理

我们了然,通过为静态能源设置Cache-ControlExpires响应头,能够反逼浏览器对其张开缓存。浏览器在向后台发起倡议的时候,会先在本身的缓存里面找,若是缓存里面没有,才会延续向服务器伏乞这么些静态财富。利用那一点,大家得以把一些内需被缓存的新闻透过这么些静态能源缓存机制来展打开饭店储。

那么大家怎么样把音信写入到静态财富中呢?canvas提供了.getImageData()方法和.createImageData()办法,能够独家用于读取设置图片的rgba值。所以我们可以动用那多个API实行消息的读写操作。

接下去看规律图:

图片 3

当静态财富踏入缓存,以往的任何对于该图片的伏乞都会先物色本地缓存,也正是说新闻实际早就以图纸的花样被缓存到地方了。

注意,由于rgba值只好是[0,
255]里头的整数,所以本文所讨论的章程仅适用于纯数字组成的数额。

3D 效果暗中提示

盛名比不上一见,先直观后感想受一下上述作者所说的效应:

See the Pen 3DView by Chokcoco
(@Chokcoco) on
CodePen.

最棒能点步入看看,这里笔者动用了带背景象的 div
作为示范,大家的观点处于三个正方体中,正方体的转动动画让大家有了 3D
的以为。

那便是说原本的图长什么样呢?大家把间隔拉远,后生可畏探毕竟:

See the Pen 3DView2 by
Chokcoco (@Chokcoco) on
CodePen.

是长这么的:

图片 4

相较于第生龙活虎种意义,其实所做的只是将咱们的见解推进到了正方体个中,有了后生可畏种身临其景的感到。

而客观的应用 CSS3 所提供的有的 3D 属性,相当轻易就会落得上述的功效。

制作那样三个 3D
图形,作者在头里的稿子已经很详细的描述了经过,感兴趣的能够戳进去看看:

【CSS3晋级】炫丽的3D旋转透视

至于小编:陈被单

图片 5

热爱前端,招待沟通
个人主页 ·
笔者的篇章 ·
19 ·
  

图片 6

静态服务器

我们应用node搭建三个简易的静态服务器:

JavaScript

const fs = require(‘fs’) const http = require(‘http’) const url =
require(‘url’) const querystring = require(‘querystring’) const util =
require(‘util’) const server = http.createServer((req, res) => { let
pathname = url.parse(req.url).pathname let realPath = ‘assets’ +
pathname console.log(realPath) if (realPath !== ‘assets/upload’) {
fs.readFile(realPath, “binary”, function(err, file) { if (err) {
res.writeHead(500, {‘Content-Type’: ‘text/plain’}) res.end(err) } else {
res.writeHead(200, { ‘Access-Control-Allow-Origin’: ‘*’,
‘Content-Type’: ‘image/png’, ‘ETag’: “666666”, ‘Cache-Control’: ‘public,
max-age=31536000’, ‘Expires’: ‘Mon, 07 Sep 2026 09:32:27 GMT’ })
res.write(file, “binary”) res.end() } }) } else { let post = ”
req.on(‘data’, (chunk) => { post += chunk }) req.on(‘end’, () => {
post = querystring.parse(post) console.log(post.imgData)
res.writeHead(200, { ‘Access-Control-Allow-Origin’: ‘*’ }) let
base64Data = post.imgData.replace(/^data:image\/\w+;base64,/, “”) let
dataBuffer = new Buffer(base64Data, ‘base64’)
fs.writeFile(‘assets/out.png’, dataBuffer, (err) => { if (err) {
res.write(err) res.end() } res.write(‘OK’) res.end() }) }) } })
server.listen(80) console.log(‘Listening on port: 80’)

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
43
44
45
46
47
48
49
50
51
52
53
54
55
const fs = require(‘fs’)
const http = require(‘http’)
const url = require(‘url’)
const querystring = require(‘querystring’)
const util = require(‘util’)
 
const server = http.createServer((req, res) => {
  let pathname = url.parse(req.url).pathname
  let realPath = ‘assets’ + pathname
  console.log(realPath)
  if (realPath !== ‘assets/upload’) {
     fs.readFile(realPath, "binary", function(err, file) {
      if (err) {
        res.writeHead(500, {‘Content-Type’: ‘text/plain’})
        res.end(err)
      } else {
        res.writeHead(200, {
          ‘Access-Control-Allow-Origin’: ‘*’,
          ‘Content-Type’: ‘image/png’,
          ‘ETag’: "666666",
          ‘Cache-Control’: ‘public, max-age=31536000’,
          ‘Expires’: ‘Mon, 07 Sep 2026 09:32:27 GMT’
        })
        res.write(file, "binary")
        res.end()
      }
   })
  } else {
    let post = ”
    req.on(‘data’, (chunk) => {
      post += chunk
    })
    req.on(‘end’, () => {
      post = querystring.parse(post)
      console.log(post.imgData)
      res.writeHead(200, {
        ‘Access-Control-Allow-Origin’: ‘*’
      })
      let base64Data = post.imgData.replace(/^data:image\/\w+;base64,/, "")
      let dataBuffer = new Buffer(base64Data, ‘base64’)
      fs.writeFile(‘assets/out.png’, dataBuffer, (err) => {
        if (err) {
          res.write(err)
          res.end()
        }
        res.write(‘OK’)
        res.end()
      })
    })
  }
})
 
server.listen(80)
 
console.log(‘Listening on port: 80’)

本条静态财富的效应很简短,它提供了四个功能:通过顾客端传来的base64生成图片并保留到服务器;设置图片的缓存时间并发送到顾客端。

最主要部分是设置响应头:

JavaScript

res.writeHead(200, { ‘Access-Control-Allow-Origin’: ‘*’,
‘Content-Type’: ‘image/png’, ‘ETag’: “666666”, ‘Cache-Control’: ‘public,
max-age=31536000’, ‘Expires’: ‘Mon, 07 Sep 2026 09:32:27 GMT’ })

1
2
3
4
5
6
7
res.writeHead(200, {
  ‘Access-Control-Allow-Origin’: ‘*’,
  ‘Content-Type’: ‘image/png’,
  ‘ETag’: "666666",
  ‘Cache-Control’: ‘public, max-age=31536000’,
  ‘Expires’: ‘Mon, 07 Sep 2026 09:32:27 GMT’
})

咱俩为那张图纸设置了一年的Content-Type和十年的Expires,理论上充分长了。上边大家来举行顾客端的coding。

transform-style 与 perspective

再轻松复述一下,首若是选拔到了多个 CSS 属性:

客户端

XHTML

<!– client.html –> <canvas id=”canvas” width=”8″,
height=”1″></canvas>

1
2
3
<!– client.html –>
 
<canvas id="canvas" width="8", height="1"></canvas>

假如大家要求仓库储存的是三十一位的数目,所以大家为canvas设置宽度为8,中度为1。到底为何三十二位数据对应长度为8,是因为每一种像素都有三个rgba,对应着redgreenbluealpha4个数值,所以要求除以4。

JavaScript

<!– client.js –> let keyString =
‘01234567890123456789012345678901’ let canvas =
document.querySelector(‘#canvas’) let ctx = canvas.getContext(‘2d’) let
imgData = ctx.createImageData(8, 1) for (let i = 0; i <
imgData.data.length; i += 4) { imgData.data[i + 0] =
parseInt(keyString[i]) + 50 imgData.data[i + 1] =
parseInt(keyString[i + 1]) + 100 imgData.data[i + 2] =
parseInt(keyString[i + 2]) + 150 imgData.data[i + 3] =
parseInt(keyString[i + 3]) + 200 } ctx.putImageData(imgData, 0, 0)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<!– client.js –>
 
let keyString = ‘01234567890123456789012345678901’
        
let canvas = document.querySelector(‘#canvas’)
let ctx = canvas.getContext(‘2d’)
 
let imgData = ctx.createImageData(8, 1)
 
for (let i = 0; i < imgData.data.length; i += 4) {
    imgData.data[i + 0] = parseInt(keyString[i]) + 50
    imgData.data[i + 1] = parseInt(keyString[i + 1]) + 100
    imgData.data[i + 2] = parseInt(keyString[i + 2]) + 150
    imgData.data[i + 3] = parseInt(keyString[i + 3]) + 200
}
 
ctx.putImageData(imgData, 0, 0)

首先大家只要须求被缓存的字符串为三十六个人的01234567890123456789012345678901,然后大家运用.createImageData(8, 1)变迁多个白手的imgData对象。接下来,我们对这么些空对象开展赋值。为了尝试效果进一步直观,大家对rgba值都进行了加大。设置完了imgData以后,通过.putImageData()主意把它放入大家的canvas就能够。

我们几这段时间得以打字与印刷一下,看看这些imgData是什么:

JavaScript

// console.log(imgData.data) [50, 101, 152, 203, 54, 105, 156, 207, 58,
109, 150, 201, 52, 103, 154, 205, 56, 107, 158, 209, 50, 101, 152, 203,
54, 105, 156, 207, 58, 109, 150, 201]

1
2
3
// console.log(imgData.data)
 
[50, 101, 152, 203, 54, 105, 156, 207, 58, 109, 150, 201, 52, 103, 154, 205, 56, 107, 158, 209, 50, 101, 152, 203, 54, 105, 156, 207, 58, 109, 150, 201]

接下去,大家要把这么些canvas编写翻译为一张图片的base64并发送给服务器,同一时间吸取服务器的响应,对图纸伸开缓存:

JavaScript

$.post(”, { imgData: canvas.toDataURL() },
(data) => { if (data === ‘OK’) { let img = new Image()
img.crossOrigin = “anonymous” img.src = ”
img.onload = () => { console.log(‘完毕图片央浼与缓存’)
ctx.drawImage(img, 0, 0) console.log(ctx.getImageData(0, 0, 8, 1).data)
} } })

1
2
3
4
5
6
7
8
9
10
11
12
$.post(‘http://xx.xx.xx.xx:80/upload’, { imgData: canvas.toDataURL() }, (data) => {
    if (data === ‘OK’) {
        let img = new Image()
        img.crossOrigin = "anonymous"
        img.src = ‘http://xx.xx.xx.xx:80/out.png’
        img.onload = () => {
            console.log(‘完成图片请求与缓存’)
            ctx.drawImage(img, 0, 0)
            console.log(ctx.getImageData(0, 0, 8, 1).data)
        }
    }
})

代码比较粗略,通过.toDataURL()方式把base64发送到服务器,服务器管理后生成图片并重返,其图片财富地址为http://xx.xx.xx.xx:80/out.png。在img.onload后,其实图片就曾经变成了本土缓存了,大家在这里个事件当中把图片消息打字与印刷出来,作为和源数据的对照。

transform-style

要动用 CSS3 达成 3D 的功用,最关键的正是借助 transform-style 属性。

transform-style 只有七个值能够选取:

// 语法: transform-style: flat|preserve-3d; transform-style: flat; //
私下认可,子成分将不保留其 3D 地方 transform-style: preserve-3d; //
子成分将保留其 3D 地方。

1
2
3
4
5
// 语法:
transform-style: flat|preserve-3d;
transform-style: flat; // 默认,子元素将不保留其 3D 位置
transform-style: preserve-3d; // 子元素将保留其 3D 位置。

当父成分设置了 transform-style:preserve-3d 后,就可以对子成分举办 3D
变形操作了,3D 变形和 2D 变形相似能够,使用 transform
属性来安装,或然能够经过制订的函数大概经过三个维度矩阵来对元素变型操作:当我们钦定叁个容器的
transform-style 的属性值为 preserve-3d 时,容器的遗族成分便会持有 3D
效果,那样说稍稍抽象,也正是最近父容器设置了 preserve-3d
值后,它的子元素就可以相对于父成分所在的平面,实行 3D 变形操作。

  • 行使 translateX(length) 、translateY(length) 、 translateZ(length)
    来拓宽 3D 位移操作,与 2D 操作相符,对成分实行活动操作,也足以统豆蔻梢头为
    translate3d(x,y,z) 这种写法;
  • 行使 scaleX() 、scaleY() 、scaleY() 来开展3D 缩放操作,也足以统大器晚成为
    scale3d(number,number,number) 这种写法;
  • 采取 rotateX(angle) 、rotateY(angle) 、rotateZ(angle) 来展开 3D
    旋转操作,也足以统大器晚成为 rotate3d(Xangle,Yangle,Zangle) 这种写法。

发表评论

电子邮件地址不会被公开。 必填项已用*标注