Skip to content
This repository was archived by the owner on Feb 22, 2021. It is now read-only.

Commit e10da51

Browse files
committed
feat(loader): add image loader
1 parent 7cf71c6 commit e10da51

File tree

7 files changed

+57
-16
lines changed

7 files changed

+57
-16
lines changed

examples/main.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,12 @@ document.title = 'hello'
44
const handler = async() => {
55
const backLoader = new BackLoader({
66
// scripts: ['https://code.jquery.com/jquery-3.2.1.slim.min.js'],
7-
pages: ['https://google.com'],
7+
// pages: ['https://google.com'],
8+
images: ['https://cn.bing.com/az/hprichbg/rb/BarHarborCave_ZH-CN8055769470_1920x1080.jpg'],
89
})
9-
backLoader.start().on(event => {
10-
console.log(event)
11-
})
10+
backLoader.start().on(event => {
11+
console.log(event)
12+
})
1213
}
1314

1415
;(() => window.onload = () => handler().then())()

src/core/loader.ts

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { EventHub } from './event'
22
import { LoaderEvent } from '../types'
3-
import { $fetch, filterResources } from '../utils/tools'
3+
import { $fetch, filterResources, listenImageLoad } from '../utils/tools'
44

55

66
export class Loader {
@@ -27,12 +27,24 @@ export class Loader {
2727
this.scripts(filterResources(html, 'script'))
2828
this.styles(filterResources(html, 'style'))
2929
})
30-
.catch((e) => {
31-
console.log(e)
30+
.catch(() => {
31+
this.emit(Object.assign({}, this.baseEvent, {
32+
type: 'page', source: url, success: false,
33+
}))
3234
})
3335
})
3436
}
3537

38+
images(urls: string[]): void {
39+
const imageElements: HTMLImageElement[] = urls
40+
.map(url => Object.assign(new Image(), { src: url }))
41+
listenImageLoad(imageElements, (url: string) => {
42+
this.emit(Object.assign({}, this.baseEvent, {
43+
type: 'image', source: url,
44+
}))
45+
})
46+
}
47+
3648
private loadURL(urls: string[], type: string): void {
3749
urls.forEach(url => {
3850
const scriptEvent = Object.assign({}, this.baseEvent, {

src/index.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,12 @@ export class BackLoader {
1515
start(): BackLoader {
1616
this.hub = new EventHub()
1717
const loader = new Loader(this.hub)
18-
const { scripts, styles, pages } = this.options
18+
const { scripts, styles, pages, images } = this.options
1919

2020
scripts && loader.scripts(scripts)
2121
styles && loader.styles(styles)
2222
pages && loader.pages(pages)
23+
images && loader.images(images)
2324
return this
2425
}
2526

src/types.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11

22
export type LoaderOptions = {
3-
pages?: string[]
4-
scripts?: string[]
5-
styles?: string[]
3+
pages?: string[],
4+
scripts?: string[],
5+
styles?: string[],
6+
images?: string[],
67
}
78

89
export type LoaderEvent = {

src/utils/check.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ const regs = {
55
page: /^http|^\/\//,
66
js: /(^http|^\/\/)\S+\.js$/,
77
css: /(^http|^\/\/)\S+\.css$/,
8+
img: /^http|^\/\//,
89
}
910

1011
export const pages = (pages: string[]): boolean => {
@@ -28,11 +29,19 @@ export const styles = (styles: string[]): boolean => {
2829
return true
2930
}
3031

32+
export const images = (images: string[]): boolean => {
33+
if (!Array.isArray(images)) return Log.options.imagesError()
34+
const unnormalLinks = images.filter(s => !regs.img.test(s))
35+
if (unnormalLinks && unnormalLinks.length) return Log.options.imagesError()
36+
return true
37+
}
38+
3139
export const options = (ops: LoaderOptions): boolean => {
3240
const checkResults: boolean[] = []
3341
ops.pages && checkResults.push(pages(ops.pages))
3442
ops.scripts && checkResults.push(scripts(ops.scripts))
3543
ops.styles && checkResults.push(styles(ops.styles))
44+
ops.images && checkResults.push(images(ops.images))
3645

3746
if (!checkResults.length) return Log.options.isEmpty()
3847
return !`${checkResults}`.includes('false')

src/utils/log.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,6 @@ export const options = {
88
pagesError: () => warning('options [pages] error.'),
99
scriptsError: () => warning('options [scripts] error.'),
1010
stylesError: () => warning('options [styles] error.'),
11+
imagesError: () => warning('options [images] error.'),
1112
isEmpty: () => warning('options is empty!'),
1213
}

src/utils/tools.ts

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,24 @@
1-
1+
// resource load use no-cors mode default
2+
// html load must use cors
23
export const $fetch = (url: string, init: RequestInit = {}) => {
34
return fetch(url, Object.assign({ mode: 'no-cors' }, init))
4-
.then(r => {
5-
console.log(r)
6-
return r.text()
7-
})
5+
.then(r => r.text())
86
}
97

8+
// like './images/xxx' or '../images'
109
export const isRelativeURL = (path: string) => {
1110
return path.startsWith('./') || path.startsWith('..')
1211
}
1312

13+
1414
export const makeResourceReg = (str: string): RegExp => {
1515
return {
1616
script: /\<script\s+\S?src\=\"([^"]*)\"/g,
1717
style: /\<link\s+\S?\s?href\=\"([^"]*.css)\"/,
1818
}[str]
1919
}
20+
21+
// find scripts and styles in html string
2022
export const filterResources = (source: string, type: string): string[] => {
2123
const reg: RegExp = makeResourceReg(type), arr: string[] = []
2224
let result: string[], num = 10
@@ -27,3 +29,17 @@ export const filterResources = (source: string, type: string): string[] => {
2729
}
2830
return arr
2931
}
32+
33+
export const listenImageLoad = (images: HTMLImageElement[], done: (url: string) => void)
34+
: void => {
35+
const isCompleted = (imgs: HTMLImageElement[]) => !imgs.length
36+
const timer: number = window.setInterval(() => {
37+
images = images.map(img => {
38+
if (!img.complete) return img
39+
done(img.src)
40+
return null
41+
})
42+
.filter(v => !!v)
43+
isCompleted(images) && clearInterval(timer)
44+
}, 300)
45+
}

0 commit comments

Comments
 (0)