Skip to content

Commit

Permalink
add: srcset support
Browse files Browse the repository at this point in the history
  • Loading branch information
hilongjw committed Dec 22, 2016
1 parent f2ada70 commit 6455a16
Show file tree
Hide file tree
Showing 5 changed files with 200 additions and 59 deletions.
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,12 @@ data: {
}
```
```html
<img v-lazy="'img.jpg'" />
<img v-lazy="'img.jpg'" srcset="img.400px.jpg 400w, img.800px.jpg 800w, img.1200px.jpg 1200w"/>


<img v-lazy="imgUrl" />
<img v-lazy="imgUrl" :srcset="imgUrl' + '?size=400 400w, ' + imgUrl + ' ?size=800 800w, ' + imgUrl +'/1200.jpg 1200w'" />
```

or Object
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "vue-lazyload",
"version": "1.0.0-rc6",
"version": "1.0.0-rc7",
"description": "Vue module for lazy-loading images in your vue.js applications.",
"main": "vue-lazyload.js",
"scripts": {
Expand Down
60 changes: 34 additions & 26 deletions src/lazy.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import Vue from 'vue'
import { remove, some, find, _, throttle, supportWebp, getDPR } from './util'
import { remove, some, find, _, throttle, supportWebp, getDPR, getBestSelectionFromSrcset } from './util'
import ReactiveListener from './listener'

const DEFAULT_URL = 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7'
Expand Down Expand Up @@ -30,13 +30,11 @@ export default class Lazy {
catIn = listener.checkInView()
catIn && listener.load()
})
}, 300)
}, 200)
}

addLazyBox (vm) {
console.log('got ',vm)
this.ListenerQueue.push(vm)

this.options.hasbind = true
this.initListen(window, true)
}
Expand All @@ -50,6 +48,12 @@ export default class Lazy {
let { src, loading, error } = this.valueFormatter(binding.value)

Vue.nextTick(() => {
let tmp = getBestSelectionFromSrcset(el, this.options.scale)

if (tmp) {
src = tmp
}

const container = Object.keys(binding.modifiers)[0]
let $parent

Expand All @@ -75,6 +79,7 @@ export default class Lazy {
this.options.hasbind = true
this.initListen(window, true)
$parent && this.initListen($parent, true)
this.lazyLoadHandler()
Vue.nextTick(() => this.lazyLoadHandler())
})
}
Expand All @@ -89,6 +94,8 @@ export default class Lazy {
loading,
error
})
this.lazyLoadHandler()
Vue.nextTick(() => this.lazyLoadHandler())
}

remove (el) {
Expand All @@ -109,29 +116,30 @@ export default class Lazy {
loading: [],
loaded: [],
error: []
},
$on (event, func) {
this.listeners[event].push(func)
},
$once (event, func) {
const vm = this
function on () {
vm.$off(event, on)
func.apply(vm, arguments)
}
this.$on(event, on)
},
$off (event, func) {
if (!func) {
this.listeners[event] = []
return
}
remove(this.listeners[event], func)
},
$emit (event, context) {
this.listeners[event].forEach(func => func(context))
}
}

this.$on = (event, func) => {
this.Event.listeners[event].push(func)
},
this.$once = (event, func) => {
const vm = this
function on () {
vm.$off(event, on)
func.apply(vm, arguments)
}
this.$on(event, on)
},
this.$off = (event, func) => {
if (!func) {
this.Event.listeners[event] = []
return
}
remove(this.Event.listeners[event], func)
},
this.$emit = (event, context) => {
this.Event.listeners[event].forEach(func => func(context))
}
}

elRenderer (data, state, notify) {
Expand All @@ -149,7 +157,7 @@ export default class Lazy {
el.setAttribute('lazy', state)

if (!notify) return
this.Event.$emit(state, data)
this.$emit(state, data)
this.options.adapter[state] && this.options.adapter[state](data, this.options)
}

Expand Down
61 changes: 60 additions & 1 deletion src/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,64 @@ function some (arr, fn) {
return has
}

function getBestSelectionFromSrcset (el, scale) {
if (el.tagName !== 'IMG' || !el.getAttribute('srcset')) return
let options = el.getAttribute('srcset')
const result = []
const container = el.parentNode
const containerWidth = container.offsetWidth * scale

let spaceIndex
let tmpSrc
let tmpWidth

options = options.trim().split(',')

options.map(item => {
item = item.trim()
spaceIndex = item.lastIndexOf(' ')
if (spaceIndex === -1) {
var tmpSrc = item
var tmpWidth = 999998
} else {
var tmpSrc = item.substr(0, spaceIndex)
var tmpWidth = parseInt(item.substr(spaceIndex + 1, item.length - spaceIndex - 2), 10)
}
result.push([tmpWidth, tmpSrc])
})

result.sort(function (a, b) {
if (a[0] < b[0]) {
return -1
}
if (a[0] > b[0]) {
return 1
}
if (a[0] === b[0]) {
if (b[1].indexOf('.webp', b[1].length - 5) !== -1) {
return 1
}
if (a[1].indexOf('.webp', a[1].length - 5) !== -1) {
return -1
}
}
return 0
})
let bestSelectedSrc = ''
let tmpOption
const resultCount = result.length

for (let i = 0; i < resultCount; i++) {
tmpOption = result[i]
if (tmpOption[0] >= containerWidth) {
bestSelectedSrc = tmpOption[1]
break
}
}

return bestSelectedSrc
}

function find (arr, fn) {
let item
for (let i = 0, len = arr.length; i < len; i++) {
Expand Down Expand Up @@ -118,5 +176,6 @@ export {
throttle,
supportWebp,
getDPR,
loadImageAsync
loadImageAsync,
getBestSelectionFromSrcset
}
Loading

0 comments on commit 6455a16

Please sign in to comment.