Full Code of verlok/vanilla-lazyload for AI

master 5123ea8e1ed1 cached
216 files
868.7 KB
224.7k tokens
9 symbols
1 requests
Download .txt
Showing preview only (913K chars total). Download the full file or copy to clipboard to get everything.
Repository: verlok/vanilla-lazyload
Branch: master
Commit: 5123ea8e1ed1
Files: 216
Total size: 868.7 KB

Directory structure:
gitextract_cukr4pm0/

├── .babelrc
├── .eslintignore
├── .eslintrc.json
├── .gitattributes
├── .github/
│   ├── CONTRIBUTING.md
│   ├── ISSUE_TEMPLATE/
│   │   ├── bug_report.md
│   │   ├── feature_request.md
│   │   └── support-request.md
│   └── workflows/
│       ├── ci.yml
│       └── playwright.yml
├── .gitignore
├── .prettierrc
├── .vscode/
│   └── settings.json
├── CHANGELOG.md
├── CODE_OF_CONDUCT.md
├── LICENSE
├── README.md
├── UPGRADE.md
├── _config.yml
├── bower.json
├── currentFeature.md
├── demos/
│   ├── async.html
│   ├── async_multiple.html
│   ├── background_images.html
│   ├── background_images_image-set.html
│   ├── background_images_multi.html
│   ├── container_multiple.html
│   ├── container_single.html
│   ├── dynamic_content.html
│   ├── dynamic_content_nodeset.html
│   ├── embedded.html
│   ├── error_no_restore.html
│   ├── error_restore.html
│   ├── esm.html
│   ├── fade_in.html
│   ├── hundreds.html
│   ├── iframes/
│   │   ├── i01.html
│   │   ├── i02.html
│   │   └── i03.html
│   ├── iframes.html
│   ├── image_basic.html
│   ├── image_hidden.html
│   ├── image_no_classes.html
│   ├── image_ph_external.html
│   ├── image_ph_inline.html
│   ├── image_srcset.html
│   ├── image_srcset_lazy_sizes.html
│   ├── image_srcset_sizes.html
│   ├── images/
│   │   ├── 220x280-01.avif
│   │   ├── 220x280-02.avif
│   │   ├── 220x280-03.avif
│   │   ├── 220x280-04.avif
│   │   ├── 220x280-05.avif
│   │   ├── 220x280-06.avif
│   │   ├── 220x280-07.avif
│   │   ├── 220x280-08.avif
│   │   ├── 220x280-09.avif
│   │   ├── 220x280-10.avif
│   │   ├── 220x280-11.avif
│   │   ├── 220x280-12.avif
│   │   ├── 220x280-13.avif
│   │   ├── 220x280-14.avif
│   │   ├── 220x280-15.avif
│   │   ├── 220x280-16.avif
│   │   ├── 220x280-17.avif
│   │   ├── 220x280-18.avif
│   │   ├── 220x280-19.avif
│   │   ├── 220x280-20.avif
│   │   ├── 220x280-21.avif
│   │   ├── 220x280-22.avif
│   │   ├── 220x280-23.avif
│   │   ├── 220x280-24.avif
│   │   ├── 220x280-25.avif
│   │   ├── 220x280-26.avif
│   │   ├── 220x280-27.avif
│   │   ├── 220x280-28.avif
│   │   ├── 220x280-29.avif
│   │   ├── 220x280-30.avif
│   │   ├── 220x280-31.avif
│   │   ├── 220x280-32.avif
│   │   ├── 220x280-33.avif
│   │   ├── 220x280-34.avif
│   │   ├── 220x280-35.avif
│   │   ├── 220x280-36.avif
│   │   ├── 220x280-37.avif
│   │   ├── 220x280-38.avif
│   │   ├── 220x280-39.avif
│   │   ├── 220x280-40.avif
│   │   ├── 440x560-01.avif
│   │   ├── 440x560-02.avif
│   │   ├── 440x560-03.avif
│   │   ├── 440x560-04.avif
│   │   ├── 440x560-05.avif
│   │   ├── 440x560-06.avif
│   │   ├── 440x560-07.avif
│   │   ├── 440x560-08.avif
│   │   ├── 440x560-09.avif
│   │   ├── 440x560-10.avif
│   │   ├── 440x560-11.avif
│   │   ├── 440x560-12.avif
│   │   ├── 440x560-13.avif
│   │   ├── 440x560-14.avif
│   │   ├── 440x560-15.avif
│   │   ├── 440x560-16.avif
│   │   ├── 440x560-17.avif
│   │   ├── 440x560-18.avif
│   │   ├── 440x560-19.avif
│   │   ├── 440x560-20.avif
│   │   ├── 440x560-21.avif
│   │   ├── 440x560-22.avif
│   │   ├── 440x560-23.avif
│   │   ├── 440x560-24.avif
│   │   ├── 440x560-25.avif
│   │   ├── 440x560-26.avif
│   │   ├── 440x560-27.avif
│   │   ├── 440x560-28.avif
│   │   ├── 440x560-29.avif
│   │   ├── 440x560-30.avif
│   │   ├── 440x560-31.avif
│   │   ├── 440x560-32.avif
│   │   ├── 440x560-33.avif
│   │   ├── 440x560-34.avif
│   │   ├── 440x560-35.avif
│   │   ├── 440x560-36.avif
│   │   ├── 440x560-37.avif
│   │   ├── 440x560-38.avif
│   │   ├── 440x560-39.avif
│   │   └── 440x560-40.avif
│   ├── lazily_load_lazyLoad.html
│   ├── lazy_functions.html
│   ├── load.html
│   ├── load_all.html
│   ├── native_lazyload.html
│   ├── native_lazyload_conditional.html
│   ├── object.html
│   ├── picture_media.html
│   ├── picture_type_avif.html
│   ├── popup_layer.html
│   ├── print.html
│   ├── restore_destroy.html
│   ├── sliders_css_only.html
│   ├── swiper.html
│   ├── thresholds.html
│   ├── video.html
│   └── video_autoplay.html
├── dist/
│   ├── esm/
│   │   ├── autoInitialize.js
│   │   ├── callback.js
│   │   ├── cancelOnExit.js
│   │   ├── class.js
│   │   ├── constants.js
│   │   ├── counters.js
│   │   ├── data.js
│   │   ├── defaults.js
│   │   ├── dom.js
│   │   ├── elementStatus.js
│   │   ├── environment.js
│   │   ├── event.js
│   │   ├── forEachSource.js
│   │   ├── intersectionHandlers.js
│   │   ├── intersectionObserver.js
│   │   ├── lazyload.js
│   │   ├── load.js
│   │   ├── native.js
│   │   ├── online.js
│   │   ├── originalAttributes.js
│   │   ├── reset.js
│   │   ├── restore.js
│   │   ├── set.js
│   │   ├── tempImage.js
│   │   └── unobserve.js
│   ├── lazyload.iife.js
│   └── lazyload.js
├── funding.yml
├── jest.config.cjs
├── package.json
├── playwright.config.js
├── rollup.config.mjs
├── src/
│   ├── autoInitialize.js
│   ├── callback.js
│   ├── cancelOnExit.js
│   ├── class.js
│   ├── constants.js
│   ├── counters.js
│   ├── data.js
│   ├── defaults.js
│   ├── dom.js
│   ├── elementStatus.js
│   ├── environment.js
│   ├── event.js
│   ├── forEachSource.js
│   ├── intersectionHandlers.js
│   ├── intersectionObserver.js
│   ├── lazyload.js
│   ├── load.js
│   ├── native.js
│   ├── online.js
│   ├── originalAttributes.js
│   ├── reset.js
│   ├── restore.js
│   ├── set.js
│   ├── tempImage.js
│   └── unobserve.js
├── tests/
│   ├── e2e/
│   │   ├── background_image.spec.js
│   │   ├── background_image_multi.spec.js
│   │   └── image_basic.spec.js
│   └── unit/
│       ├── cancelOnExit.test.js
│       ├── lib/
│       │   ├── expectExtend.js
│       │   └── getFakeInstance.js
│       ├── load.test.js
│       ├── originalAttributes.test.js
│       ├── reset.test.js
│       ├── restore.test.js
│       └── set.test.js
├── todo.md
├── typings/
│   └── lazyload.d.ts
└── utils/
    └── index.html

================================================
FILE CONTENTS
================================================

================================================
FILE: .babelrc
================================================
{
  "ignore": ["node_modules/**"],
  "presets": [["@babel/env", { "modules": false }]],
  "env": {
    "test": {
      "presets": ["@babel/preset-env"]
    }
  }
}


================================================
FILE: .eslintignore
================================================
dist/**/*.js

================================================
FILE: .eslintrc.json
================================================
{
	"parserOptions": {
		"ecmaVersion": 6,
		"sourceType": "module"
	},
	"env": {
		"browser": true,
		"jest": true
	},
	"rules": {
		"quotes": [2, "double"],
		"block-scoped-var": 1,
		"class-methods-use-this": 1,
		"complexity": 1,
		"consistent-return": 1,
		"curly": 2,
		"default-case": 1,
		"dot-location": 1,
		"dot-notation": 1,
		"eqeqeq": 2,
		"guard-for-in": 1,
		"no-alert": 1,
		"no-caller": 1,
		"no-case-declarations": 1,
		"no-div-regex": 1,
		"no-else-return": 1,
		"no-empty-function": 1,
		"no-empty-pattern": 1,
		"no-eq-null": 1,
		"no-eval": 1,
		"no-extend-native": 1,
		"no-extra-bind": 1,
		"no-extra-label": 1,
		"no-fallthrough": 1,
		"no-floating-decimal": 1,
		"no-global-assign": 1,
		"no-implicit-coercion": 0,
		"no-implicit-globals": 1,
		"no-implied-eval": 1,
		"no-invalid-this": 1,
		"no-iterator": 1,
		"no-labels": 1,
		"no-lone-blocks": 1,
		"no-loop-func": 1,
		"no-magic-numbers": [1, { "ignore": [-1, 0, 1] }],
		"no-multi-spaces": 1,
		"no-multi-str": 1,
		"no-new": 1,
		"no-new-func": 1,
		"no-new-wrappers": 1,
		"no-octal": 1,
		"no-octal-escape": 1,
		"no-param-reassign": 1,
		"no-proto": 1,
		"no-redeclare": 1,
		"no-restricted-properties": 1,
		"no-return-assign": 1,
		"no-return-await": 1,
		"no-script-url": 1,
		"no-self-assign": 1,
		"no-self-compare": 1,
		"no-sequences": 1,
		"no-throw-literal": 1,
		"no-unmodified-loop-condition": 1,
		"no-unused-expressions": 1,
		"no-unused-labels": 1,
		"no-useless-call": 1,
		"no-useless-concat": 1,
		"no-useless-escape": 1,
		"no-useless-return": 1,
		"no-void": 1,
		"no-warning-comments": 1,
		"no-with": 1,
		"prefer-promise-reject-errors": 1,
		"radix": 1,
		"require-await": 1,
		"vars-on-top": 1,
		"wrap-iife": 1,
		"yoda": 1
	}
}


================================================
FILE: .gitattributes
================================================
# Auto detect text files and perform LF normalization
* text=auto

# Custom for Visual Studio
*.cs     diff=csharp
*.sln    merge=union
*.csproj merge=union
*.vbproj merge=union
*.fsproj merge=union
*.dbproj merge=union

# Standard to msysgit
*.doc  diff=astextplain
*.DOC  diff=astextplain
*.docx diff=astextplain
*.DOCX diff=astextplain
*.dot  diff=astextplain
*.DOT  diff=astextplain
*.pdf  diff=astextplain
*.PDF  diff=astextplain
*.rtf  diff=astextplain
*.RTF  diff=astextplain

================================================
FILE: .github/CONTRIBUTING.md
================================================
Thank you for taking the time to contribute!

To report a bug or request an enhancement or a feature, use the [issues page](https://github.com/verlok/vanilla-lazyload/issues) on github

If you just want to show your appreciation for this script, how about [buying a coffee](https://ko-fi.com/verlok) to its author?

If you want to contribute actively with your own code, please:

1. fork the repo on your namespace
2. open a new branch
3. develop your contribution on the branch
4. create a pull request towards this repo

I recommend to do **one pull request per feature** to make sure your contribution is easy to review and accept.

Thank you and... may the force be with you!


================================================
FILE: .github/ISSUE_TEMPLATE/bug_report.md
================================================
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: 'TYPE: Bug'
assignees: ''

---

**Describe the bug**
A clear and concise description of what the bug is.

**To Reproduce**
Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error

**Expected behavior**
A clear and concise description of what you expected to happen.

**LazyLoad version**
Please report which version of LazyLoad you're using.
- Version [e.g. 8.x.x, 10.x.x, 11.x.x]

**Desktop (please complete the following information):**
 - OS: [e.g. iOS]
 - Browser [e.g. chrome, safari]
 - Version [e.g. 22]

**Smartphone (please complete the following information):**
 - Device: [e.g. iPhone6]
 - OS: [e.g. iOS8.1]
 - Browser [e.g. stock browser, safari]
 - Version [e.g. 22]

**Screenshots**
If applicable, add screenshots to help explain your problem.

**Additional context**
Add any other context about the problem here.


================================================
FILE: .github/ISSUE_TEMPLATE/feature_request.md
================================================
---
name: Feature request
about: Suggest an idea for this project
title: ''
labels: 'TYPE: Enhancement'
assignees: ''

---

**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]

**Describe the solution you'd like**
A clear and concise description of what you want to happen.

**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.

**Additional context**
Add any other context or screenshots about the feature request here.


================================================
FILE: .github/ISSUE_TEMPLATE/support-request.md
================================================
---
name: Support request
about: Ask a question or support
title: ''
labels: 'TYPE: Question'
assignees: ''

---

**Is your support request related to a problem? Please describe.**
A clear and concise description of what the problem is.

**To Reproduce**
Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error

**Expected behavior**
A clear and concise description of what you expected to happen.

**LazyLoad version**
Please report which version of LazyLoad you're using.
- Version [e.g. 8.x.x, 10.x.x, 11.x.x]

**Desktop (please complete the following information):**
 - OS: [e.g. iOS]
 - Browser [e.g. chrome, safari]
 - Version [e.g. 22]

**Smartphone (please complete the following information):**
 - Device: [e.g. iPhone6]
 - OS: [e.g. iOS8.1]
 - Browser [e.g. stock browser, safari]
 - Version [e.g. 22]

**Screenshots**
If applicable, add screenshots to help explain your problem.

**Additional context**
Add any other context about the problem here.


================================================
FILE: .github/workflows/ci.yml
================================================
name: Node.js CI

on:
  - push
  - pull_request

jobs:
  build:

    runs-on: ${{ matrix.os }}

    strategy:
      matrix:
        node-version: [lts/*, latest]
        os: [ubuntu-latest, macos-latest, windows-latest]
        # See supported Node.js release schedule at https://nodejs.org/en/about/releases/

    steps:
      - uses: actions/checkout@v4
      - name: Use Node.js ${{ matrix.node-version }}
        uses: actions/setup-node@v4
        with:
          node-version: ${{ matrix.node-version }}
          cache: 'npm'

      - run: npm install

      - run: npm run build --if-present

      - run: npm run test:unit


================================================
FILE: .github/workflows/playwright.yml
================================================
name: Playwright Tests
on:
  push:
    branches: [main, master, develop, "feature/**"]
  pull_request:
    branches: [main, master]
jobs:
  test:
    timeout-minutes: 60
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: lts/*
      - name: Install dependencies
        run: npm ci
      - name: Install Playwright Browsers
        run: npx playwright install --with-deps
      - name: Run Playwright tests
        run: npx playwright test
      - uses: actions/upload-artifact@v4
        if: always()
        with:
          name: playwright-report
          path: playwright-report/
          retention-days: 30


================================================
FILE: .gitignore
================================================
Thumbs.db
ehthumbs.db

Desktop.ini

$RECYCLE.BIN/

*.cab
*.msi
*.msm
*.msp

.DS_Store
.AppleDouble
.LSOverride

Icon

._*

.Spotlight-V100
.Trashes

.AppleDB
.AppleDesktop
Network Trash Folder
Temporary Items
.apdisk

.idea

node_modules

_site
.sass-cache

/test-results/
/playwright-report/
/blob-report/
/playwright/.cache/

coverage

================================================
FILE: .prettierrc
================================================
{
  "tabWidth": 2,
  "useTabs": false,
  "printWidth": 100,
  "trailingComma": "none"
}


================================================
FILE: .vscode/settings.json
================================================
{
  "editor.codeActionsOnSave": {
    "source.fixAll.eslint": "explicit"
  },
  "editor.tabSize": 4,
  "editor.defaultFormatter": "esbenp.prettier-vscode"
}

================================================
FILE: CHANGELOG.md
================================================
# CHANGELOG

## Version 19

#### 19.1.3

- File `CHANGELOG.md` is now included in the package and installed along with it
- Updated Babel, Rollup and Playwright to the latest versions

#### 19.1.2

- Modernized code and smaller file bundles, everything is now shipped as in the ES2015 format.

#### 19.1.1

- Removed code to support image-set on legacy versions of Chromium browsers
- Added coverage with 2 more demos for images with single src and a placeholder image

#### 19.1.0

- Added end to end tests to expand test coverage to more use cases and cross browser

#### 19.0.5

- Removed `.eslintrc.json`, `LICENSE`, `CHANGELOG.md`, `CODE_OF_CONDUCT.md`, `README.md`, `package.json` from the package files, as they didn't have any impact on [code quality](https://docs.npmjs.com/searching-for-and-choosing-packages-to-download#quality).

#### 19.0.4

- Removed Babel plugin to polyfill `Object.assign()`, as suggested in #611.

#### 19.0.3

- Files `.eslintrc.json`, `LICENSE`, `CHANGELOG.md`, `CODE_OF_CONDUCT.md`, `README.md`, `package.json` are now included in the package

#### 19.0.1

- Restored compatibility for bundlers that used this module, see #609

#### 19.0.0

- Rollup setup enhancement 
  - Refactored the Rollup setup to improve performance and maintainability.
  - Switched to ES6 module format for better compatibility and readability.
  - Enabled tree shaking and module preservation to optimize the build output.
- Added [ESM demo](demos/esm.html) to showcase the functionality of the esm module.
- Updated various dependencies to their latest versions for better compatibility and security
- Removed AMD module from the `/dist` folder, as it's been unused since version 11
- Removed AMD-related demos

## Version 18

#### 18.0.0

- **Dropped support for Internet Explorer 11**
- Modernized code
- Smaller file

## Version 17

#### 17.9.0

- Allowing to pass empty string (`""`) as value for class options (`class_loading`, `class_applied`, `class_loaded`, `class_error`, `class_entered`, `class_exited`) so that no DOM mutation will happen if not necessary. This is a potential performance improvement. Suggested in [#605](https://github.com/verlok/vanilla-lazyload/issues/605).

#### 17.8.8

- Fixed dependency issues detected by `npm audit`

#### 17.8.5

- Improved callbacks check by introducing type check (must be `function`)

#### 17.8.4

- Updated link to demos in the documentation.

#### 17.8.3

- Fixed `callback_error` in background images demos, like suggested in #573. Thanks to @Soul244.

#### 17.8.2

- Fixed a bug which occurred if the network connection went off and on again after a LazyLoad instance was destroyed

#### 17.8.1

- Updated Typescript typings

#### 17.8.0

- Added the ability to lazyload background images with CSS `image-set()` via `data-bg-set`.

#### 17.7.0

- Added the new option `restore_on_error` to restore original attributes on error.

#### 17.6.1

- Removed nasty "debugger" from code (sorry about that rookie mistake!)

#### 17.6.0

- Added ability to lazily load the `<object>` tag, as requested in #177. Useful to lazily load animated SVGs.

#### 17.5.1

- Updated Typescript typings

#### 17.5.0

- Added the ability to restore DOM to its original state through the `restoreAll()` method.
- Destroy demo became [restore and destroy demo](demos/restore_destroy.html)

#### 17.4.0

- Adding native lazy loading for videos, as discussed in #527. Thanks to @saschaeggi.
- Updated the `native_lazyload_conditional.html` demo with the new best practice for cross browser native lazy loading.

#### 17.3.2

- Fixes double trigger of `callback_load` after a watched image was loaded using the static `load()` method (#526). Thanks to @nick-vincent.

#### 17.3.1

- Removed `caniuse-lite` from dependencies. Fixes #505. Thanks to @ar53n.

#### 17.3.0

- Added `class_entered` and `class_exited` options to apply a class when an element entered and/or exited the viewport

#### 17.2.0

- Rolling back the "`data` attribute cleanup" feature that was released on 16.1.0 and was causing issues like [#484](https://github.com/verlok/vanilla-lazyload/issues/484) when more than one instance of LazyLoad were working on the same elements of the page - the script is also 500 bytes lighter now

#### 17.1.3

- Added missing types (#480), thanks to @ar53n (#482)

#### 17.1.2

- Fixed TypeScript typings (#475), thanks to @ar53n (#477)

#### 17.1.1

- Fixing npm audit vulnerabilities

#### 17.1.0

- Unobserve all elements on `loadAll()` call. It's better for performance, and it solves #469.
- Added some hidden images in the `load_all.html` demo

#### 17.0.1

- Bug fix: `callback_exit()` was not being called on non-image elements (#468).

#### 17.0.0

- The `elements_selector` option now defaults to  `.lazy` (was `img`)
- The `cancel_on_exit` option now defaults to `true` (was `false`)

See [UPGRADE.md](UPGRADE.md) to understand **if** you are impacted by any breaking change and **how** to upgrade from previous versions.

---

**Love this project? 😍 [Buy me a coffee!](https://ko-fi.com/verlok)**

---

## Version 16

#### 16.1.0

Improved speed, cleaning DOM, better working destroy, and also fixed 2 bugs.

- Cleaning up `data` attributes from the DOM when finished using them (mainly when elements have finished loading)
- Improved `destroy` method, which now also removes lazyload's additions to the DOM elements
- Video elements are now only listening to the `loadeddata` event, no longer to `load`
- Removed constants containing strings. I thought it would produced shorter minified code, but discovered that terser expands them to strings.
- Bugfix: when lazily loading videos, the error `_poster_ is undefined` was thrown
- Bugfix: when selecting native lazy loading, the `loading` class was added without knowing whether or not the loading had started

#### 16.0.0

Functional changes:

- Removed call to deprecated `callback_reveal`
- Removed deprecated instance `load()` method in favor of the static `LazyLoad.load()` method
- Replaced `auto_unobserve` with `unobserve_completed`, still defaulting to `true`
- Introduced a new `unobserve_entered` option (useful to execute lazy functions once)
- Created a demo called `lazy_functions.html` to show how to execute functions as elements enter the viewport
- Wrote a new recipe to facilitate the lazy execution of scripts/functions
- Renamed instance method `resetElementStatus()` to the static `LazyLoad.resetStatus()`
- Removed the `load_delay` option since there's no more use for it
- Removed the `load_delay` related demos

See [UPGRADE.md](UPGRADE.md) to understand **if** you are impacted by any breaking change and **how** to upgrade from previous versions.

Internal changes:

- Simplified management of the `cancel_on_exit` with less increase/decrease of the `toLoadCount` property
- Refactored counters functions in a new `lazyload.counters` file

---

**Love this project? 😍 [Buy me a coffee!](https://ko-fi.com/verlok)**

---

## Version 15

#### 15.2.0

OPTIMIZE FOR SLOW CONNECTIONS WITH `cancel_on_exit`

Want to optimize speed for users who scroll down fast on a slow connection? Just set `cancel_on_exit: true` and LazyLoad will cancel the download of images exiting the viewport while still loading, eventually restoring the original attributes.

- Introduced the new `cancel_on_exit` option.
- Introduced the `callback_cancel` option, just in case you want to perform any additional action whenever a download gets canceled by `cancel_on_exit`.
- Created a new demo named `cancel_on_exit.html` so you can try the new `cancel_on_exit` option live.
- Set `cancel_on_exit` to `true` in the following demos, so you can test how it behaves...
  - `image_ph_inline.html`, with an inline SVG placeholder
  - `image_ph_external.html`, with an external SVG placeholder
  - `delay_test.html`, in conjuction with the `delay_load` option
  - `fade_in.html`, with a beautiful fade-in effect.

The `cancel_on_exit` option applies only to images so to the `img` (and `picture`) tags. It doesn't work for background images, `iframe`s nor `video`s.

The `cancel_on_exit` option will probably default to `true` starting from the next major version, so give it a try! And please report your feedback in the comments of [#438](https://github.com/verlok/vanilla-lazyload/issues/438).

API

- Added the `resetElementStatus()` method for when you need to tell LazyLoad to consider an image (or other DOM element) again. This is particularly useful if you change the `data-src` attribute after the previous `data-src` was loaded). See the [API section](README.md#-api) in the README file for more information.

FIX

- The `callback_exit` callback was called several times (for every images out of the viewport) at instance creation or upon `update()` calls. Now the callback is properly called only when any element exits the viewport.

INTERNALS

- Improved script performance by reducing the number of event listeners used for loading elements.
- Changed the values that the (internally used) `data-ll-status` attribute can take. Removed the status `"observed"` (it was useless) and introduced status `"delayed"`.

#### 15.1.1

Fixed a bug when loading lazy background images on HiDPI screens, `data-bg-hidpi` was mandatory, not it fallbacks to `data-bg`. #430

#### 15.1.0

Lazy background images just gained support for hiDPI ("retina") screens!
Place your standard resolution images in the `data-bg` attribute and your hiDPI images in `data-bg-hidpi`.
Same for `data-bg-multi` and `data-bg-multi-hidpi`.

#### 15.0.0

**Lazy background images gained loaded/error classes and callbacks! 🎉**

**Breaking changes impacting lazy background images!** ⚠ See [UPGRADE.md](UPGRADE.md) to understand **if** you are impacted and **how** to upgrade from previous versions.

- Lazy loading of **one background image** using the `data-bg` attribute, now manages the `load` and `error` events, so they are applied the classes defined in the `class_loading`/`class_loaded`/`class_error`, and the callbacks defined in `callback_loading`/`callback_loaded`/`callback_error`.
- Lazy loading of **multiple background images** is still possible via the `data-bg-multi` attribute. In this case, the `load` and `error` events are not managed. The `class_applied` and `callback_applied` can be used to understand when the multiple background was applied to the element.
- Updated background images demos:
  - background-images.html -> single background images
  - background-images-multi.html -> multiple background images
- Added [UPGRADE.md](UPGRADE.md), a guide on how to upgrade from previous versions (from version 12 up)

---

**Love this project? 😍 [Buy me a coffee!](https://ko-fi.com/verlok)**

---

## Version 14

#### 14.0.1

Fixed error TS1036: Statements are not allowed in ambient contexts. Closes #427

#### 14.0.0

🎉 **Major refactoring and performance improvement!**
🔍 File size stays tiny: only 2.07 KB gZipped

**Settings**

- `callback_loading` is called when an element started loading
- `callback_reveal` is now **⚠ DEPRECATED, use `callback_loading` instead** (it's the same thing, it was just renamed). `callback_reveal` will be removed and will stop working in version 15.

**Instance methods**

- `update()` method now **also unobserves deleted elements**, instead of just looking for and observing new elements
- `destroy()` **destroys better** than it did before, `delete`-ing properties instead of setting their values to `null`
- `load()` method (as an instance method) is now **⚠ DEPRECATED, use the static method instead**. If you were using `aLazyLoadInstance.load(element)` you should change it to `LazyLoad.load(element, settings)`.

**Static methods**

- `load()` was added as a static method. Note that if you need to use custom settings, you need to pass them in the `settings` parameter.

**Instance properties**

- Added `toLoadCount`. It's the counter of the elements that haven't been lazyloaded yet.

**DOM**

- Removed the `data-was-processed` attribute, that was added to mark lazy DOM elements as "already managed". If you were manually handling that attribute to obtain some goal, this is a potentially breaking change. You should now refer to the `data-ll-status` instead.
- Added the `data-ll-status` attribute, which is now used to mark the status of a lazy DOM element. The values it can take are: `observing` (not loaded yet), `loading` (loading started), `loaded` (load completed), `error` (an error has occured), `native` (similar to `observing`, but managed by native lazy loading).

---

**Love this project? 😍 [Buy me a coffee!](https://ko-fi.com/verlok)**

---

## Version 13

#### 13.0.1

- Fixed a JS error that could happen to IE11 users after going offline and back online
- Minor refactoring for better readibility and lighter code (and files)!

#### 13.0.0

- Added the minified version of `dist/lazyload.esm.js` as `dist/lazyload.esm.min.js`, so now you can effortlessly use it with an ES module `import` statement when using `type="module"`
- Reduced files weight even more! `dist/lazyload.iife.min.js` now weights only 2.03 KB GZipped
- Removed the `callback_set` callback that was **deprecated** since version 11 in favour of `callback_reveal`
- Removed sourcemaps (they were probably used only by the authors, but if anyone was actually needing them, we can bring them back)
- Hidden the `_extends` function inside LazyLoad's scope (it was global before)
- Updated build tooling: removed Gulp, now using Rollup & Babel only

## Version 12

#### 12.5.1

Restored IE 11 compatibility, which was broken since 12.2.0. See #414.
Thanks to @ninosaurus for reporting.

#### 12.5.0

The once-private `_loadingCount` property is now public and renamed to `loadingCount`. This property contains the number of images that are currently downloading from the network, limitedly to the ones managed by an instance of LazyLoad. This is particularly useful to understand whether or not is safe to destroy an instance of LazyLoad. See implementation in the [destroy demo](demos/destroy.html).

Thanks to @wzhscript and @eugene-stativka.

#### 12.4.0

Video `poster`s can now be loaded lazily, as requested in #365

#### 12.3.0

Callbacks now pass more arguments!

`callback_enter`, `callback_exit` now pass:

1. the DOM element that entered / exited the viewport
2. the `IntersectionObserverEntry` that triggered the enter/exit event
3. the LazyLoad instance

`callback_load`, `callback_error`, `callback_reveal` now pass

1. the DOM element that entered / exited the viewport
2. the LazyLoad instance

`callback_finish` now passes:

1. the LazyLoad instance

The README file has been updated accordingly.

#### 12.2.0

Released new feature "retry when back online". Now if your users lose the internet connection causing errors on images loading, this script tries and loads those images again when the connection is restored.

#### 12.1.1

Solved a bug with Internet Explorer 11 and the W3C polyfill, as reported in #383.

#### 12.1.0

- Updated npm dev dependencies
- Added the new `image_ph_inline.html`, with an inline SVG placeholder
- Added the new `image_ph_external.html`, with an external SVG placeholder

#### 12.0.3

Updated the IntersectionObserver polyfill to version 0.7.0

#### 12.0.2

Improved detection of browser support of IntersectionObserver, as suggested in #362. Thanks to @kaldonir

#### 12.0.1

Updated CHANGELOG.md and README.md to mention the change of the option name `callback_load` which is called `callback_loaded` in versions 11.0.0 and above.

#### 12.0.0

- Reorganized code
- Improved native lazy loading demos
- Aligned console messages throughout all demos.

#### 12.0.0-beta.0

- Added the `use_native` option which enables _native lazy loading_ (where supported) with the `loading="lazy"` attribute. See #331
- Added two demos:
  - native_lazyload_conditional.html which you can use to test the `use_native` option
  - native_lazyload.html which always uses native lazy loading (without JS) just to test how it works beyond the LazyLoad script
- Refactored the constructor and the `update` method

## Version 11

#### 11.0.6

Restored the `callback_set` callback as **deprecated**, in order to make the upgrade from v.10 easier.

#### 11.0.5

Fixed the `module` property of this package.json, which was pointing to a non-existing dist file.

#### 11.0.4

Fixed the `main` property of this package.json, which was pointing to a non-existing dist file.

#### 11.0.3

Rollback of the patch applied in 11.0.2 since it gave strange results in some cases. See #293. Thanks to @davejamesmiller for the analysis and the report.

#### 11.0.2

Applied a patch to resolve #293 a [Chromium bug](https://bugs.chromium.org/p/chromium/issues/detail?id=910741#c13) already fixed in Chrome 72. Thanks to @dverbovyi for the analysis and the report.

#### 11.0.1

Squashed a nasty bug that occurred on IE 11 and Safari when the `IntersectionObserver` polyfill wasn't loaded before LazyLoad.

#### 11.0.0

- Changed bundle file name of ES Module from `lazyload.es2015.js` to `lazyload.esm.js`
- Removed the `to_webp` option (see issue #288)
- Ceased support and development of LazyLoad v.8 (see issue #306)
  version. If you were using it, please update your code to use `callback_reveal` instead.
- Private methods like `_setObserver`, `_onIntersection` etc. are now hidden from the outside.
- Added the `auto_unobserve` boolean option, see API.
- Bugfix: `loadAll()` didn't unobserve elements.
- Updated to Jest 24, Babel 7, etc.
- Fixed dev dependencies vulnerabilities
- Updated callbacks. See below:

Callbacks updated:

- **Changed** `callback_enter`. This callback is now called whenever an element enters the viewport, even when `load_delay` is set. In previous versions, this callback was delayed until an element started loading if a `load_delay` was set. Note that this is a **possible breaking change**, which you can fix using `callback_reveal` instead.
- **Renamed** `callback_loaded` is the new name of `callback_load`.
- **Added** `callback_exit`. This callback is called whenever an element exits the viewport, even if a `load_delay` is set.
- **Added** `callback_reveal`. This callback is called just after an element starts loading.
- **Deprecated** `callback_set`. This callback still works\*, but will be removed in the next major

\* it didn't work from versions 11.0.0 to 11.0.5, it still works from 11.0.6.

## Version 10

#### 10.20.1

Fixed a bug for which LazyLoad didn't copy the `data-sizes` attribute value to `sizes` in `source` tags inside `picture`. See #307.

#### 10.20.0

Improved WebP detection to work correctly on Firefox too, see #298.

Thanks to @ipernet for contributing.

#### 10.19.1

- Fixed build for those using React + SSR, see #287
- TypeScript definitions clearified, see #283
- Gulp updated to v.4.0.0 to make it work with node 10

Thanks to @AlexCSR and @muturgan for contributing.

#### 10.19.0

- Added the ability to know when all images have been downloaded through the `callback_finish` callback.
- Added the file `demos/print.html` to demo how to print lazy images.

#### 10.18.0

Added the ability to have multiple background images, through the new `data_bg` option.

#### 10.17.0

Added the ability to set different thresholds for the scrolling area, through the new `thresholds` option.

#### 10.16.2

**BUGFIX**: Class `loaded` was not applied to a loaded video (issue #239).

#### 10.16.1

**BUGFIX**: Autoplaying video not loaded correctly after entering the viewport (issue #240). Thanks to @maeligg.

#### 10.16.0

Added new option `load_delay` to skip loading when fast scrolling occurs, as requested in issues #235 and #166.
Pass in a number of milliseconds, and each image will be loaded after it stayed inside that viewport for that time.

#### 10.15.0

- Refactorized code & improved script performance
- **BUGFIX**: Fixed webpack import (issue #230) `TypeError: default is not a constructor`

#### 10.14.0

Now supporting WebP through dynamic extension rename if the user browser is compatible.

#### 10.13.0

- Shortened the RegEx for crawlers detection (shaved a few bytes)
- Released LazyLoad in new module types! Enjoy the new flavours :)

| Filename               | Module Type                                    | Advantages                                                         |
| ---------------------- | ---------------------------------------------- | ------------------------------------------------------------------ |
| `lazyload.min.js`      | UMD (Universal Module Definition)              | Works pretty much everywhere, even in common-js contexts           |
| `lazyload.iife.min.js` | IIFE (Immediately Invoked Function Expression) | Works as in-page `<script src="">`, ~0.5kb smaller minified        |
| `lazyload.amd.min.js`  | AMD (Asynchronous Module Definition)           | Works with the _require.js_ module loader, ~0.5kb smaller minified |
| `lazyload.es2015.js`   | ES Module type                                 | Exports `LazyLoad` so you can import it in your project            |

#### 10.12.0

SEO! Expanded SEO-friendliness to more crawlers, Bingbot included.

#### 10.11.1

**BUGFIX**: Fixed issue #225. Due to mistyped BOT detection, in version 10.11.0 all images were loaded as soon as `LazyLoad` was created.

#### 10.11.0

SEO! Version 10.x is now as SEO-friendly as version 8.x.

#### 10.10.0

Added a public `load` method to lazyload any element.

#### 10.9.0

Added the ability to lazily set the `sizes` attribute via a `data-sizes` attribute.
See the [README](README.md) file for more information.

#### 10.8.0

Added a public `loadAll` method to loading all the images at once, as asked in #193.

#### 10.7.0

- Added support for the `<video>` HTML tag and descending `<source>` tags.
  Now you can lazily load your videos too!
- Created the `video.html` demo.

#### 10.6.0

- Added a demo with a popup layer and images injected after popup open, to help with #196.
- Updated the `background_images` demo with a custom management of the loading class and the loaded event callback.

#### 10.5.2

Added a security check on lazy elements' parents.

#### 10.5.1

Just a refactoring over previous version.

#### 10.5.0

Added node support by merging pull request #188, "node-support" by @klarstrup.

With these changes in place, simply importing vanilla-lazyload without using it won't crash Node by itself. This is important for isomorphic/universal/server rendered setups where the same code runs on both the server and the browser.

#### 10.4.2

Fixed a bug for which sometimes images wouldn't reveal on Chrome 65 (see issue #165).

#### 10.4.1

Updated `dist` folder.

#### 10.4.0

Added the `callback_enter` callback, which is called whenevery any element managed by LazyLoad enters the viewport, as requested in #159. Thanks to @alvarotrigo.

#### 10.3.6

Fixed tests to match dataset revert made in 10.3 and 8.2 (oopsy).

#### 10.3.5

Fixed a bug that could occur on older versions of IE when trying to access an image's parent node.

#### 10.3.4

Fixed a CustomEvent bug which occurred on IE when using async object initialization.

#### 10.3.3

Fixed `supportsClassList` test to work even when the `document` object isn't yet there. Thanks to @Spone and his pull request #145.

#### 10.3.1

Introduced a workaround for an issue of Microsoft Edge documented [here](https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/12156111/)

#### 10.3.0

Restored support to IE9 and IE10, as requested in #118 and #132.

#### 10.2.0

To solve cases when you can't select the elements to load using a string, added the ability to pass a `NodeList` object...

- as a second parameter in the constructor, after the regular option object, e.g. `var ll = new Lazyload({}, myNodeList)`
- as a single parameter to the `update()` method, e.g. `ll.update(myNodeList)`

#### 10.1.0

To solve cases when you can't select the elements to load using a string, added the ability to pass a `NodeList` object to the `elements_selector` option, as suggested by @SassNinja in #130.

#### 10.0.1

Solved a problem with cdnjs.com: version 10.0.0 was pointing to 9.0.0.

#### 10.0.0

- Change in default options:
  - default for `data_src` is now `src` (was `original`)
  - default for `data_srcset` is now `srcset` (was `original-set`)

## Version 9

#### 9.0.1

- Restored tests using Jest
- Squashed a bug which didn't make images inside `picture` load correctly

#### 9.0.0

LazyLoad is now _faster_ thanks to the [Intersection Observer API](https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API).

**IMPORTANT!** Browser support changed. Find more information in the [README](README.md) file.

## Version 8

#### 8.17.0

- Added the ability to know when all images have been downloaded through the `callback_finish` callback.
- Added the file `demos/print.html` to demo how to print lazy images.

#### 8.16.0

Added the ability to have multiple background images, through the new `data_bg` option.

#### 8.15.2

**BUGFIX**: Class `loaded` was not applied to a loaded video (issue #239).

#### 8.15.1

**BUGFIX**: Autoplaying video not loaded correctly after entering the viewport (issue #240). Thanks to @maeligg.

#### 8.15.0

- Refactorized code & improved script performance
- **BUGFIX**: Fixed webpack import (issue #230) `TypeError: default is not a constructor`

#### 8.14.0

Now supporting WebP through dynamic extension rename if the user browser is compatible.

#### 8.13.0

- Shortened the RegEx for crawlers detection (shaved a few bytes)
- Released LazyLoad in new module types! Enjoy the new flavours :)

| Filename               | Module Type                                    | Advantages                                                         |
| ---------------------- | ---------------------------------------------- | ------------------------------------------------------------------ |
| `lazyload.min.js`      | UMD (Universal Module Definition)              | Works pretty much everywhere, even in common-js contexts           |
| `lazyload.iife.min.js` | IIFE (Immediately Invoked Function Expression) | Works as in-page `<script src="">`, ~0.5kb smaller minified        |
| `lazyload.amd.min.js`  | AMD (Asynchronous Module Definition)           | Works with the _require.js_ module loader, ~0.5kb smaller minified |
| `lazyload.es2015.js`   | ES Module type                                 | Exports `LazyLoad` so you can import it in your project            |

#### 8.12.0

SEO! Expanded SEO-friendliness to more crawlers, Bingbot included.

#### 8.11.0

Added a public `load` method to lazyload any element.

#### 8.10.0

Added the ability to lazily set the `sizes` attribute via a `data-sizes` attribute.
See the [README](README.md) file for more information.

#### 8.9.0

Added a public `loadAll` method to load all the images, as asked in #193.

#### 8.8.0

Added support for the `video` tag. Closes #209.
Created the `video.html` demo.

#### 8.7.1

Added a security check on lazy elements' parents.

#### 8.7.0

Added node support by merging pull request #188, "node-support" by @klarstrup.

With these changes in place, simply importing vanilla-lazyload without using it won't crash Node by itself. This is important for isomorphic/universal/server rendered setups where the same code runs on both the server and the browser.

#### 8.6.0

Added the `callback_enter` callback, which is called whenevery any element managed by LazyLoad enters the viewport, as requested in #159. Thanks to @alvarotrigo.

#### 8.5.2

Fixed a bug that could occur on older versions of IE when trying to access an image's parent node.

#### 8.5.1

Fixed a CustomEvent bug which occured on IE when using async object initialization.

#### 8.5.0

- Change in default options, in order to be aligned with version 10
  - default for `data_src` is now `src` (was `original`)
  - default for `data_srcset` is now `srcset` (was `original-set`)

#### 8.2.1

Fixed `supportsClassList` test to work even when the `document` object isn't yet there. Thanks to @Spone and his #145.

#### 8.2.0

Restored support to IE9 and IE10, as requested in #118 and #132.

#### 8.1.0

Updated from grunt to gulp (run with gulp scripts).

#### 8.0.3

Added quotes in background image URLs, as suggested in #114 (thanks to @vseva).

#### 8.0.2

Fixed a bug that affected performance.

#### 8.0.1

Fixed reference to old names in demo files.

#### 8.0.0

- The main file to include is now **`dist/lazyload.min.js`** as you would expect, and no longer `dist/lazyload.transpiled.min.js`.
- The non-transpiled version is now named lazyload.es2015.js

## Version 7

#### 7.2.0

- Now using `element.dataset` to read data attributes
- New readme! New website!

Bug fixes:

- Fixed #87

**IMPORTANT!** Browser support changed. Find more information in the [README](README.md) file.

#### 7.1.0

- Refactored code now using more modules
- Saving ~0.5 kb of transpiled code going back from ES2015 `class` to function's `prototype`

#### 7.0.0

Source code converted to ES2015 modules, bundled with [rollup.js](https://rollupjs.org/) and transpiled with [babel](https://babeljs.io/).

## Version 6

#### 6.3.x

Added the class initial to all images (or iframes) inside the viewport at the moment of script initialization

#### 6.2.x

- Added the ability to load LazyLoad using an async script

#### 6.1.x

SEO improvements for lazily loaded images

#### 6.0.x

- Source code migrated to ES6 / ES2015
- Serving both minified ES6 version and minified transpiled-to-ES5 version

## Version 5

- Exposed private functions for test coverage
- Test coverage

## Version 4

- Lighter constructor
- Performance improvements
- Bugfix: null on background images
- Removed code for legacy browsers - now supporting IE10+

## Version 3

- Added support to the picture tag
- Removed the "show image only when fully loaded" mode
  - Dumped the show_while_loading and placeholder options

## Version 2

- Added support to lazily load iframes and background images
- Added error management callback and error class option
- Performance improvements

## Version 1

- Added support to the srcset attribute for images
- Added typescript typings + updated dist folder files
- Performance improvements
- Stable release of LazyLoad

---

_Want more detail? Take a look at the [release history](https://github.com/verlok/vanilla-lazyload/releases) on GitHub_!


================================================
FILE: CODE_OF_CONDUCT.md
================================================
# Contributor Covenant Code of Conduct

## Our Pledge

In the interest of fostering an open and welcoming environment, we as
contributors and maintainers pledge to making participation in our project and
our community a harassment-free experience for everyone, regardless of age, body
size, disability, ethnicity, sex characteristics, gender identity and expression,
level of experience, education, socio-economic status, nationality, personal
appearance, race, religion, or sexual identity and orientation.

## Our Standards

Examples of behavior that contributes to creating a positive environment
include:

* Using welcoming and inclusive language
* Being respectful of differing viewpoints and experiences
* Gracefully accepting constructive criticism
* Focusing on what is best for the community
* Showing empathy towards other community members

Examples of unacceptable behavior by participants include:

* The use of sexualized language or imagery and unwelcome sexual attention or
 advances
* Trolling, insulting/derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or electronic
 address, without explicit permission
* Other conduct which could reasonably be considered inappropriate in a
 professional setting

## Our Responsibilities

Project maintainers are responsible for clarifying the standards of acceptable
behavior and are expected to take appropriate and fair corrective action in
response to any instances of unacceptable behavior.

Project maintainers have the right and responsibility to remove, edit, or
reject comments, commits, code, wiki edits, issues, and other contributions
that are not aligned to this Code of Conduct, or to ban temporarily or
permanently any contributor for other behaviors that they deem inappropriate,
threatening, offensive, or harmful.

## Scope

This Code of Conduct applies both within project spaces and in public spaces
when an individual is representing the project or its community. Examples of
representing a project or community include using an official project e-mail
address, posting via an official social media account, or acting as an appointed
representative at an online or offline event. Representation of a project may be
further defined and clarified by project maintainers.

## Enforcement

Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported by contacting the project team at andrea.verlicchi@gmail.com. All
complaints will be reviewed and investigated and will result in a response that
is deemed necessary and appropriate to the circumstances. The project team is
obligated to maintain confidentiality with regard to the reporter of an incident.
Further details of specific enforcement policies may be posted separately.

Project maintainers who do not follow or enforce the Code of Conduct in good
faith may face temporary or permanent repercussions as determined by other
members of the project's leadership.

## Attribution

This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html

[homepage]: https://www.contributor-covenant.org

For answers to common questions about this code of conduct, see
https://www.contributor-covenant.org/faq


================================================
FILE: LICENSE
================================================
MIT License

Copyright (c) 2025 Andrea Verlicchi

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.


================================================
FILE: README.md
================================================
LazyLoad is a lightweight (2.4 kB) and flexible script that **speeds up your web application** by deferring the loading of your below-the-fold images, animated SVGs, videos and iframes to **when they will enter the viewport**. It's written in plain "vanilla" JavaScript, it leverages the [IntersectionObserver](https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API) API, it supports [responsive images](https://alistapart.com/article/responsive-images-in-practice), it optimizes your website for slower connections, and can enable native lazy loading. See [all features](#-all-features-compared) for more.

[![vanilla-lazyload (latest)](https://img.shields.io/npm/v/vanilla-lazyload/latest.svg)](https://www.npmjs.com/package/vanilla-lazyload)
[![vanilla-lazyload (downloads)](https://img.shields.io/npm/dy/vanilla-lazyload.svg)](https://www.npmjs.com/package/vanilla-lazyload)
[![](https://data.jsdelivr.com/v1/package/npm/vanilla-lazyload/badge)](https://www.jsdelivr.com/package/npm/vanilla-lazyload)
[![](https://github.com/verlok/vanilla-lazyload/actions/workflows/ci.yml/badge.svg)](https://github.com/verlok/vanilla-lazyload/actions/workflows/ci.yml)

➡️ Jump to: [👨‍💻 Getting started - HTML](#-getting-started---html) - [👩‍💻 Getting started - Script](#-getting-started---script) - [🥧 Recipes](#-recipes) - [📺 Demos](#-demos) - [😋 Tips & tricks](#-tips--tricks) - [🔌 API](#-api) - [😯 All features compared](#-all-features-compared)

---

**Love this project? 😍 [Buy me a coffee!](https://ko-fi.com/verlok)**

---

## 👨‍💻 Getting started - HTML

In order to make your content be loaded by LazyLoad, you must use some `data-` attributes instead of the actual attributes. Examples below.

### Lazy image:

```html
<img alt="A lazy image" class="lazy" data-src="lazy.jpg" />
```

### Lazy image with low quality placeholder:

```html
<img alt="A lazy image" class="lazy" src="lazy-lowQuality.jpg" data-src="lazy.jpg" />
```

### Lazy responsive image with `srcset` and `sizes`:

```html
<img
  alt="A lazy image"
  class="lazy"
  data-src="lazy.jpg"
  data-srcset="lazy_400.jpg 400w, 
    lazy_800.jpg 800w"
  data-sizes="100w"
/>
```

To have a low quality placeholder, add the `src` attribute pointing to a very small version of the image. E.g. `src="lazy_10.jpg"`.

### Lazy responsive image with hi-dpi support using the `picture` tag:

```html
<picture>
  <source media="(min-width: 1200px)" data-srcset="lazy_1200.jpg 1x, lazy_2400.jpg 2x" />
  <source media="(min-width: 800px)" data-srcset="lazy_800.jpg 1x, lazy_1600.jpg 2x" />
  <img alt="A lazy image" class="lazy" data-src="lazy.jpg" />
</picture>
```

To have a low quality placeholder, add the `src` attribute pointing to a very small version of the image to the `img` tag. E.g. `src="lazy_10.jpg"`.

### Lazy responsive image with automatic _WebP_ format selection, using the `picture` tag:

```html
<picture>
  <source
    type="image/webp"
    data-srcset="lazy_400.webp 400w, 
      lazy_800.webp 800w"
    data-sizes="100w"
  />
  <img
    alt="A lazy image"
    class="lazy"
    data-src="lazy.jpg"
    data-srcset="lazy_400.jpg 400w, 
      lazy_800.jpg 800w"
    data-sizes="100w"
  />
</picture>
```

To have a low quality placeholder, add the `src` attribute pointing to a very small version of the image to the `img` tag. E.g. `src="lazy_10.jpg"`.

### Lazy background image

⚠ **IMPORTANT NOTE**: To display content images on your pages, always use the `img` tag. This would benefit the SEO and the accessibility of your website. To understand if your images are content or background, ask yourself: "would my website user like to see those images when printing out the page?". If the answer is "yes", then your images are content images and you should avoid using background images to display them.

#### Single background image:

```html
<div class="lazy" data-bg="lazy.jpg"></div>
```

#### Single background, with HiDPI screen support:

```html
<div class="lazy" data-bg="lazy.jpg" data-bg-hidpi="lazy@2x.jpg"></div>
```

#### Multiple backgrounds:

```html
<div
  class="lazy"
  data-bg-multi="url(lazy-head.jpg), 
    url(lazy-body.jpg), 
    linear-gradient(#fff, #ccc)"
>
  ...
</div>
```

#### Multiple backgrounds, HiDPI screen support:

```html
<div
  class="lazy"
  data-bg-multi="url(lazy-head.jpg),
    url(lazy-body.jpg),
    linear-gradient(#fff, #ccc)"
  data-bg-multi-hidpi="url(lazy-head@2x.jpg),
    url(lazy-body@2x.jpg),
    linear-gradient(#fff, #ccc)"
>
  ...
</div>
```

#### Backgrounds with `image-set`:

```html
<div class="lazy" data-bg-set="url('lazy@1x.jpg') 1x, url('lazy@2x.jpg') 2x">...</div>
```

#### Multiple backgrounds with `image-set`:

```html
<div
  class="lazy"
  data-bg-set="
    url('lazy-head@1x.jpg') 1x, url('lazy-head@2x.jpg') 2x | 
    url('lazy-body@1x.jpg') 1x, url('lazy-body@2x.jpg') 2x
  "
>
  ...
</div>
```

### Lazy animated SVG

```html
<object class="lazy" type="image/svg+xml" data-src="lazy.svg"></object>
```

### Lazy video

```html
<video class="lazy" controls width="620" data-src="lazy.mp4" data-poster="lazy.jpg">
  <source type="video/mp4" data-src="lazy.mp4" />
  <source type="video/ogg" data-src="lazy.ogg" />
  <source type="video/avi" data-src="lazy.avi" />
</video>
```

Please note that the video poster can be lazily loaded too.

### Lazy iframe

```html
<iframe class="lazy" data-src="lazyFrame.html"></iframe>
```

---

**Love this project? 😍 [Buy me a coffee!](https://ko-fi.com/verlok)**

---

## 👩‍💻 Getting started - Script

The latest, recommended version of LazyLoad is **19.1.3**.
Note that if you need to support Internet Explorer 11, you need to use version 17.9.0 or below.

Quickly understand how to upgrade from a previous version reading the [practical upgrade guide](UPGRADE.md).

### The simple, easiest way

The easiest way to use LazyLoad is to include the script from a CDN.

```html
<script src="https://cdn.jsdelivr.net/npm/vanilla-lazyload@19.1.3/dist/lazyload.min.js"></script>
```

OR, if you prefer to import it as an ES module:

```html
<script type="module">
  import LazyLoad from "https://cdn.jsdelivr.net/npm/vanilla-lazyload@19.0.3/+esm";
</script>
```

Then, in your javascript code:

```js
var lazyLoadInstance = new LazyLoad({
  // Your custom settings go here
});
```

To be sure that DOM for your lazy content is ready when you instantiate LazyLoad, **place the script tag right before the closing `</body>` tag**.

If more DOM arrives later, e.g. via an AJAX call, you'll need to call `lazyLoadInstance.update();` to make LazyLoad check the DOM again.

```js
lazyLoadInstance.update();
```

### Using an `async` script

If you prefer, it's possible to include LazyLoad's script using `async` script and initialize it as soon as it's loaded.

To do so, **you must define the options before including the script**. You can pass:

- `{}` an object to get a single instance of LazyLoad
- `[{}, {}]` an array of objects to get multiple instances of LazyLoad, each one with different options.

```html
<script>
  // Set the options globally
  // to make LazyLoad self-initialize
  window.lazyLoadOptions = {
    // Your custom settings go here
  };
</script>
```

Then include the script.

```html
<script
  async
  src="https://cdn.jsdelivr.net/npm/vanilla-lazyload@19.1.3/dist/lazyload.min.js"
></script>
```

**Possibly place the script tag right before the closing `</body>` tag**. If you can't do that, LazyLoad could be executed before the browser has loaded all the DOM, and you'll need to call its `update()` method to make it check the DOM again.

### Using an `async` script + getting the instance reference

Same as above, but you must put the `addEventListener` code shown below before including the `async` script.

```html
<script>
  // Set the options globally
  // to make LazyLoad self-initialize
  window.lazyLoadOptions = {
    // Your custom settings go here
  };
  // Listen to the initialization event
  // and get the instance of LazyLoad
  window.addEventListener(
    "LazyLoad::Initialized",
    function (event) {
      window.lazyLoadInstance = event.detail.instance;
    },
    false
  );
</script>
```

Then include the script.

```html
<script
  async
  src="https://cdn.jsdelivr.net/npm/vanilla-lazyload@19.1.3/dist/lazyload.min.js"
></script>
```

Now you'll be able to call its methods, like:

```js
lazyLoadInstance.update();
```

[DEMO](https://verlok.github.io/vanilla-lazyload/demos/async.html) - [SOURCE](https://github.com/verlok/vanilla-lazyload/blob/master/demos/async.html) &larr; for a single LazyLoad instance

[DEMO](https://verlok.github.io/vanilla-lazyload/demos/async_multiple.html) - [SOURCE](https://github.com/verlok/vanilla-lazyload/blob/master/demos/async_multiple.html) &larr; for multiple LazyLoad instances

### Local install

If you prefer to install LazyLoad locally in your project, you can!

#### Using npm

```
npm install vanilla-lazyload
```

#### Using bower

```
bower install vanilla-lazyload
```

#### Manual download

Download one the latest [releases](https://github.com/verlok/vanilla-lazyload/releases/). The files you need are inside the `dist` folder. If you don't know which one to pick, use `lazyload.min.js`, or read [about bundles](#bundles).

### Local usage

Should you install LazyLoad locally, you can import it as ES module like the following:

```js
import LazyLoad from "vanilla-lazyload";
```

It's also possible (but unadvised) to use the `require` commonJS syntax.

More information about bundling LazyLoad with WebPack are available on [this specific repo](https://github.com/verlok/lazyload-es2015-webpack-test).

### Usage with React

Take a look at this example of [usage of React with LazyLoad](https://codesandbox.io/s/20306yk96p) on Sandbox.

This implementation takes the same props that you would normally pass to the `img` tag, but it renders a lazy image. Feel free to fork and improve it!

### Bundles

Inside the `dist` folder you will find different bundles.

| Filename               | Module Type                                                   | Advantages                                                                                                                                 |
| ---------------------- | ------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------ |
| `lazyload.min.js`      | UMD <small>(Universal Module Definition)</small>              | Works pretty much everywhere, even in common-js contexts                                                                                   |
| `lazyload.iife.min.js` | IIFE <small>(Immediately Invoked Function Expression)</small> | Works as in-page `<script src="...">`, ~0.5kb smaller than UMD version                                                                     |
| `esm/lazyload.js`      | ES Module                                                     | Exports `LazyLoad` so you can import it in your project both using `<script type="module" src="...">` and a bundler like WebPack or Rollup |

---

**Love this project? 😍 [Buy me a coffee!](https://ko-fi.com/verlok)**

---

## 🥧 Recipes

This is the section where you can find _ready to copy & paste_ code for your convenience.

### Hide alt text and empty image

> 💡 **Use case**: when your lazily loaded images show their `alt` text and the empty image icon before loading.

CSS

```css
img:not([src]):not([srcset]) {
  visibility: hidden;
}
```

Just that, really.

### Image errors handling

> 💡 **Use case**: when you want to prevent showing unexisting/broken images on your website.

Javascript

```js
var myLazyLoad = new LazyLoad({
  // Other options here...
  callback_error: (img) => {
    // Use the following line only if your images have the `srcset` attribute
    img.setAttribute("srcset", "fallback_image@1x.jpg 1x, fallback_image@2x.jpg 2x");
    img.setAttribute("src", "fallback_image@1x.jpg");
  }
});
```

NOTE: if the error was generated by a network down (navigator if temporarily offline), vanilla-lazyload will try and load the images again when the network becomes available again.

[EXAMPLE](https://codepen.io/verlok/pen/mdwYbGq) - [API](#-api)

### Dynamic content

> 💡 **Use case**: when you want to lazily load images, but the number of images change in the scrolling area changes, maybe because they are added asynchronously.

Javascript

```js
var myLazyLoad = new LazyLoad();
// After your content has changed...
myLazyLoad.update();
```

[DEMO](https://verlok.github.io/vanilla-lazyload/demos/dynamic_content.html) - [SOURCE](https://github.com/verlok/vanilla-lazyload/blob/master/demos/dynamic_content.html) - [API](#-api)

### Mixed native and JS-based lazy loading

> 💡 **Use case**: you want to use the `use_native` option to delegate the loading of images, iframes and videos to the browsers engine where supported, but you also want to lazily load background images.

HTML

```html
<img class="lazy" alt="A lazy image" data-src="lazy.jpg" />
<iframe class="lazy" data-src="lazyFrame.html"></iframe>
<video class="lazy" controls data-src="lazy.mp4" data-poster="lazy.jpg">...</video>
<object class="lazy" type="image/svg+xml" data-src="lazy.svg"></object>
<div class="lazy" data-bg="lazy.jpg"></div>
```

Javascript

```js
// Instance using native lazy loading
const lazyContent = new LazyLoad({
  use_native: true // <-- there you go
});

// Instance without native lazy loading
const lazyBackground = new LazyLoad({
  // DON'T PASS use_native: true HERE
});
```

[DEMO](https://verlok.github.io/vanilla-lazyload/demos/native_lazyload_conditional.html) - [SOURCE](https://github.com/verlok/vanilla-lazyload/blob/master/demos/native_lazyload_conditional.html) - [API](#-api)

### Scrolling panel(s)

> 💡 **Use case**: when your scrolling container is not the main browser window, but a scrolling container.

HTML

```html
<div class="scrollingPanel">
  <!-- Set of images -->
</div>
```

Javascript

```js
var myLazyLoad = new LazyLoad({
  container: document.querySelector(".scrollingPanel")
});
```

[DEMO](https://verlok.github.io/vanilla-lazyload/demos/container_single.html) - [SOURCE](https://github.com/verlok/vanilla-lazyload/blob/master/demos/container_single.html) - [API](#-api)

If you have _multiple_ scrolling panels, you can use the following markup and code.

HTML

```html
<div id="scrollingPanel1" class="scrollingPanel">
  <!-- Set of images -->
</div>
<div id="scrollingPanel2" class="scrollingPanel">
  <!-- Set of images -->
</div>
```

Javascript

```js
var myLazyLoad1 = new LazyLoad({
  container: document.getElementById("scrollingPanel1")
});
var myLazyLoad2 = new LazyLoad({
  container: document.getElementById("scrollingPanel2")
});
```

[DEMO](https://verlok.github.io/vanilla-lazyload/demos/container_multiple.html) - [SOURCE](https://github.com/verlok/vanilla-lazyload/blob/master/demos/container_multiple.html) - [API](#-api)

### Lazy functions

> 💡 **Use case**: when you want to execute arbitrary scripts or functions when given elements enter the viewport

HTML

```html
<div class="lazy" data-lazy-function="foo">...</div>
<div class="lazy" data-lazy-function="bar">...</div>
<div class="lazy" data-lazy-function="buzz">...</div>
<div class="lazy" data-lazy-function="booya">...</div>
```

JS

```js
// It's a best practice to scope the function names inside a namespace like `lazyFunctions`.
window.lazyFunctions = {
  foo: function (element) {
    element.style.color = "red";
    console.log("foo");
  },
  bar: function (element) {
    element.remove(element);
    console.log("bar");
  },
  buzz: function (element) {
    var span = document.createElement("span");
    span.innerText = " - buzz!";
    element.appendChild(span);
    console.log("buzz");
  },
  booya: function (element) {
    element.classList.add("boo");
    console.log("booya");
  }
};
```

```js
function executeLazyFunction(element) {
  var lazyFunctionName = element.getAttribute("data-lazy-function");
  var lazyFunction = window.lazyFunctions[lazyFunctionName];
  if (!lazyFunction) return;
  lazyFunction(element);
}

var ll = new LazyLoad({
  unobserve_entered: true, // <- Avoid executing the function multiple times
  callback_enter: executeLazyFunction // Assigning the function defined above
});
```

Use `unobserve_entered` to avoid executing the function multiple times.

That's it. Whenever an element with the `data-lazy-function` attribute enters the viewport, LazyLoad calls the `executeLazyScript` function, which gets the function name from the `data-lazy-function` attribute itself and executes it.

[DEMO](https://verlok.github.io/vanilla-lazyload/demos/lazy_functions.html) - [SOURCE](https://github.com/verlok/vanilla-lazyload/blob/master/demos/lazy_functions.html) - [API](#-api)

### Lazy initialization of multiple LazyLoad instances

> 💡 **Use case**: when you have a lot of horizontally scrolling containers and you want to instantiate a LazyLoad instance on them, but only when they entered the viewport.

HTML

```html
<div class="horizContainer">
  <img
    src=""
    alt="Row 01, col 01"
    data-src="https://placeholdit.imgix.net/~text?txtsize=19&amp;txt=row_01_col_01&amp;w=200&amp;h=200"
  />
  <img
    src=""
    alt="Row 01, col 02"
    data-src="https://placeholdit.imgix.net/~text?txtsize=19&amp;txt=row_01_col_02&amp;w=200&amp;h=200"
  />
  <!-- ... -->
</div>
<div class="horizContainer">
  <img
    src=""
    alt="Row 02, col 01"
    data-src="https://placeholdit.imgix.net/~text?txtsize=19&amp;txt=row_02_col_01&amp;w=200&amp;h=200"
  />
  <img
    src=""
    alt="Row 02, col 02"
    data-src="https://placeholdit.imgix.net/~text?txtsize=19&amp;txt=row_02_col_02&amp;w=200&amp;h=200"
  />
  <!-- ... -->
</div>
```

Javascript

```js
var lazyLoadInstances = [];

var initOneLazyLoad = function (horizContainerElement) {
  // When the .horizContainer element enters the viewport,
  // instantiate a new LazyLoad on the horizContainerElement
  var oneLL = new LazyLoad({
    container: horizContainerElement
  });
  // Optionally push it in the lazyLoadInstances
  // array to keep track of the instances
  lazyLoadInstances.push(oneLL);
};

// The "lazyLazy" instance of lazyload is used to check
// when the .horizContainer divs enter the viewport
var lazyLazy = new LazyLoad({
  elements_selector: ".horizContainer",
  callback_enter: initOneLazyLoad,
  unobserve_entered: true // Stop observing .horizContainer(s) after they entered
});
```

That's it. Whenever a `.horizContainer` element enters the viewport, LazyLoad calls the `initOneLazyLoad` function, which creates a new instance of LazyLoad on the `.horizContainer` element.

[DEMO](https://verlok.github.io/vanilla-lazyload/demos/lazily_load_lazyLoad.html) - [SOURCE](https://github.com/verlok/vanilla-lazyload/blob/master/demos/lazily_load_lazyLoad.html) - [API](#-api)

---

**Love this project? 😍 [Buy me a coffee!](https://ko-fi.com/verlok)**

---

## 📺 Demos

Didn't find the [recipe](#-recipes) that exactly matches your case? We have demos!

The [demos](https://github.com/verlok/vanilla-lazyload/tree/master/demos) folder contains 30+ use cases of vanilla-lazyload. You might find there what you're looking for.

| Type      | Title                                                                                          | Code                                           | Demo                                                                                     |
| --------- | ---------------------------------------------------------------------------------------------- | ---------------------------------------------- | ---------------------------------------------------------------------------------------- |
| Content   | Simple lazy loaded images, not using any placeholder                                           | [Code](demos/image_basic.html)                 | [Live](https://verlok.github.io/vanilla-lazyload/demos/image_basic.html)                 |
| Content   | Lazy images that use an inline SVG as a placeholder                                            | [Code](demos/image_ph_inline.html)             | [Live](https://verlok.github.io/vanilla-lazyload/demos/image_ph_inline.html)             |
| Content   | Lazy images that use an external SVG file as a placeholder                                     | [Code](demos/image_ph_external.html)           | [Live](https://verlok.github.io/vanilla-lazyload/demos/image_ph_external.html)           |
| Content   | Lazy responsive images with `srcset`                                                           | [Code](demos/image_srcset.html)                | [Live](https://verlok.github.io/vanilla-lazyload/demos/image_srcset.html)                |
| Content   | Lazy responsive images with the `<picture>` tag and the `media` attribute (art direction)      | [Code](demos/picture_media.html)               | [Live](https://verlok.github.io/vanilla-lazyload/demos/picture_media.html)               |
| Content   | Lazy responsive images with `srcset` and `sizes` (using `data-sizes`)                          | [Code](demos/image_srcset_lazy_sizes.html)     | [Live](https://verlok.github.io/vanilla-lazyload/demos/image_srcset_lazy_sizes.html)     |
| Content   | Lazy responsive images with `srcset` and `sizes` (using plain `sizes`)                         | [Code](demos/image_srcset_sizes.html)          | [Live](https://verlok.github.io/vanilla-lazyload/demos/image_srcset_sizes.html)          |
| Content   | Lazy video with multiple `<source>` tags, different preload options, NO autoplay               | [Code](demos/video.html)                       | [Live](https://verlok.github.io/vanilla-lazyload/demos/video.html)                       |
| Content   | Lazy video with multiple `<source>` tags, different preload options, WITH autoplay             | [Code](demos/video_autoplay.html)              | [Live](https://verlok.github.io/vanilla-lazyload/demos/video_autoplay.html)              |
| Content   | Lazy loading background images                                                                 | [Code](demos/background_images.html)           | [Live](https://verlok.github.io/vanilla-lazyload/demos/background_images.html)           |
| Content   | Lazy loading multiple background images                                                        | [Code](demos/background_images_multi.html)     | [Live](https://verlok.github.io/vanilla-lazyload/demos/background_images_multi.html)     |
| Content   | Lazy loading background images with `image-set()`                                              | [Code](demos/background_images_image-set.html) | [Live](https://verlok.github.io/vanilla-lazyload/demos/background_images_image-set.html) |
| Content   | Lazy loading iframes                                                                           | [Code](demos/iframes.html)                     | [Live](https://verlok.github.io/vanilla-lazyload/demos/iframes.html)                     |
| Content   | Lazy loading animated SVGs and PDF files                                                       | [Code](demos/objects.html)                     | [Live](https://verlok.github.io/vanilla-lazyload/demos/objects.html)                     |
| Content   | Lazy WebP images with the `<picture>` tag and the `type` attribute for WebP                    | [Code](demos/picture_type_webp.html)           | [Live](https://verlok.github.io/vanilla-lazyload/demos/picture_type_webp.html)           |
| Loading   | Asynchronous loading LazyLoad with `<script async>`                                            | [Code](demos/async.html)                       | [Live](https://verlok.github.io/vanilla-lazyload/demos/async.html)                       |
| Loading   | Asynchronous loading multiple LazyLoad instances with `<script async>`                         | [Code](demos/async_multiple.html)              | [Live](https://verlok.github.io/vanilla-lazyload/demos/async_multiple.html)              |
| Error     | Test error loading behaviour when `restore_on_error` is `false`                                | [Code](demos/error_no_restore.html)            | [Live](https://verlok.github.io/vanilla-lazyload/demos/error_no_restore.html)            |
| Error     | Test error loading behaviour when `restore_on_error` is `true`                                 | [Code](demos/error_restore.html)               | [Live](https://verlok.github.io/vanilla-lazyload/demos/error_restore.html)               |
| Technique | Fade in images as they load                                                                    | [Code](demos/fade_in.html)                     | [Live](https://verlok.github.io/vanilla-lazyload/demos/fade_in.html)                     |
| Technique | Lazy load images in CSS-only horizontal sliders (Netflix style)                                | [Code](demos/sliders_css_only.html)            | [Live](https://verlok.github.io/vanilla-lazyload/demos/sliders_css_only.html)            |
| Technique | Lazily create Swiper instances and lazily load Swiper images                                   | [Code](demos/swiper.html)                      | [Live](https://verlok.github.io/vanilla-lazyload/demos/swiper.html)                      |
| Technique | Lazily execute functions as specific elements enter the viewport                               | [Code](demos/lazy_functions.html)              | [Live](https://verlok.github.io/vanilla-lazyload/demos/lazy_functions.html)              |
| Technique | How to manage the print of a page with lazy images                                             | [Code](demos/print.html)                       | [Live](https://verlok.github.io/vanilla-lazyload/demos/print.html)                       |
| Technique | A popup layer containing lazy images in a scrolling container                                  | [Code](demos/popup_layer.html)                 | [Live](https://verlok.github.io/vanilla-lazyload/demos/popup_layer.html)                 |
| Settings  | Multiple scrolling containers                                                                  | [Code](demos/container_multiple.html)          | [Live](https://verlok.github.io/vanilla-lazyload/demos/container_multiple.html)          |
| Settings  | Single scrolling container                                                                     | [Code](demos/container_single.html)            | [Live](https://verlok.github.io/vanilla-lazyload/demos/container_single.html)            |
| Methods   | How to `restore()` DOM to its original state, and/or `destroy()` LazyLoad                      | [Code](demos/restore_destroy.html)             | [Live](https://verlok.github.io/vanilla-lazyload/demos/restore_destroy.html)             |
| Methods   | Adding dynamic content, then `update()` LazyLoad                                               | [Code](demos/dynamic_content.html)             | [Live](https://verlok.github.io/vanilla-lazyload/demos/dynamic_content.html)             |
| Methods   | Adding dynamic content, then `update()` LazyLoad passing a NodeSet of elements                 | [Code](demos/dynamic_content_nodeset.html)     | [Live](https://verlok.github.io/vanilla-lazyload/demos/dynamic_content_nodeset.html)     |
| Methods   | Load punctual images using the `load()` method                                                 | [Code](demos/load.html)                        | [Live](https://verlok.github.io/vanilla-lazyload/demos/load.html)                        |
| Methods   | Load all images at once using `loadAll()`                                                      | [Code](demos/load_all.html)                    | [Live](https://verlok.github.io/vanilla-lazyload/demos/load_all.html)                    |
| Test      | Test for multiple thresholds                                                                   | [Code](demos/thresholds.html)                  | [Live](https://verlok.github.io/vanilla-lazyload/demos/thresholds.html)                  |
| Test      | Test behaviour with hidden images                                                              | [Code](demos/image_hidden.html)                | [Live](https://verlok.github.io/vanilla-lazyload/demos/image_hidden.html)                |
| Test      | Test performance, lazy loading of hundreds of images                                           | [Code](demos/hundreds.html)                    | [Live](https://verlok.github.io/vanilla-lazyload/demos/hundreds.html)                    |
| Native    | Test the native lazy loading of images _WITHOUT_ any line of javascript, not even this script  | [Code](demos/native_lazyload.html)             | [Live](https://verlok.github.io/vanilla-lazyload/demos/native_lazyload.html)             |
| Native    | Test the native lazy loading of images _conditionally_ using the `use_native` option (see API) | [Code](demos/native_lazyload_conditional.html) | [Live](https://verlok.github.io/vanilla-lazyload/demos/native_lazyload_conditional.html) |

---

**Love this project? 😍 [Buy me a coffee!](https://ko-fi.com/verlok)**

---

## 😋 Tips & tricks

### Minimize [CLS](https://web.dev/cls) by occupy space beforehand

It's very important to make sure that your lazy images occupy some space even **before they are loaded**, otherwise the `img` elements will be shrinked to zero-height, causing your layout to shift and making lazyload inefficient.

The best way to do that is to set both `width` and `height` attributes to `img` and `video` elements and, if you choose not to use a placeholder image, apply the `display: block` CSS rule to every image.

You can find more details and demos in my article [aspect-ratio: A modern way to reserve space for images and async content in responsive design](https://www.andreaverlicchi.eu/blog/aspect-ratio-modern-reserve-space-lazy-images-async-content-responsive-design/).

---

**Love this project? 😍 [Buy me a coffee!](https://ko-fi.com/verlok)**

---

## 🔌 API

### Constructor arguments

The `new LazyLoad()` instruction you execute on your page can take two parameters:

| Parameter | What to pass                                    | Required | Default value | Type         |
| --------- | ----------------------------------------------- | -------- | ------------- | ------------ |
| Options   | The option object for this instance of LazyLoad | No       | `{}`          | Plain Object |
| Nodeset   | A NodeSet of elements to execute LazyLoad on    | No       | `null`        | NodeSet      |

The most common usage of LazyLoad constructor is to pass only the options object (see "options" in the next section). For example:

```js
var aLazyLoad = new LazyLoad({
  /* options here */
});
```

In the unusual cases when you can't select the elements using `elements_selector`, you could pass the elements set as a second parameter. It can be either a NodeSet or an array of DOM elements.

```js
var elementsToLazyLoad = getElementSetFromSomewhere();
var aLazyLoad = new LazyLoad(
  {
    /* options here */
  },
  elementsToLazyLoad
);
```

### Options

For every instance of _LazyLoad_ you can pass in some options, to alter its default behaviour.
Here's the list of the options.

| Name                  | Meaning                                                                                                                                                                                                                                                                                                                                                                                                                                                      | Default value      | Example value                            |
| --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------ | ---------------------------------------- |
| `container`           | The scrolling container of the elements in the `elements_selector` option.                                                                                                                                                                                                                                                                                                                                                                                   | `document`         | `document.querySelector('.scrollPanel')` |
| `elements_selector`   | The CSS selector of the elements to load lazily, which will be selected as descendants of the `container` object.                                                                                                                                                                                                                                                                                                                                            | `".lazy"`          | `".lazyload"`                            |
| `threshold`           | A number of pixels representing the outer distance off the scrolling area from which to start loading the elements.                                                                                                                                                                                                                                                                                                                                          | `300`              | `0`                                      |
| `thresholds`          | Similar to `threshold`, but accepting multiple values and both `px` and `%` units. It maps directly to the `rootMargin` property of IntersectionObserver ([read more](https://developer.mozilla.org/en-US/docs/Web/API/IntersectionObserver/rootMargin)), so it must be a string with a syntax similar to the CSS `margin` property. You can use it when you need to have different thresholds for the scrolling area. It overrides `threshold` when passed. | `null`             | `"500px 10%"`                            |
| `data_src`            | The name of the data attribute containing the element URL to load, excluding the `"data-"` part. E.g. if your data attribute is named `"data-src"`, just pass `"src"`                                                                                                                                                                                                                                                                                        | `"src"`            | `"lazy-src"`                             |
| `data_srcset`         | The name of the data attribute containing the image URL set to load, in either `img` and `source` tags, excluding the `"data-"` part. E.g. if your data attribute is named `"data-srcset"`, just pass `"srcset"`                                                                                                                                                                                                                                             | `"srcset"`         | `"lazy-srcset"`                          |
| `data_sizes`          | The name of the data attribute containing the sizes attribute to use, excluding the `"data-"` part. E.g. if your data attribute is named `"data-sizes"`, just pass `"sizes"`                                                                                                                                                                                                                                                                                 | `"sizes"`          | `"lazy-sizes"`                           |
| `data_bg`             | The name of the data attribute containing the URL of `background-image` to load lazily, excluding the `"data-"` part. E.g. if your data attribute is named `"data-bg"`, just pass `"bg"`. The attribute value must be a valid value for `background-image`, including the `url()` part of the CSS instruction.                                                                                                                                               | `"bg"`             | `"lazy-bg"`                              |
| `data_bg_hidpi`       | The name of the data attribute containing the URL of `background-image` to load lazily on HiDPI screens, excluding the `"data-"` part. E.g. if your data attribute is named `"data-bg-hidpi"`, just pass `"bg-hidpi"`. The attribute value must be a valid value for `background-image`, including the `url()` part of the CSS instruction.                                                                                                                  | `"bg-hidpi"`       | `"lazy-bg-hidpi"`                        |
| `data_bg_multi`       | The name of the data attribute containing the value of multiple `background-image` to load lazily, excluding the `"data-"` part. E.g. if your data attribute is named `"data-bg-multi"`, just pass `"bg-multi"`. The attribute value must be a valid value for `background-image`, including the `url()` part of the CSS instruction.                                                                                                                        | `"bg-multi"`       | `"lazy-bg-multi"`                        |
| `data_bg_multi_hidpi` | The name of the data attribute containing the value of multiple `background-image` to load lazily on HiDPI screens, excluding the `"data-"` part. E.g. if your data attribute is named `"data-bg-multi-hidpi"`, just pass `"bg-multi-hidpi"`. The attribute value must be a valid value for `background-image`, including the `url()` part of the CSS instruction.                                                                                           | `"bg-multi-hidpi"` | `"lazy-bg-multi-hidpi"`                  |
| `data_bg_set`         | The name of the data attribute containing the value of the background to be applied with image-set, excluding the `"data-"` part. E.g. if your data attribute is named `"data-bg-set"`, just pass `"bg-set"`. The attribute value must be what goes inside the `image-set` CSS function. You can separate values with a pipe (`\|`) character to have multiple backgrounds.                                                                                  | `"bg-set"`         | `"lazy-bg-set"`                          |
| `data_poster`         | The name of the data attribute containing the value of `poster` to load lazily, excluding the `"data-"` part. E.g. if your data attribute is named `"data-poster"`, just pass `"poster"`.                                                                                                                                                                                                                                                                    | `"poster"`         | `"lazy-poster"`                          |
| `class_applied`       | The class applied to the multiple background elements after the multiple background was applied                                                                                                                                                                                                                                                                                                                                                              | `"applied"`        | `"lazy-applied"`                         |
| `class_loading`       | The class applied to the elements while the loading is in progress.                                                                                                                                                                                                                                                                                                                                                                                          | `"loading"`        | `"lazy-loading"`                         |
| `class_loaded`        | The class applied to the elements when the loading is complete.                                                                                                                                                                                                                                                                                                                                                                                              | `"loaded"`         | `"lazy-loaded"`                          |
| `class_error`         | The class applied to the elements when the element causes an error.                                                                                                                                                                                                                                                                                                                                                                                          | `"error"`          | `"lazy-error"`                           |
| `class_entered`       | The class applied to the elements after they entered the viewport.                                                                                                                                                                                                                                                                                                                                                                                           | `"entered"`        | `"lazy-entered"`                         |
| `class_exited`        | The class applied to the elements after they exited the viewport. This class is removed if an element enters the viewport again. The `unobserve_entered` option can affect the appliance of this class, e.g. when loading images that complete loading before exiting.                                                                                                                                                                                       | `"exited"`         | `"lazy-exited"`                          |
| `cancel_on_exit`      | A boolean that defines whether or not to cancel the download of the images that exit the viewport while they are still loading, eventually restoring the original attributes. It applies only to images so to the `img` (and `picture`) tags, so it doesn't apply to background images, `iframe`s, `object`s nor `video`s.                                                                                                                                   | `true`             | `false`                                  |
| `unobserve_entered`   | A boolean that defines whether or not to automatically unobserve elements once they entered the viewport                                                                                                                                                                                                                                                                                                                                                     | `false`            | `true`                                   |
| `unobserve_completed` | A boolean that defines whether or not to automatically unobserve elements once they've loaded or throwed an error                                                                                                                                                                                                                                                                                                                                            | `true`             | `false`                                  |
| `callback_enter`      | A callback function which is called whenever an element enters the viewport. Arguments: DOM element, intersection observer entry, lazyload instance.                                                                                                                                                                                                                                                                                                         | `null`             | `(el)=>{console.log("Entered", el)}`     |
| `callback_exit`       | A callback function which is called whenever an element exits the viewport. Arguments: DOM element, intersection observer entry, lazyload instance.                                                                                                                                                                                                                                                                                                          | `null`             | `(el)=>{console.log("Exited", el)}`      |
| `callback_loading`    | A callback function which is called whenever an element starts loading. Arguments: DOM element, lazyload instance.                                                                                                                                                                                                                                                                                                                                           | `null`             | `(el)=>{console.log("Loading", el)}`     |
| `callback_cancel`     | A callback function which is called whenever an element loading is canceled while loading, as for `cancel_on_exit: true`.                                                                                                                                                                                                                                                                                                                                    | `null`             | `(el)=>{console.log("Cancelled", el)}`   |
| `callback_loaded`     | A callback function which is called whenever an element finishes loading. Note that, in version older than 11.0.0, this option went under the name `callback_load`. Arguments: DOM element, lazyload instance.                                                                                                                                                                                                                                               | `null`             | `(el)=>{console.log("Loaded", el)}`      |
| `callback_error`      | A callback function which is called whenever an element triggers an error. Arguments: DOM element, lazyload instance.                                                                                                                                                                                                                                                                                                                                        | `null`             | `(el)=>{console.log("Error", el)}`       |
| `callback_applied`    | A callback function which is called whenever a multiple background element starts loading. Arguments: DOM element, lazyload instance.                                                                                                                                                                                                                                                                                                                        | `null`             | `(el)=>{console.log("Applied", el)}`     |
| `callback_finish`     | A callback function which is called when there are no more elements to load _and_ all elements have been downloaded. Arguments: lazyload instance.                                                                                                                                                                                                                                                                                                           | `null`             | `()=>{console.log("Finish")}`            |
| `use_native`          | This boolean sets whether or not to use [native lazy loading](https://addyosmani.com/blog/lazy-loading/) to do [hybrid lazy loading](https://www.smashingmagazine.com/2019/05/hybrid-lazy-loading-progressive-migration-native/). On browsers that support it, LazyLoad will set the `loading="lazy"` attribute on images, iframes and videos, and delegate their loading to the browser.                                                                    | `false`            | `true`                                   |
| `restore_on_error`    | Tells LazyLoad if to restore the original values of `src`, `srcset` and `sizes` when a loading error occurs.                                                                                                                                                                                                                                                                                                                                                 | `false`            | `true`                                   |

### Methods

**Instance methods**

You can call the following methods on any instance of LazyLoad.

| Method name    | Effect                                                                                                                                                           | Use case                                                                          |
| -------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------- |
| `update()`     | Make LazyLoad to re-check the DOM for `elements_selector` elements inside its `container`.                                                                       | Update LazyLoad after you added or removed DOM elements to the page.              |
| `loadAll()`    | Loads all the lazy elements right away _and_ stop observing them, no matter if they are inside or outside the viewport, no matter if they are hidden or visible. | To load all the remaining elements in advance                                     |
| `restoreAll()` | Restores DOM to its original state. Note that it doesn't destroy LazyLoad, so you probably want to use it along with `destroy()`.                                | Reset the DOM before a soft page navigation (SPA) occures, e.g. using TurboLinks. |
| `destroy()`    | Destroys the instance, unsetting instance variables and removing listeners.                                                                                      | Free up some memory. Especially useful for Single Page Applications.              |

**Static methods**

You can call the following static methods on the LazyLoad class itself (e.g. `LazyLoad.load(element, settings)`).

| Method name               | Effect                                                                                                                                                                                                                                                                                 | Use case                                                                                                                                                                                                           |
| ------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `load(element, settings)` | Immediately loads the lazy `element`. You can pass your custom options in the `settings` parameter. Note that the `elements_selector` option has no effect, since you are passing the element as a parameter. Also note that this method has effect only once on a specific `element`. | To load an `element` at mouseover or at any other event different than "entering the viewport"                                                                                                                     |
| `resetStatus(element)`    | Resets the internal status of the given `element`.                                                                                                                                                                                                                                     | To tell LazyLoad to consider this `element` again, for example: if you changed the `data-src` attribute after the previous `data-src` was loaded, call this method, then call `update()` on the LazyLoad instance. |

### Properties

You can use the following properties on any instance of LazyLoad.

| Property name  | Value                                                                                                                                                                                                                                      |
| -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `loadingCount` | The number of elements that are currently downloading from the network (limitedly to the ones managed by the instance of LazyLoad). This is particularly useful to understand whether or not is safe to destroy this instance of LazyLoad. |
| `toLoadCount`  | The number of elements that haven't been lazyloaded yet (limitedly to the ones managed by the instance of LazyLoad)                                                                                                                        |

---

**Love this project? 😍 [Buy me a coffee!](https://ko-fi.com/verlok)**

---

## 😯 All features, compared

A list of all vanilla-lazyload features, compared with other popular lazy loading libraries.

### vanilla-lazyload VS lazysizes

| It                                                                                                                       | vanilla-lazyload | lazysizes   |
| ------------------------------------------------------------------------------------------------------------------------ | ---------------- | ----------- |
| Is lightweight                                                                                                           | ✔ (2.8 kB)       | ✔ (3.4 kB)  |
| Is extendable                                                                                                            | ✔ (API)          | ✔ (plugins) |
| Is SEO friendly                                                                                                          | ✔                | ✔           |
| Optimized for INP (uses `IntersectionObserver` instead of [these]https://gist.github.com/paulirish/5d52fb081b3570c81e3a) | ✔                |             |
| Optimizes performance by cancelling downloads of images that already exited the viewport                                 | ✔                |             |
| Retries loading after network connection went off and on again                                                           | ✔                |             |
| Supports conditional usage of native lazyloading                                                                         | ✔                |             |
| Works with your DOM, your own classes and data-attributes                                                                | ✔                |             |
| Can lazyload responsive images                                                                                           | ✔                | ✔           |
| ...and automatically calculate the value of the `sizes` attribute                                                        |                  | ✔           |
| Can lazyload iframes                                                                                                     | ✔                | ✔           |
| Can lazyload animated SVGs                                                                                               | ✔                |             |
| Can lazyload videos                                                                                                      | ✔                |             |
| Can lazyload background images                                                                                           | ✔                |             |
| Can lazily execute code, when given elements enter the viewport                                                          | ✔                |             |
| Can restore DOM to its original state                                                                                    | ✔                |             |

Weights source: [bundlephobia](https://bundlephobia.com/). Find others table rows explanation below.

#### Is extendable

Both scripts are extendable, check out the [API](#-api).

#### Is SEO friendly

Both scripts **don't hide images/assets from search engines**. No matter what markup pattern you use. Search engines don't scroll/interact with your website. These scripts detects whether or not the user agent is capable to scroll. If not, they reveal all images instantly.

#### Optimizes performance by cancelling downloads of images that already exited the viewport

If your mobile users are on slow connections and scrolls down fast, vanilla-lazyload cancels the download of images that are still loading but already exited the viewport.

#### Retries loading after network connection went off and on

If your mobile users are on flaky connections and go offline and back online, vanilla-lazyload retries downloading the images that errored.

#### Supports conditional usage of native lazyloading

If your users are on a browser supporting native lazyloading and you want to use it, just set the `use_native` option to `true`.

#### Works with your DOM, your own classes and data-attributes

Both scripts work by default with the `data-src` attribute and the `lazy` class in your DOM, but on LazyLoad you can change it, e.g. using `data-origin` to migrate from other lazy loading script.

#### Can lazyload responsive images

Both scripts can lazyload images and responsive images by all kinds, e.g. `<img src="..." srcset="..." sizes="...">` and `<picture><source media="..." srcset="" ...><img ...></picture>`.

#### ...and automatically calculate the value of the `sizes` attribute

lazysizes is it can derive the value of the `sizes` attribute from your CSS by using Javascript.
vanilla-lazyload doesn't have this feature because of performance optimization reasons (the `sizes` attribute is useful to eagerly load responsive images when it's expressed in the markup, not when it's set by javascript).

#### Can lazyload iframes

Both scripts can lazyload the `iframe` tag.

#### Can lazyload animated SVGs

Only vanilla-lazyload can load animated SVGs via the `object` tag.

#### Can lazyload videos

Only vanilla-lazyload can lazyload the `video` tag, even with multiple `source`s.

#### Can lazyload background images

Only vanilla-lazyload can lazyload background images. And also multiple background images. And supporting HiDPI such as Retina and Super Retina display.

#### Can lazily execute code, when given elements enter the viewport

Check out the [lazy functions](#lazy-functions) section and learn how to execute code only when given elements enter the viewport.

#### Can restore DOM to its original state

Using the `restoreAll()` method, you can make LazyLoad restore all DOM manipulated from LazyLoad to how it was when the page was loaded the first time.

---

**Love this project? 😍 [Buy me a coffee!](https://ko-fi.com/verlok)**

---

## Tested on real browsers

This script is tested in every browser before every release using [BrowserStack](http://browserstack.com/) live, thanks to the BrowserStack Open Source initiative.

<a href="http://browserstack.com/"><img alt="BrowserStack Logo" src="./img/browserstack-logo-600x315.png"  width="300" height="158"/></a>


================================================
FILE: UPGRADE.md
================================================
# 🗺 HOW TO UPDATE FROM PREVIOUS VERSIONS

## Version 16 to 17

**If you were NOT setting the `elements_selector` option**

You should add the `lazy` class to your lazy images.

```html
<!-- FROM -->
<img data-src="lazyImage.jpg" alt="Lazy image" />
<!-- TO -->
<img class="lazy" data-src="lazyImage.jpg" alt="Lazy image" />
```

**ALTERNATIVELY**, you could set the `elements_selector` option to `"img"`

```js
const myLazyLoad = new LazyLoad({
  /* other options here */
  elements_selector: "img" // ADD THIS OPTION
});
```


**If you were using `cancel_on_exit: true`**

```js
// From
const myLazyLoad = new LazyLoad({
  /* other options here */
  cancel_on_exit: true // REMOVE THIS OPTION
});
```

You should remove `cancel_on_exit: true` from the settings.

---

**Love this project? 😍 [Buy me a coffee!](https://ko-fi.com/verlok)**

---

## Version 15 to 16

**If you were using the `callback_reveal` callback**

You should replace `callback_reveal` with `callback_loading` in your JS code.

**If you were using the instance `load(element)` method**

You should replace the `load(element)` with `LazyLoad.load(element, settings)`

```js
const myLazyLoad = new LazyLoad({
  /* options here */
});
// FROM
myLazyLoad.load(element);
// TO
LazyLoad.load(element, {
  /* options here */
});
```

Note that the settings object of the `load` method can be different. If none are provided, the default options will apply.

**If you were using `auto_unobserve: false`**

You should replace `auto_unobserve` with `unobserve_completed`.

```js
const myLazyLoad = new LazyLoad({
  // FROM
  auto_unobserve: false,
  // TO
  unobserve_completed: false
});
```

**If you were using the `load_delay` option**

You should change `load_delay: ___` with `cancel_on_exit: true`.

```js
const myLazyLoad = new LazyLoad({
  // FROM
  load_delay: 300,
  // TO
  cancel_on_exit: true
});
```

---

**Love this project? 😍 [Buy me a coffee!](https://ko-fi.com/verlok)**

---

## Version 14 to 15

**If you have background images loaded via `data-src`**

You should replace `data-src` with `data-bg` in your markup/DOM

```html
<!-- FROM -->
<div data-src="background.jpg">...</div>
<!-- TO -->
<div data-bg="background.jpg">...</div>
```

**ALTERNATIVELY**, you could pass `src` in the `data_bg` option

```js
new LazyLoad({
  /* other options here */
  data_bg: "src"
});
```

**If you have single background images loaded via `data-bg`**

You must remove the `url()` part from the `data-bg` attribute values

```html
<!-- FROM -->
<div data-bg="url(background.jpg)">...</div>
<!-- TO -->
<div data-bg="background.jpg">...</div>
```

**If you have multipe background images loaded via `data-bg`**

You must change the attribute to `data-bg-multi`

```html
<!-- FROM -->
<div data-bg="url(background1.jpg), url(background2.jpg)">...</div>
<!-- TO -->
<div data-bg-multi="url(background1.jpg), url(background2.jpg)">...</div>
```

---

**Love this project? 😍 [Buy me a coffee!](https://ko-fi.com/verlok)**

---

## Version 13 to 14

**If you are using `callback_reveal`**

You should replace it to `callback_loading`. `callback_reveal` still works but it will be removed in next versions

```js
// FROM
new LazyLoad({ /* other options? */ callback_reveal: () => {} });
// TO
new LazyLoad({ /* other options? */ callback_loading: () => {} });
```

---

**Love this project? 😍 [Buy me a coffee!](https://ko-fi.com/verlok)**

---

## Version 12 to 13

**If you are using `callback_set`**

You should replace it to `callback_reveal`. `callback_set` still works but it will be removed in next versions

```js
// FROM
new LazyLoad({ /* other options? */ callback_set: () => {} });
// TO
new LazyLoad({ /* other options? */ callback_reveal: () => {} });
```


================================================
FILE: _config.yml
================================================
theme: jekyll-theme-slate
title: vanilla-lazyload
description: LazyLoad is a fast, lightweight and flexible script that speeds up your web application by loading images only as they enter the viewport. LazyLoad supports responsive images.


================================================
FILE: bower.json
================================================
{
  "name": "vanilla-lazyload",
  "homepage": "https://verlok.github.io/vanilla-lazyload/",
  "authors": ["Andrea Verlicchi <andrea.verlicchi@gmail.com>"],
  "description": "A fast, lightweight script to load images as they enter the viewport. Supporting responsive images (both srcset + sizes and picture).",
  "main": "dist/lazyload.min.js",
  "keywords": [
    "lazy",
    "load",
    "responsive",
    "images",
    "picture",
    "srcset",
    "sizes",
    "progressive",
    "SEO",
    "JPEG",
    "performance",
    "perfmatters",
    "no-jquery",
    "vanilla"
  ],
  "license": "MIT",
  "ignore": [
    "**/.*",
    "node_modules",
    "bower_components",
    "test",
    "tests",
    "src",
    "img",
    "demos",
    "Gruntfile.js",
    "README.md",
    "todo.md",
    "favicon.ico",
    "index.html",
    "package.json"
  ]
}


================================================
FILE: currentFeature.md
================================================
# Current feature:

- Unobserve all elements on `loadAll()`. It's better for performance. It solves #469.
- Added some hidden images in the `load_all.html` demo

================================================
FILE: demos/async.html
================================================
<!DOCTYPE html>
<html>
  <head lang="en">
    <meta charset="UTF-8" />
    <title>
      Async loading - Lazyload demos
    </title>
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <style>
      ul,
      li {
        list-style-type: none;
        margin: 0;
        padding: 0;
      }

      a,
      img {
        display: block;
      }

      img {
        border: 0;
        width: 220px;
        height: 280px;
      }

      img:not([src]) {
        visibility: hidden;
      }

      /* Fixes Firefox anomaly during image load */
      @-moz-document url-prefix() {
        img:-moz-loading {
          visibility: hidden;
        }
      }
    </style>
  </head>

  <body>
    <h1>Async loading demo</h1>
    <div id="results1" class="results">
      <ul>
        <li>
          <a href="#/it/donna/stivaletti_cod44721746jj.html"
            ><img
              class="lazy"
              alt="Stivaletti"
              data-src="./images/440x560-01.webp"
              width="220"
              height="280"
          /></a>
        </li>
        <li>
          <a href="#/it/donna/open-toe_cod44740806jx.html"
            ><img
              class="lazy"
              alt="Open toe"
              data-src="./images/440x560-02.webp"
              width="220"
              height="280"
          /></a>
        </li>
        <li>
          <a href="#/it/donna/sneakers-tennis-shoes-basse_cod44735977gr.html"
            ><img
              class="lazy"
              alt="Sneakers &amp; Tennis"
              data-src="./images/440x560-03.webp"
              width="220"
              height="280"
          /></a>
        </li>
        <li>
          <a href="#/it/donna/sneakers-tennis-shoes-basse_cod44738717am.html"
            ><img
              class="lazy"
              alt="Sneakers &amp; Tennis shoes basse"
              data-src="./images/440x560-04.webp"
              width="220"
              height="280"
          /></a>
        </li>
        <li>
          <a href="#/it/donna/sneakers-tennis-shoes-alte_cod44739940cb.html"
            ><img
              class="lazy"
              alt="Sneakers &amp; Tennis shoes alte"
              data-src="./images/440x560-05.webp"
              width="220"
              height="280"
          /></a>
        </li>
        <li>
          <a href="#/it/donna/sneakers-tennis-shoes-alte_cod44740860xg.html"
            ><img
              class="lazy"
              alt="Sneakers &amp; Tennis shoes alte"
              data-src="./images/440x560-06.webp"
              width="220"
              height="280"
          /></a>
        </li>
        <li>
          <a href="#/it/donna/sneakers-tennis-shoes-basse_cod44738719vn.html"
            ><img
              class="lazy"
              alt="Sneakers &amp; Tennis shoes basse"
              data-src="./images/440x560-07.webp"
              width="220"
              height="280"
          /></a>
        </li>
        <li>
          <a href="#/it/donna/sneakers-tennis-shoes-basse_cod44739938wk.html"
            ><img
              class="lazy"
              alt="Sneakers &amp; Tennis shoes basse"
              data-src="./images/440x560-08.webp"
              width="220"
              height="280"
          /></a>
        </li>
        <li>
          <a href="#/it/donna/stivali_cod44736534fq.html"
            ><img
              class="lazy"
              alt="Stivali"
              data-src="./images/440x560-09.webp"
              width="220"
              height="280"
          /></a>
        </li>
        <li>
          <a href="#/it/donna/stivali_cod44735388ui.html"
            ><img
              class="lazy"
              alt="Stivali"
              data-src="./images/440x560-10.webp"
              width="220"
              height="280"
          /></a>
        </li>
        <li>
          <a href="#/it/donna/stivaletti_cod44739165ev.html"
            ><img
              class="lazy"
              alt="Stivaletti"
              data-src="./images/440x560-11.webp"
              width="220"
              height="280"
          /></a>
        </li>
        <li>
          <a href="#/it/donna/stivaletti_cod44739454hf.html"
            ><img
              class="lazy"
              alt="Stivaletti"
              data-src="./images/440x560-12.webp"
              width="220"
              height="280"
          /></a>
        </li>
        <li>
          <a href="#/it/donna/stivali_cod44719480km.html"
            ><img
              class="lazy"
              alt="Stivali"
              data-src="./images/440x560-13.webp"
              width="220"
              height="280"
          /></a>
        </li>
        <li>
          <a href="#/it/donna/stivaletti_cod44719687td.html"
            ><img
              class="lazy"
              alt="Stivaletti"
              data-src="./images/440x560-14.webp"
              width="220"
              height="280"
          /></a>
        </li>
        <li>
          <a href="#/it/donna/decollete_cod44721899ng.html"
            ><img
              class="lazy"
              alt="Décolleté"
              data-src="./images/440x560-15.webp"
              width="220"
              height="280"
          /></a>
        </li>
        <li>
          <a href="#/it/donna/mocassini_cod44721744sl.html"
            ><img
              class="lazy"
              alt="Mocassini"
              data-src="./images/440x560-16.webp"
              width="220"
              height="280"
          /></a>
        </li>
        <li>
          <a href="#/it/donna/stivaletti_cod44716730kr.html"
            ><img
              class="lazy"
              alt="Stivaletti"
              data-src="./images/440x560-17.webp"
              width="220"
              height="280"
          /></a>
        </li>
        <li>
          <a href="#/it/donna/decollete_cod44718734xl.html"
            ><img
              class="lazy"
              alt="Décolleté"
              data-src="./images/440x560-18.webp"
              width="220"
              height="280"
          /></a>
        </li>
        <li>
          <a href="#/it/donna/decollete_cod44721796uk.html"
            ><img
              class="lazy"
              alt="Décolleté"
              data-src="./images/440x560-19.webp"
              width="220"
              height="280"
          /></a>
        </li>
        <li>
          <a href="#/it/donna/francesine_cod44717679mj.html"
            ><img
              class="lazy"
              alt="Francesine"
              data-src="./images/440x560-20.webp"
              width="220"
              height="280"
          /></a>
        </li>
        <li>
          <a href="#/it/donna/stivaletti_cod44724594vu.html"
            ><img
              class="lazy"
              alt="Stivaletti"
              data-src="./images/440x560-21.webp"
              width="220"
              height="280"
          /></a>
        </li>
        <li>
          <a href="#/it/donna/decollete_cod44726148aq.html"
            ><img
              class="lazy"
              alt="Décolleté"
              data-src="./images/440x560-22.webp"
              width="220"
              height="280"
          /></a>
        </li>
        <li>
          <a href="#/it/donna/mocassini_cod44719629nt.html"
            ><img
              class="lazy"
              alt="Mocassini"
              data-src="./images/440x560-23.webp"
              width="220"
              height="280"
          /></a>
        </li>
        <li>
          <a href="#/it/donna/mocassini_cod44725329kq.html"
            ><img
              class="lazy"
              alt="Mocassini"
              data-src="./images/440x560-24.webp"
              width="220"
              height="280"
          /></a>
        </li>
        <li>
          <a href="#/it/donna/stivali_cod44724026qs.html"
            ><img
              class="lazy"
              alt="Stivali"
              data-src="./images/440x560-25.webp"
              width="220"
              height="280"
          /></a>
        </li>
        <li>
          <a href="#/it/donna/stivaletti_cod44720256gw.html"
            ><img
              class="lazy"
              alt="Stivaletti"
              data-src="./images/440x560-26.webp"
              width="220"
              height="280"
          /></a>
        </li>
        <li>
          <a href="#/it/donna/stivaletti_cod44722062id.html"
            ><img
              class="lazy"
              alt="Stivaletti"
              data-src="./images/440x560-27.webp"
              width="220"
              height="280"
          /></a>
        </li>
        <li>
          <a href="#/it/donna/mocassini_cod44722402rh.html"
            ><img
              class="lazy"
              alt="Mocassini"
              data-src="./images/440x560-28.webp"
              width="220"
              height="280"
          /></a>
        </li>
        <li>
          <a href="#/it/donna/stivaletti_cod44726296vu.html"
            ><img
              class="lazy"
              alt="Stivaletti"
              data-src="./images/440x560-29.webp"
              width="220"
              height="280"
          /></a>
        </li>
        <li>
          <a href="#/it/donna/stivaletti_cod44725755ct.html"
            ><img
              class="lazy"
              alt="Stivaletti"
              data-src="./images/440x560-30.webp"
              width="220"
              height="280"
          /></a>
        </li>
        <li>
          <a href="#/it/donna/stivaletti_cod44725348nv.html"
            ><img
              class="lazy"
              alt="Stivaletti"
              data-src="./images/440x560-31.webp"
              width="220"
              height="280"
          /></a>
        </li>
        <li>
          <a href="#/it/donna/stivaletti_cod44721879xx.html"
            ><img
              class="lazy"
              alt="Stivaletti"
              data-src="./images/440x560-32.webp"
              width="220"
              height="280"
          /></a>
        </li>
        <li>
          <a href="#/it/donna/cuissardes_cod44729472iq.html"
            ><img
              class="lazy"
              alt="Cuissardes"
              data-src="./images/440x560-33.webp"
              width="220"
              height="280"
          /></a>
        </li>
        <li>
          <a href="#/it/donna/decollete_cod44725388jv.html"
            ><img
              class="lazy"
              alt="Décolleté"
              data-src="./images/440x560-34.webp"
              width="220"
              height="280"
          /></a>
        </li>
        <li>
          <a href="#/it/donna/stivaletti_cod44721854ce.html"
            ><img
              class="lazy"
              alt="Stivaletti"
              data-src="./images/440x560-35.webp"
              width="220"
              height="280"
          /></a>
        </li>
        <li>
          <a href="#/it/donna/sneakers-tennis-shoes-basse_cod44727690jp.html"
            ><img
              class="lazy"
              alt="Sneakers &amp; Tennis shoes basse"
              data-src="./images/440x560-36.webp"
              width="220"
              height="280"
          /></a>
        </li>
        <li>
          <a href="#/it/donna/mocassini_cod44727501hh.html"
            ><img
              class="lazy"
              alt="Mocassini"
              data-src="./images/440x560-37.webp"
              width="220"
              height="280"
          /></a>
        </li>
        <li>
          <a href="#/it/donna/sneakers-tennis-shoes-basse_cod44727038aq.html"
            ><img
              class="lazy"
              alt="Sneakers &amp; Tennis shoes basse"
              data-src="./images/440x560-38.webp"
              width="220"
              height="280"
          /></a>
        </li>
        <li>
          <a href="#/it/donna/mocassini_cod44704882bq.html"
            ><img
              class="lazy"
              alt="Mocassini"
              data-src="./images/440x560-39.webp"
              width="220"
              height="280"
          /></a>
        </li>
        <li>
          <a href="#/it/donna/mocassini_cod44734002vc.html"
            ><img
              class="lazy"
              alt="Mocassini"
              data-src="./images/440x560-40.webp"
              width="220"
              height="280"
          /></a>
        </li>
      </ul>
    </div>
    <script>
      function logElementEvent(eventName, element) {
        console.log(Date.now(), eventName, element.getAttribute("data-src"));
      }

      var callback_enter = function (element) {
        logElementEvent("🔑 ENTERED", element);
      };
      var callback_exit = function (element) {
        logElementEvent("🚪 EXITED", element);
      };
      var callback_loading = function (element) {
        logElementEvent("⌚ LOADING", element);
      };
      var callback_loaded = function (element) {
        logElementEvent("👍 LOADED", element);
      };
      var callback_error = function (element) {
        logElementEvent("💀 ERROR", element);
        element.src =
          "./images/440x560-Error.webp";
      };
      var callback_finish = function () {
        logElementEvent("✔️ FINISHED", document.documentElement);
      };
      var callback_cancel = function (element) {
        logElementEvent("🔥 CANCEL", element);
      };

      window.lazyLoadOptions = {
        threshold: 0,
        // Assign the callbacks defined above
        callback_enter: callback_enter,
        callback_exit: callback_exit,
        callback_cancel: callback_cancel,
        callback_loading: callback_loading,
        callback_loaded: callback_loaded,
        callback_error: callback_error,
        callback_finish: callback_finish
      };
      window.addEventListener(
        "LazyLoad::Initialized",
        function (e) {
          console.log(e.detail.instance);
        },
        false
      );
    </script>
    <script async src="../dist/lazyload.min.js"></script>
  </body>
</html>


================================================
FILE: demos/async_multiple.html
================================================
<!DOCTYPE html>
<html>
  <head lang="en">
    <meta charset="UTF-8" />
    <title>
      Async loading, multiple instances - Lazyload demos
    </title>
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <style type="text/css">
      ul,
      li {
        list-style-type: none;
        margin: 0;
        padding: 0;
      }

      a,
      img {
        display: block;
      }

      img {
        border: 0;
        width: 220px;
        height: 280px;
      }

      img:not([src]) {
        visibility: hidden;
      }

      .flex {
        display: flex;
      }

      .results {
        height: 564px;
        overflow: scroll;
        border: 1px dotted #f00;
        flex-grow: 1;
      }
    </style>
  </head>

  <body>
    <h1>Async loading, multiple instances demo</h1>
    <div class="flex">
      <div id="results1" class="results">
        <ul>
          <li>
            <a href="#/it/donna/stivaletti_cod44721746jj.html"
              ><img
                alt="Stivaletti"
                src="./images/440x560-01.webp"
                width="220"
                height="280"
            /></a>
          </li>
          <li>
            <a href="#/it/donna/open-toe_cod44740806jx.html"
              ><img
                alt="Open toe"
                src="./images/440x560-02.webp"
                width="220"
                height="280"
            /></a>
          </li>
          <li>
            <a href="#/it/donna/sneakers-tennis-shoes-basse_cod44735977gr.html"
              ><img
                alt="Sneakers &amp; Tennis"
                class="lazy"
                data-src="./images/440x560-03.webp"
                width="220"
                height="280"
            /></a>
          </li>
          <li>
            <a href="#/it/donna/sneakers-tennis-shoes-basse_cod44738717am.html"
              ><img
                alt="Sneakers &amp; Tennis shoes basse"
                class="lazy"
                data-src="./images/440x560-04.webp"
                width="220"
                height="280"
            /></a>
          </li>
          <li>
            <a href="#/it/donna/sneakers-tennis-shoes-alte_cod44739940cb.html"
              ><img
                alt="Sneakers &amp; Tennis shoes alte"
                class="lazy"
                data-src="./images/440x560-05.webp"
                width="220"
                height="280"
            /></a>
          </li>
          <li>
            <a href="#/it/donna/sneakers-tennis-shoes-alte_cod44740860xg.html"
              ><img
                alt="Sneakers &amp; Tennis shoes alte"
                class="lazy"
                data-src="./images/440x560-06.webp"
                width="220"
                height="280"
            /></a>
          </li>
          <li>
            <a href="#/it/donna/sneakers-tennis-shoes-basse_cod44738719vn.html"
              ><img
                alt="Sneakers &amp; Tennis shoes basse"
                class="lazy"
                data-src="./images/440x560-07.webp"
                width="220"
                height="280"
            /></a>
          </li>
          <li>
            <a href="#/it/donna/sneakers-tennis-shoes-basse_cod44739938wk.html"
              ><img
                alt="Sneakers &amp; Tennis shoes basse"
                class="lazy"
                data-src="./images/440x560-08.webp"
                width="220"
                height="280"
            /></a>
          </li>
          <li>
            <a href="#/it/donna/stivali_cod44736534fq.html"
              ><img
                alt="Stivali"
                class="lazy"
                data-src="./images/440x560-09.webp"
                width="220"
                height="280"
            /></a>
          </li>
          <li>
            <a href="#/it/donna/stivali_cod44735388ui.html"
              ><img
                alt="Stivali"
                class="lazy"
                data-src="./images/440x560-10.webp"
                width="220"
                height="280"
            /></a>
          </li>
          <li>
            <a href="#/it/donna/stivaletti_cod44739165ev.html"
              ><img
                alt="Stivaletti"
                class="lazy"
                data-src="./images/440x560-11.webp"
                width="220"
                height="280"
            /></a>
          </li>
          <li>
            <a href="#/it/donna/stivaletti_cod44739454hf.html"
              ><img
                alt="Stivaletti"
                class="lazy"
                data-src="./images/440x560-12.webp"
                width="220"
                height="280"
            /></a>
          </li>
          <li>
            <a href="#/it/donna/stivali_cod44719480km.html"
              ><img
                alt="Stivali"
                class="lazy"
                data-src="./images/440x560-13.webp"
                width="220"
                height="280"
            /></a>
          </li>
          <li>
            <a href="#/it/donna/stivaletti_cod44719687td.html"
              ><img
                alt="Stivaletti"
                class="lazy"
                data-src="./images/440x560-14.webp"
                width="220"
                height="280"
            /></a>
          </li>
          <li>
            <a href="#/it/donna/decollete_cod44721899ng.html"
              ><img
                alt="Décolleté"
                class="lazy"
                data-src="./images/440x560-15.webp"
                width="220"
                height="280"
            /></a>
          </li>
          <li>
            <a href="#/it/donna/mocassini_cod44721744sl.html"
              ><img
                alt="Mocassini"
                class="lazy"
                data-src="./images/440x560-16.webp"
                width="220"
                height="280"
            /></a>
          </li>
          <li>
            <a href="#/it/donna/stivaletti_cod44716730kr.html"
              ><img
                alt="Stivaletti"
                class="lazy"
                data-src="./images/440x560-17.webp"
                width="220"
                height="280"
            /></a>
          </li>
          <li>
            <a href="#/it/donna/decollete_cod44718734xl.html"
              ><img
                alt="Décolleté"
                class="lazy"
                data-src="./images/440x560-18.webp"
                width="220"
                height="280"
            /></a>
          </li>
          <li>
            <a href="#/it/donna/decollete_cod44721796uk.html"
              ><img
                alt="Décolleté"
                class="lazy"
                data-src="./images/440x560-19.webp"
                width="220"
                height="280"
            /></a>
          </li>
        </ul>
      </div>
      <div id="results2" class="results">
        <ul>
          <li>
            <a href="#/it/donna/francesine_cod44717679mj.html"
              ><img
                alt="Francesine"
                src="./images/440x560-20.webp"
                width="220"
                height="280"
            /></a>
          </li>
          <li>
            <a href="#/it/donna/stivaletti_cod44724594vu.html"
              ><img
                alt="Stivaletti"
                src="./images/440x560-21.webp"
                width="220"
                height="280"
            /></a>
          </li>
          <li>
            <a href="#/it/donna/decollete_cod44726148aq.html"
              ><img
                alt="Décolleté"
                class="lazy"
                data-src="./images/440x560-22.webp"
                width="220"
                height="280"
            /></a>
          </li>
          <li>
            <a href="#/it/donna/mocassini_cod44719629nt.html"
              ><img
                alt="Mocassini"
                class="lazy"
                data-src="./images/440x560-23.webp"
                width="220"
                height="280"
            /></a>
          </li>
          <li>
            <a href="#/it/donna/mocassini_cod44725329kq.html"
              ><img
                alt="Mocassini"
                class="lazy"
                data-src="./images/440x560-24.webp"
                width="220"
                height="280"
            /></a>
          </li>
          <li>
            <a href="#/it/donna/stivali_cod44724026qs.html"
              ><img
                alt="Stivali"
                class="lazy"
                data-src="./images/440x560-25.webp"
                width="220"
                height="280"
            /></a>
          </li>
          <li>
            <a href="#/it/donna/stivaletti_cod44720256gw.html"
              ><img
                alt="Stivaletti"
                class="lazy"
                data-src="./images/440x560-26.webp"
                width="220"
                height="280"
            /></a>
          </li>
          <li>
            <a href="#/it/donna/stivaletti_cod44722062id.html"
              ><img
                alt="Stivaletti"
                class="lazy"
                data-src="./images/440x560-27.webp"
                width="220"
                height="280"
            /></a>
          </li>
          <li>
            <a href="#/it/donna/mocassini_cod44722402rh.html"
              ><img
                alt="Mocassini"
                class="lazy"
                data-src="./images/440x560-28.webp"
                width="220"
                height="280"
            /></a>
          </li>
          <li>
            <a href="#/it/donna/stivaletti_cod44726296vu.html"
              ><img
                alt="Stivaletti"
                class="lazy"
                data-src="./images/440x560-29.webp"
                width="220"
                height="280"
            /></a>
          </li>
          <li>
            <a href="#/it/donna/stivaletti_cod44725755ct.html"
              ><img
                alt="Stivaletti"
                class="lazy"
                data-src="./images/440x560-30.webp"
                width="220"
                height="280"
            /></a>
          </li>
          <li>
            <a href="#/it/donna/stivaletti_cod44725348nv.html"
              ><img
                alt="Stivaletti"
                class="lazy"
                data-src="./images/440x560-31.webp"
                width="220"
                height="280"
            /></a>
          </li>
          <li>
            <a href="#/it/donna/stivaletti_cod44721879xx.html"
              ><img
                alt="Stivaletti"
                class="lazy"
                data-src="./images/440x560-32.webp"
                width="220"
                height="280"
            /></a>
          </li>
          <li>
            <a href="#/it/donna/cuissardes_cod44729472iq.html"
              ><img
                alt="Cuissardes"
                class="lazy"
                data-src="./images/440x560-33.webp"
                width="220"
                height="280"
            /></a>
          </li>
          <li>
            <a href="#/it/donna/decollete_cod44725388jv.html"
              ><img
                alt="Décolleté"
                class="lazy"
                data-src="./images/440x560-34.webp"
                width="220"
                height="280"
            /></a>
          </li>
          <li>
            <a href="#/it/donna/stivaletti_cod44721854ce.html"
              ><img
                alt="Stivaletti"
                class="lazy"
                data-src="./images/440x560-35.webp"
                width="220"
                height="280"
            /></a>
          </li>
          <li>
            <a href="#/it/donna/sneakers-tennis-shoes-basse_cod44727690jp.html"
              ><img
                alt="Sneakers &amp; Tennis shoes basse"
                class="lazy"
                data-src="./images/440x560-36.webp"
                width="220"
                height="280"
            /></a>
          </li>
          <li>
            <a href="#/it/donna/mocassini_cod44727501hh.html"
              ><img
                alt="Mocassini"
                class="lazy"
                data-src="./images/440x560-37.webp"
                width="220"
                height="280"
            /></a>
          </li>
          <li>
            <a href="#/it/donna/sneakers-tennis-shoes-basse_cod44727038aq.html"
              ><img
                alt="Sneakers &amp; Tennis shoes basse"
                class="lazy"
                data-src="./images/440x560-38.webp"
                width="220"
                height="280"
            /></a>
          </li>
          <li>
            <a href="#/it/donna/mocassini_cod44704882bq.html"
              ><img
                alt="Mocassini"
                class="lazy"
                data-src="./images/440x560-39.webp"
                width="220"
                height="280"
            /></a>
          </li>
          <li>
            <a href="#/it/donna/mocassini_cod44734002vc.html"
              ><img
                alt="Mocassini"
                class="lazy"
                data-src="./images/440x560-40.webp"
                width="220"
                height="280"
            /></a>
          </li>
        </ul>
      </div>
    </div>

    <script>
      function logElementEvent(eventName, element) {
        console.log(Date.now(), eventName, element.getAttribute("data-src"));
      }

      var callback_enter = function (element) {
        logElementEvent("🔑 ENTERED", element);
      };
      var callback_exit = function (element) {
        logElementEvent("🚪 EXITED", element);
      };
      var callback_loading = function (element) {
        logElementEvent("⌚ LOADING", element);
      };
      var callback_loaded = function (element) {
        logElementEvent("👍 LOADED", element);
      };
      var callback_error = function (element) {
        logElementEvent("💀 ERROR", element);
        element.src =
          "./images/440x560-Error.webp";
      };
      var callback_finish = function () {
        logElementEvent("✔️ FINISHED", document.documentElement);
      };
      var callback_cancel = function (element) {
        logElementEvent("🔥 CANCEL", element);
      };

      window.lazyLoadInstances = [];
      window.lazyLoadOptions = [
        {
          container: document.getElementById("results1"),
          // Assign the callbacks defined above
          callback_enter: callback_enter,
          callback_exit: callback_exit,
          callback_cancel: callback_cancel,
          callback_loading: callback_loading,
          callback_loaded: callback_loaded,
          callback_error: callback_error,
          callback_finish: callback_finish
        },
        {
          container: document.getElementById("results2"),
          // Assign the callbacks defined above
          callback_enter: callback_enter,
          callback_exit: callback_exit,
          callback_loading: callback_loading,
          callback_loaded: callback_loaded,
          callback_error: callback_error,
          callback_finish: callback_finish
        }
      ];
      window.addEventListener(
        "LazyLoad::Initialized",
        function (e) {
          var instance = e.detail.instance;
          console.log(instance);
          lazyLoadInstances.push(instance);
        },
        false
      );
    </script>
    <script async src="../dist/lazyload.min.js"></script>
  </body>
</html>


================================================
FILE: demos/background_images.html
================================================
<!DOCTYPE html>
<html>
  <head lang="en">
    <meta charset="UTF-8" />
    <title>Background images - Lazyload demos</title>
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <style>
      ul,
      li {
        list-style-type: none;
        margin: 0;
        padding: 0;
      }

      a {
        display: block;
        width: 220px;
        height: 280px;
        background-size: 220px 280px;
      }

      a.multiple {
        width: 440px;
        background-repeat: no-repeat;
        background-position: left, right;
      }
    </style>
  </head>

  <body>
    <h1>Background images demo</h1>
    <div id="results1" class="results">
      <ul>
        <li>
          <a
            class="lazy"
            href="#"
            data-bg="./images/220x280-01.webp"
            data-bg-hidpi="./images/440x560-01.webp"
          ></a>
        </li>
        <li>
          <a class="lazy" href="#" data-bg="./images/220x280-02.webp"></a>
        </li>
        <li>
          <a
            class="lazy"
            href="#"
            data-bg="./images/220x280-03.webp"
            data-bg-hidpi="./images/440x560-03.webp"
          ></a>
        </li>
        <li>
          <a class="lazy" href="#" data-bg="./images/220x280-04.webp"></a>
        </li>
        <li>
          <a
            class="lazy"
            href="#"
            data-bg="./images/220x280-05.webp"
            data-bg-hidpi="./images/440x560-05.webp"
          ></a>
        </li>
        <li>
          <a class="lazy" href="#" data-bg="./images/220x280-06.webp"></a>
        </li>
        <li>
          <a
            class="lazy"
            href="#"
            data-bg="./images/220x280-07.webp"
            data-bg-hidpi="./images/440x560-07.webp"
          ></a>
        </li>
        <li>
          <a
            class="lazy"
            href="#"
            data-bg="./images/220x280-08.webp"
            data-bg-hidpi="./images/440x560-08.webp"
          ></a>
        </li>
        <li>
          <a
            class="lazy"
            href="#"
            data-bg="./images/220x280-09.webp"
            data-bg-hidpi="./images/440x560-09.webp"
          ></a>
        </li>
        <li>
          <a
            class="lazy"
            href="#"
            data-bg="./images/220x280-10.webp"
            data-bg-hidpi="./images/440x560-10.webp"
          ></a>
        </li>
        <li>
          <a
            class="lazy"
            href="#"
            data-bg="./images/220x280-11.webp"
            data-bg-hidpi="./images/440x560-11.webp"
          ></a>
        </li>
        <li>
          <a
            class="lazy"
            href="#"
            data-bg="./images/220x280-12.webp"
            data-bg-hidpi="./images/440x560-12.webp"
          ></a>
        </li>
        <li>
          <a
            class="lazy"
            href="#"
            data-bg="./images/220x280-13.webp"
            data-bg-hidpi="./images/440x560-13.webp"
          ></a>
        </li>
        <li>
          <a
            class="lazy"
            href="#"
            data-bg="./images/220x280-14.webp"
            data-bg-hidpi="./images/440x560-14.webp"
          ></a>
        </li>
        <li>
          <a
            class="lazy"
            href="#"
            data-bg="./images/220x280-15.webp"
            data-bg-hidpi="./images/440x560-15.webp"
          ></a>
        </li>
        <li>
          <a
            class="lazy"
            href="#"
            data-bg="./images/220x280-16.webp"
            data-bg-hidpi="./images/440x560-16.webp"
          ></a>
        </li>
        <li>
          <a
            class="lazy"
            href="#"
            data-bg="./images/220x280-17.webp"
            data-bg-hidpi="./images/440x560-17.webp"
          ></a>
        </li>
        <li>
          <a
            class="lazy"
            href="#"
            data-bg="./images/220x280-18.webp"
            data-bg-hidpi="./images/440x560-18.webp"
          ></a>
        </li>
        <li>
          <a
            class="lazy"
            href="#"
            data-bg="./images/220x280-19.webp"
            data-bg-hidpi="./images/440x560-19.webp"
          ></a>
        </li>
        <li>
          <a
            class="lazy"
            href="#"
            data-bg="./images/220x280-20.webp"
            data-bg-hidpi="./images/440x560-20.webp"
          ></a>
        </li>
        <li>
          <a
            class="lazy"
            href="#"
            data-bg="./images/220x280-21.webp"
            data-bg-hidpi="./images/440x560-21.webp"
          ></a>
        </li>
        <li>
          <a
            class="lazy"
            href="#"
            data-bg="./images/220x280-22.webp"
            data-bg-hidpi="./images/440x560-22.webp"
          ></a>
        </li>
        <li>
          <a
            class="lazy"
            href="#"
            data-bg="./images/220x280-23.webp"
            data-bg-hidpi="./images/440x560-23.webp"
          ></a>
        </li>
        <li>
          <a
            class="lazy"
            href="#"
            data-bg="./images/220x280-24.webp"
            data-bg-hidpi="./images/440x560-24.webp"
          ></a>
        </li>
        <li>
          <a
            class="lazy"
            href="#"
            data-bg="./images/220x280-25.webp"
            data-bg-hidpi="./images/440x560-25.webp"
          ></a>
        </li>
        <li>
          <a
            class="lazy"
            href="#"
            data-bg="./images/220x280-26.webp"
            data-bg-hidpi="./images/440x560-26.webp"
          ></a>
        </li>
        <li>
          <a
            class="lazy"
            href="#"
            data-bg="./images/220x280-27.webp"
            data-bg-hidpi="./images/440x560-27.webp"
          ></a>
        </li>
        <li>
          <a
            class="lazy"
            href="#"
            data-bg="./images/220x280-28.webp"
            data-bg-hidpi="./images/440x560-28.webp"
          ></a>
        </li>
        <li>
          <a
            class="lazy"
            href="#"
            data-bg="./images/220x280-29.webp"
            data-bg-hidpi="./images/440x560-29.webp"
          ></a>
        </li>
        <li>
          <a
            class="lazy"
            href="#"
            data-bg="./images/220x280-30.webp"
            data-bg-hidpi="./images/440x560-30.webp"
          ></a>
        </li>
        <li>
          <a
            class="lazy"
            href="#"
            data-bg="./images/220x280-31.webp"
            data-bg-hidpi="./images/440x560-31.webp"
          ></a>
        </li>
        <li>
          <a
            class="lazy"
            href="#"
            data-bg="./images/220x280-32.webp"
            data-bg-hidpi="./images/440x560-32.webp"
          ></a>
        </li>
        <li>
          <a
            class="lazy"
            href="#"
            data-bg="./images/220x280-33.webp"
            data-bg-hidpi="./images/440x560-33.webp"
          ></a>
        </li>
        <li>
          <a
            class="lazy"
            href="#"
            data-bg="./images/220x280-34.webp"
            data-bg-hidpi="./images/440x560-34.webp"
          ></a>
        </li>
        <li>
          <a
            class="lazy"
            href="#"
            data-bg="./images/220x280-35.webp"
            data-bg-hidpi="./images/440x560-35.webp"
          ></a>
        </li>
        <li>
          <a
            class="lazy"
            href="#"
            data-bg="./images/220x280-36.webp"
            data-bg-hidpi="./images/440x560-36.webp"
          ></a>
        </li>
        <li>
          <a
            class="lazy"
            href="#"
            data-bg="./images/220x280-37.webp"
            data-bg-hidpi="./images/440x560-37.webp"
          ></a>
        </li>
        <li>
          <a
            class="lazy"
            href="#"
            data-bg="./images/220x280-38.webp"
            data-bg-hidpi="./images/440x560-38.webp"
          ></a>
        </li>
        <li>
          <a
            class="lazy"
            href="#"
            data-bg="./images/220x280-39.webp"
            data-bg-hidpi="./images/440x560-39.webp"
          ></a>
        </li>
      </ul>
    </div>
    <script src="../dist/lazyload.min.js"></script>
    <script>
      function logElementEvent(eventName, element) {
        console.log(Date.now(), eventName, element.getAttribute("data-bg88da112-bg-hidpi=bg"));
      }

      var callback_enter = function (element) {
        logElementEvent("🔑 ENTERED", element);
      };
      var callback_exit = function (element) {
        logElementEvent("🚪 EXITED", element);
      };
      var callback_loading = function (element) {
        logElementEvent("⌚ LOADING", element);
      };
      var callback_loaded = function (element) {
        logElementEvent("👍 LOADED", element);
      };
      var callback_error = function (element) {
        logElementEvent("💀 ERROR", element);
        element.style.backgroundImage = 'url("./images/440x560-Error.webp")';
      };
      var callback_finish = function () {
        logElementEvent("✔️ FINISHED", document.documentElement);
      };
      var callback_cancel = function (element) {
        logElementEvent("🔥 CANCEL", element);
      };

      LL = new LazyLoad({
        // Assign the callbacks defined above
        callback_enter: callback_enter,
        callback_exit: callback_exit,
        callback_cancel: callback_cancel,
        callback_loading: callback_loading,
        callback_loaded: callback_loaded,
        callback_error: callback_error,
        callback_finish: callback_finish
      });
    </script>
  </body>
</html>


================================================
FILE: demos/background_images_image-set.html
================================================
<!DOCTYPE html>
<html>
  <head lang="en">
    <meta charset="UTF-8" />
    <title>Background images with "image-set" - Lazyload demos</title>
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <style>
      ul,
      li {
        list-style-type: none;
        margin: 0;
        padding: 0;
      }

      a {
        display: block;
        width: 220px;
        height: 280px;
        background-size: 220px 280px;
      }

      a.multiple {
        width: 440px;
        background-repeat: no-repeat;
        background-position: left, right;
      }
    </style>
  </head>

  <body>
    <h1>Background images with <q>image-set</q> demo</h1>
    <div id="results1" class="results">
      <ul>
        <li>
          <a
            href="#"
            style="
              background-image: image-set(
                url('./images/220x280-01.webp') 1x,
                url('./images/440x560-01.webp') 2x
              );
            "
          ></a>
        </li>
        <li>
          <a
            class="multiple"
            href="#"
            style="
              background-image: image-set(
                  url('./images/220x280-L-02.webp') 1x,
                  url('./images/440x560-L-02.webp') 2x
                ),
                image-set(
                  url('./images/220x280-R-02.webp') 1x,
                  url('./images/440x560-R-02.webp') 2x
                );
            "
          ></a>
        </li>
        <li>
          <a
            class="lazy"
            href="#"
            data-bg-set='url("./images/220x280-03.webp") 1x, url("./images/440x560-03.webp") 2x'
          ></a>
        </li>
        <li>
          <a
            class="lazy multiple"
            href="#"
            data-bg-set='url("./images/220x280-L-04.webp") 1x, url("./images/440x560-L-04.webp") 2x | url("./images/220x280-R-04.webp") 1x, url("./images/440x560-R-04.webp") 2x'
          ></a>
        </li>
        <li>
          <a
            class="lazy"
            href="#"
            data-bg-set='url("./images/220x280-05.webp") 1x, url("./images/440x560-05.webp") 2x'
          ></a>
        </li>
        <li>
          <a
            class="lazy"
            href="#"
            data-bg-set='url("./images/220x280-06.webp") 1x, url("./images/440x560-06.webp") 2x'
          ></a>
        </li>
        <li>
          <a
            class="lazy"
            href="#"
            data-bg-set='url("./images/220x280-07.webp") 1x, url("./images/440x560-07.webp") 2x'
          ></a>
        </li>
        <li>
          <a
            class="lazy"
            href="#"
            data-bg-set='url("./images/220x280-08.webp") 1x, url("./images/440x560-08.webp") 2x'
          ></a>
        </li>
        <li>
          <a
            class="lazy"
            href="#"
            data-bg-set='url("./images/220x280-09.webp") 1x, url("./images/440x560-09.webp") 2x'
          ></a>
        </li>
        <li>
          <a
            class="lazy"
            href="#"
            data-bg-set='url("./images/220x280-10.webp") 1x, url("./images/440x560-10.webp") 2x'
          ></a>
        </li>
        <li>
          <a
            class="lazy"
            href="#"
            data-bg-set='url("./images/220x280-11.webp") 1x, url("./images/440x560-11.webp") 2x'
          ></a>
        </li>
        <li>
          <a
            class="lazy"
            href="#"
            data-bg-set='url("./images/220x280-12.webp") 1x, url("./images/440x560-12.webp") 2x'
          ></a>
        </li>
        <li>
          <a
            class="lazy"
            href="#"
            data-bg-set='url("./images/220x280-13.webp") 1x, url("./images/440x560-13.webp") 2x'
          ></a>
        </li>
        <li>
          <a
            class="lazy"
            href="#"
            data-bg-set='url("./images/220x280-14.webp") 1x, url("./images/440x560-14.webp") 2x'
          ></a>
        </li>
        <li>
          <a
            class="lazy"
            href="#"
            data-bg-set='url("./images/220x280-15.webp") 1x, url("./images/440x560-15.webp") 2x'
          ></a>
        </li>
        <li>
          <a
            class="lazy"
            href="#"
            data-bg-set='url("./images/220x280-16.webp") 1x, url("./images/440x560-16.webp") 2x'
          ></a>
        </li>
        <li>
          <a
            class="lazy"
            href="#"
            data-bg-set='url("./images/220x280-17.webp") 1x, url("./images/440x560-17.webp") 2x'
          ></a>
        </li>
        <li>
          <a
            class="lazy"
            href="#"
            data-bg-set='url("./images/220x280-18.webp") 1x, url("./images/440x560-18.webp") 2x'
          ></a>
        </li>
        <li>
          <a
            class="lazy"
            href="#"
            data-bg-set='url("./images/220x280-19.webp") 1x, url("./images/440x560-19.webp") 2x'
          ></a>
        </li>
        <li>
          <a
            class="lazy"
            href="#"
            data-bg-set='url("./images/220x280-20.webp") 1x, url("./images/440x560-20.webp") 2x'
          ></a>
        </li>
        <li>
          <a
            class="lazy"
            href="#"
            data-bg-set='url("./images/220x280-21.webp") 1x, url("./images/440x560-21.webp") 2x'
          ></a>
        </li>
        <li>
          <a
            class="lazy"
            href="#"
            data-bg-set='url("./images/220x280-22.webp") 1x, url("./images/440x560-22.webp") 2x'
          ></a>
        </li>
        <li>
          <a
            class="lazy"
            href="#"
            data-bg-set='url("./images/220x280-23.webp") 1x, url("./images/440x560-23.webp") 2x'
          ></a>
        </li>
        <li>
          <a
            class="lazy"
            href="#"
            data-bg-set='url("./images/220x280-24.webp") 1x, url("./images/440x560-24.webp") 2x'
          ></a>
        </li>
        <li>
          <a
            class="lazy"
            href="#"
            data-bg-set='url("./images/220x280-25.webp") 1x, url("./images/440x560-25.webp") 2x'
          ></a>
        </li>
        <li>
          <a
            class="lazy"
            href="#"
            data-bg-set='url("./images/220x280-26.webp") 1x, url("./images/440x560-26.webp") 2x'
          ></a>
        </li>
        <li>
          <a
            class="lazy"
            href="#"
            data-bg-set='url("./images/220x280-27.webp") 1x, url("./images/440x560-27.webp") 2x'
          ></a>
        </li>
        <li>
          <a
            class="lazy"
            href="#"
            data-bg-set='url("./images/220x280-28.webp") 1x, url("./images/440x560-28.webp") 2x'
          ></a>
        </li>
        <li>
          <a
            class="lazy"
            href="#"
            data-bg-set='url("./images/220x280-29.webp") 1x, url("./images/440x560-29.webp") 2x'
          ></a>
        </li>
        <li>
          <a
            class="lazy"
            href="#"
            data-bg-set='url("./images/220x280-30.webp") 1x, url("./images/440x560-30.webp") 2x'
          ></a>
        </li>
        <li>
          <a
            class="lazy"
            href="#"
            data-bg-set='url("./images/220x280-31.webp") 1x, url("./images/440x560-31.webp") 2x'
          ></a>
        </li>
        <li>
          <a
            class="lazy"
            href="#"
            data-bg-set='url("./images/220x280-32.webp") 1x, url("./images/440x560-32.webp") 2x'
          ></a>
        </li>
        <li>
          <a
            class="lazy"
            href="#"
            data-bg-set='url("./images/220x280-33.webp") 1x, url("./images/440x560-33.webp") 2x'
          ></a>
        </li>
        <li>
          <a
            class="lazy"
            href="#"
            data-bg-set='url("./images/220x280-34.webp") 1x, url("./images/440x560-34.webp") 2x'
          ></a>
        </li>
        <li>
          <a
            class="lazy"
            href="#"
            data-bg-set='url("./images/220x280-35.webp") 1x, url("./images/440x560-35.webp") 2x'
          ></a>
        </li>
        <li>
          <a
            class="lazy"
            href="#"
            data-bg-set='url("./images/220x280-36.webp") 1x, url("./images/440x560-36.webp") 2x'
          ></a>
        </li>
        <li>
          <a
            class="lazy"
            href="#"
            data-bg-set='url("./images/220x280-37.webp") 1x, url("./images/440x560-37.webp") 2x'
          ></a>
        </li>
        <li>
          <a
            class="lazy"
            href="#"
            data-bg-set='url("./images/220x280-38.webp") 1x, url("./images/440x560-38.webp") 2x'
          ></a>
        </li>
        <li>
          <a
            class="lazy"
            href="#"
            data-bg-set='url("./images/220x280-39.webp") 1x, url("./images/440x560-39.webp") 2x'
          ></a>
        </li>
      </ul>
    </div>
    <script src="../dist/lazyload.min.js"></script>
    <script>
      function logElementEvent(eventName, element) {
        console.log(Date.now(), eventName, element.getAttribute("data-bg88da112-bg-hidpi=bg"));
      }

      var callback_enter = function (element) {
        logElementEvent("🔑 ENTERED", element);
      };
      var callback_exit = function (element) {
        logElementEvent("🚪 EXITED", element);
      };
      var callback_loading = function (element) {
        logElementEvent("⌚ LOADING", element);
      };
      var callback_loaded = function (element) {
        logElementEvent("👍 LOADED", element);
      };
      var callback_error = function (element) {
        logElementEvent("💀 ERROR", element);
        element.style.backgroundImage = 'url("./images/440x560-Error.webp")';
      };
      var callback_finish = function () {
        logElementEvent("✔️ FINISHED", document.documentElement);
      };
      var callback_cancel = function (element) {
        logElementEvent("🔥 CANCEL", element);
      };

      LL = new LazyLoad({
        // Assign the callbacks defined above
        callback_enter: callback_enter,
        callback_exit: callback_exit,
        callback_cancel: callback_cancel,
        callback_loading: callback_loading,
        callback_loaded: callback_loaded,
        callback_error: callback_error,
        callback_finish: callback_finish
      });
    </script>
  </body>
</html>


================================================
FILE: demos/background_images_multi.html
================================================
<!DOCTYPE html>
<html>
  <head lang="en">
    <meta charset="UTF-8" />
    <title>Multiple background images - Lazyload demos</title>
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <style>
      ul,
      li {
        list-style-type: none;
        margin: 0;
        padding: 0;
      }

      a {
        display: block;
        width: 220px;
        height: 280px;
        background-size: 220px 280px;
      }

      a.multiple {
        width: 440px;
        background-repeat: no-repeat;
        background-position: left, right;
      }
    </style>
  </head>

  <body>
    <h1>Multiple background images demo</h1>
    <div id="results1" class="results">
      <ul>
        <li>
          <a
            class="lazy"
            href="#/it/donna/stivaletti_cod44721746jj.html"
            data-bg-multi='url("./images/220x280-01.webp")'
            data-bg-multi-hidpi='url("./images/440x560-01.webp")'
          ></a>
        </li>
        <li>
          <a
            class="lazy"
            href="#/it/donna/open-toe_cod44740806jx.html"
            data-bg-multi='url("./images/220x280-02.webp")'
          ></a>
        </li>
        <li>
          <a
            class="lazy"
            href="#/it/donna/sneakers-tennis-shoes-basse_cod44735977gr.html"
            data-bg-multi='url("./images/220x280-L-03.webp"), url("./images/440x560-R-03.webp")'
            data-bg-multi-hidpi='url("./images/440x560-L-03.webp"), url("./images/440x560-R-03.webp")'
            class="multiple"
          ></a>
        </li>
        <li>
          <a
            class="lazy"
            href="#/it/donna/sneakers-tennis-shoes-basse_cod44738717am.html"
            data-bg-multi='url("./images/220x280-03.webp")'
          ></a>
        </li>
        <li>
          <a
            class="lazy"
            href="#/it/donna/sneakers-tennis-shoes-alte_cod44739940cb.html"
            data-bg-multi='url("./images/220x280-04.webp")'
            data-bg-multi-hidpi='url("./images/440x560-04.webp")'
          ></a>
        </li>
        <li>
          <a
            class="lazy"
            href="#/it/donna/sneakers-tennis-shoes-alte_cod44740860xg.html"
            data-bg-multi='url("./images/220x280-L-05.webp"), url("./images/440x560-R-05.webp")'
            class="multiple"
          ></a>
        </li>
        <li>
          <a
            class="lazy"
            href="#/it/donna/sneakers-tennis-shoes-basse_cod44738719vn.html"
            data-bg-multi='url("./images/220x280-06.webp")'
            data-bg-multi-hidpi='url("./images/440x560-06.webp")'
          ></a>
        </li>
        <li>
          <a
            class="lazy"
            href="#/it/donna/sneakers-tennis-shoes-basse_cod44739938wk.html"
            data-bg-multi='url("./images/220x280-07.webp")'
            data-bg-multi-hidpi='url("./images/440x560-07.webp")'
          ></a>
        </li>
        <li>
          <a
            class="lazy"
            href="#/it/donna/stivali_cod44736534fq.html"
            data-bg-multi='url("./images/220x280-L-08.webp"), url("./images/440x560-R-08.webp")'
            data-bg-multi-hidpi='url("./images/440x560-L-08.webp"), url("./images/440x560-R-08.webp")'
            class="multiple"
          ></a>
        </li>
        <li>
          <a
            class="lazy"
            href="#/it/donna/stivali_cod44735388ui.html"
            data-bg-multi='url("./images/220x280-09.webp")'
            data-bg-multi-hidpi='url("./images/440x560-09.webp")'
          ></a>
        </li>
        <li>
          <a
            class="lazy"
            href="#/it/donna/stivaletti_cod44739165ev.html"
            data-bg-multi='url("./images/220x280-10.webp")'
            data-bg-multi-hidpi='url("./images/440x560-10.webp")'
          ></a>
        </li>
        <li>
          <a
            class="lazy"
            href="#/it/donna/stivaletti_cod44739454hf.html"
            data-bg-multi='url("./images/220x280-L-11.webp"), url("./images/440x560-R-11.webp")'
            data-bg-multi-hidpi='url("./images/440x560-L-11.webp"), url("./images/440x560-R-11.webp")'
            class="multiple"
          ></a>
        </li>
        <li>
          <a
            class="lazy"
            href="#/it/donna/stivali_cod44719480km.html"
            data-bg-multi='url("./images/220x280-12.webp")'
            data-bg-multi-hidpi='url("./images/440x560-12.webp")'
          ></a>
        </li>
        <li>
          <a
            class="lazy"
            href="#/it/donna/stivaletti_cod44719687td.html"
            data-bg-multi='url("./images/220x280-13.webp")'
            data-bg-multi-hidpi='url("./images/440x560-13.webp")'
          ></a>
        </li>
        <li>
          <a
            class="lazy"
            href="#/it/donna/decollete_cod44721899ng.html"
            data-bg-multi='url("./images/220x280-L-14.webp"), url("./images/440x560-R-14.webp")'
            data-bg-multi-hidpi='url("./images/440x560-L-14.webp"), url("./images/440x560-R-14.webp")'
            class="multiple"
          ></a>
        </li>
        <li>
          <a
            class="lazy"
            href="#/it/donna/mocassini_cod44721744sl.html"
            data-bg-multi='url("./images/220x280-15.webp")'
            data-bg-multi-hidpi='url("./images/440x560-15.webp")'
          ></a>
        </li>
        <li>
          <a
            class="lazy"
            href="#/it/donna/stivaletti_cod44716730kr.html"
            data-bg-multi='url("./images/220x280-16.webp")'
            data-bg-multi-hidpi='url("./images/440x560-16.webp")'
          ></a>
        </li>
        <li>
          <a
            class="lazy"
            href="#/it/donna/decollete_cod44718734xl.html"
            data-bg-multi='url("./images/220x280-L-17.webp"), url("./images/440x560-R-17.webp")'
            data-bg-multi-hidpi='url("./images/440x560-L-17.webp"), url("./images/440x560-R-17.webp")'
            class="multiple"
          ></a>
        </li>
        <li>
          <a
            class="lazy"
            href="#/it/donna/decollete_cod44721796uk.html"
            data-bg-multi='url("./images/220x280-18.webp")'
            data-bg-multi-hidpi='url("./images/440x560-18.webp")'
          ></a>
        </li>
        <li>
          <a
            class="lazy"
            href="#/it/donna/francesine_cod44717679mj.html"
            data-bg-multi='url("./images/220x280-19.webp")'
            data-bg-multi-hidpi='url("./images/440x560-19.webp")'
          ></a>
        </li>
        <li>
          <a
            class="lazy"
            href="#/it/donna/stivaletti_cod44724594vu.html"
            data-bg-multi='url("./images/220x280-L-20.webp"), url("./images/440x560-R-20.webp")'
            data-bg-multi-hidpi='url("./images/440x560-L-20.webp"), url("./images/440x560-R-20.webp")'
            class="multiple"
          ></a>
        </li>
        <li>
          <a
            class="lazy"
            href="#/it/donna/decollete_cod44726148aq.html"
            data-bg-multi='url("./images/220x280-21.webp")'
            data-bg-multi-hidpi='url("./images/440x560-21.webp")'
          ></a>
        </li>
        <li>
          <a
            class="lazy"
            href="#/it/donna/mocassini_cod44719629nt.html"
            data-bg-multi='url("./images/220x280-22.webp")'
            data-bg-multi-hidpi='url("./images/440x560-22.webp")'
          ></a>
        </li>
        <li>
          <a
            class="lazy"
            href="#/it/donna/mocassini_cod44725329kq.html"
            data-bg-multi='url("./images/220x280-L-23.webp"), url("./images/440x560-R-23.webp")'
            data-bg-multi-hidpi='url("./images/440x560-L-23.webp"), url("./images/440x560-R-23.webp")'
            class="multiple"
          ></a>
        </li>
        <li>
          <a
            class="lazy"
            href="#/it/donna/stivali_cod44724026qs.html"
            data-bg-multi='url("./images/220x280-24.webp")'
            data-bg-multi-hidpi='url("./images/440x560-24.webp")'
          ></a>
        </li>
        <li>
          <a
            class="lazy"
            href="#/it/donna/stivaletti_cod44720256gw.html"
            data-bg-multi='url("./images/220x280-25.webp")'
            data-bg-multi-hidpi='url("./images/440x560-25.webp")'
          ></a>
        </li>
        <li>
          <a
            class="lazy"
            href="#/it/donna/stivaletti_cod44722062id.html"
            data-bg-multi='url("./images/220x280-L-26.webp"), url("./images/440x560-R-26.webp")'
            data-bg-multi-hidpi='url("./images/440x560-L-26.webp"), url("./images/440x560-R-26.webp")'
            class="multiple"
          ></a>
        </li>
        <li>
          <a
            class="lazy"
            href="#/it/donna/mocassini_cod44722402rh.html"
            data-bg-multi='url("./images/220x280-27.webp")'
            data-bg-multi-hidpi='url("./images/440x560-27.webp")'
          ></a>
        </li>
        <li>
          <a
            class="lazy"
            href="#/it/donna/stivaletti_cod44726296vu.html"
            data-bg-multi='url("./images/220x280-28.webp")'
            data-bg-multi-hidpi='url("./images/440x560-28.webp")'
          ></a>
        </li>
        <li>
          <a
            class="lazy"
            href="#/it/donna/stivaletti_cod44725755ct.html"
            data-bg-multi='url("./images/220x280-L-29.webp"), url("./images/440x560-R-29.webp")'
            data-bg-multi-hidpi='url("./images/440x560-L-29.webp"), url("./images/440x560-R-29.webp")'
            class="multiple"
          ></a>
        </li>
        <li>
          <a
            class="lazy"
            href="#/it/donna/stivaletti_cod44725348nv.html"
            data-bg-multi='url("./images/220x280-30.webp")'
            data-bg-multi-hidpi='url("./images/440x560-30.webp")'
          ></a>
        </li>
        <li>
          <a
            class="lazy"
            href="#/it/donna/stivaletti_cod44721879xx.html"
            data-bg-multi='url("./images/220x280-31.webp")'
            data-bg-multi-hidpi='url("./images/440x560-31.webp")'
          ></a>
        </li>
        <li>
          <a
            class="lazy"
            href="#/it/donna/cuissardes_cod44729472iq.html"
            data-bg-multi='url("./images/220x280-L-32.webp"), url("./images/440x560-R-32.webp")'
            data-bg-multi-hidpi='url("./images/440x560-L-32.webp"), url("./images/440x560-R-32.webp")'
            class="multiple"
          ></a>
        </li>
        <li>
          <a
            class="lazy"
            href="#/it/donna/decollete_cod44725388jv.html"
            data-bg-multi='url("./images/220x280-33.webp")'
            data-bg-multi-hidpi='url("./images/440x560-33.webp")'
          ></a>
        </li>
        <li>
          <a
            class="lazy"
            href="#/it/donna/stivaletti_cod44721854ce.html"
            data-bg-multi='url("./images/220x280-34.webp")'
            data-bg-multi-hidpi='url("./images/440x560-34.webp")'
          ></a>
        </li>
        <li>
          <a
            class="lazy"
            href="#/it/donna/sneakers-tennis-shoes-basse_cod44727690jp.html"
            data-bg-multi='url("./images/220x280-L-35.webp"), url("./images/440x560-R-35.webp")'
            data-bg-multi-hidpi='url("./images/440x560-L-35.webp"), url("./images/440x560-R-35.webp")'
            class="multiple"
          ></a>
        </li>
        <li>
          <a
            class="lazy"
            href="#/it/donna/mocassini_cod44727501hh.html"
            data-bg-multi='url("./images/220x280-36.webp")'
            data-bg-multi-hidpi='url("./images/440x560-36.webp")'
          ></a>
        </li>
        <li>
          <a
            class="lazy"
            href="#/it/donna/sneakers-tennis-shoes-basse_cod44727038aq.html"
            data-bg-multi='url("./images/220x280-37.webp")'
            data-bg-multi-hidpi='url("./images/440x560-37.webp")'
          ></a>
        </li>
        <li>
          <a
            class="lazy"
            href="#/it/donna/mocassini_cod44704882bq.html"
            data-bg-multi='url("./images/220x280-L-38.webp"), url("./images/440x560-R-38.webp")'
            data-bg-multi-hidpi='url("./images/440x560-L-38.webp"), url("./images/440x560-R-38.webp")'
            class="multiple"
          ></a>
        </li>
        <li>
          <a
            class="lazy"
            href="#/it/donna/mocassini_cod44734002vc.html"
            data-bg-multi='url("./images/220x280-39.webp")'
            data-bg-multi-hidpi='url("./images/440x560-39.webp")'
          ></a>
        </li>
      </ul>
    </div>
    <script src="../dist/lazyload.min.js"></script>
    <script>
      function logElementEvent(eventName, element) {
        console.log(Date.now(), eventName, element.getAttribute("data-bg-multi"));
      }

      var callback_enter = function (element) {
        logElementEvent("🔑 ENTERED", element);
      };
      var callback_exit = function (element) {
        logElementEvent("🚪 EXITED", element);
      };
      var callback_loading = function (element) {
        logElementEvent("⌚ LOADING", element);
      };
      var callback_applied = function (element) {
        logElementEvent("👍 APPLIED", element);
      };
      var callback_loaded = function (element) {
        logElementEvent("👍 LOADED", element);
      };
      var callback_error = function (element) {
        logElementEvent("💀 ERROR", element);
        element.style.backgroundImage = "url(&quot;./images/440x560-Error.webp&quot;)";
      };
      var callback_finish = function () {
        logElementEvent("✔️ FINISHED", document.documentElement);
      };
      var callback_cancel = function (element) {
        logElementEvent("🔥 CANCEL", element);
      };

      LL = new LazyLoad({
        // Assign the callbacks defined above
        callback_enter: callback_enter,
        callback_exit: callback_exit,
        callback_cancel: callback_cancel,
        callback_applied: callback_applied,
        callback_loading: callback_loading,
        callback_loaded: callback_loaded,
        callback_error: callback_error,
        callback_finish: callback_finish
      });
    </script>
  </body>
</html>


================================================
FILE: demos/container_multiple.html
================================================
<!DOCTYPE html>
<html>
  <head lang="en">
    <meta charset="UTF-8" />
    <title>
      Multiple scrolling container - Lazyload demos
    </title>
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <style type="text/css">
      ul,
      li {
        list-style-type: none;
        margin: 0;
        padding: 0;
      }

      a,
      img {
        display: block;
      }

      img {
        border: 0;
        width: 220px;
        height: 280px;
      }

      img:not([src]) {
        visibility: hidden;
      }

      .flex {
        display: flex;
      }

      .results {
        height: 564px;
        overflow: scroll;
        border: 1px dotted #f00;
        flex-grow: 1;
      }
    </style>
  </head>

  <body>
    <h1>Multiple scrolling container demo</h1>
    <div class="flex">
      <div id="results1" class="results">
        <ul>
          <li>
            <a href="#/it/donna/stivaletti_cod44721746jj.html"
              ><img
                alt="Stivaletti"
                src="./images/440x560-01.webp"
                width="220"
                height="280"
            /></a>
          </li>
          <li>
            <a href="#/it/donna/open-toe_cod44740806jx.html"
              ><img
                alt="Open toe"
                src="./images/440x560-02.webp"
                width="220"
                height="280"
            /></a>
          </li>
          <li>
            <a href="#/it/donna/sneakers-tennis-shoes-basse_cod44735977gr.html"
              ><img
                class="lazy"
                alt="Sneakers &amp; Tennis"
                data-src="./images/440x560-03.webp"
                width="220"
                height="280"
            /></a>
          </li>
          <li>
            <a href="#/it/donna/sneakers-tennis-shoes-basse_cod44738717am.html"
              ><img
                class="lazy"
                alt="Sneakers &amp; Tennis shoes basse"
                data-src="./images/440x560-04.webp"
                width="220"
                height="280"
            /></a>
          </li>
          <li>
            <a href="#/it/donna/sneakers-tennis-shoes-alte_cod44739940cb.html"
              ><img
                class="lazy"
                alt="Sneakers &amp; Tennis shoes alte"
                data-src="./images/440x560-05.webp"
                width="220"
                height="280"
            /></a>
          </li>
          <li>
            <a href="#/it/donna/sneakers-tennis-shoes-alte_cod44740860xg.html"
              ><img
                class="lazy"
                alt="Sneakers &amp; Tennis shoes alte"
                data-src="./images/440x560-06.webp"
                width="220"
                height="280"
            /></a>
          </li>
          <li>
            <a href="#/it/donna/sneakers-tennis-shoes-basse_cod44738719vn.html"
              ><img
                class="lazy"
                alt="Sneakers &amp; Tennis shoes basse"
                data-src="./images/440x560-07.webp"
                width="220"
                height="280"
            /></a>
          </li>
          <li>
            <a href="#/it/donna/sneakers-tennis-shoes-basse_cod44739938wk.html"
              ><img
                class="lazy"
                alt="Sneakers &amp; Tennis shoes basse"
                data-src="./images/440x560-08.webp"
                width="220"
                height="280"
            /></a>
          </li>
          <li>
            <a href="#/it/donna/stivali_cod44736534fq.html"
              ><img
                class="lazy"
                alt="Stivali"
                data-src="./images/440x560-09.webp"
                width="220"
                height="280"
            /></a>
          </li>
          <li>
            <a href="#/it/donna/stivali_cod44735388ui.html"
              ><img
                class="lazy"
                alt="Stivali"
                data-src="./images/440x560-10.webp"
                width="220"
                height="280"
            /></a>
          </li>
          <li>
            <a href="#/it/donna/stivaletti_cod44739165ev.html"
              ><img
                class="lazy"
                alt="Stivaletti"
                data-src="./images/440x560-11.webp"
                width="220"
                height="280"
            /></a>
          </li>
          <li>
            <a href="#/it/donna/stivaletti_cod44739454hf.html"
              ><img
                class="lazy"
                alt="Stivaletti"
                data-src="./images/440x560-12.webp"
                width="220"
                height="280"
            /></a>
          </li>
          <li>
            <a href="#/it/donna/stivali_cod44719480km.html"
              ><img
                class="lazy"
                alt="Stivali"
                data-src="./images/440x560-13.webp"
                width="220"
                height="280"
            /></a>
          </li>
          <li>
            <a href="#/it/donna/stivaletti_cod44719687td.html"
              ><img
                class="lazy"
                alt="Stivaletti"
                data-src="./images/440x560-14.webp"
                width="220"
                height="280"
            /></a>
          </li>
          <li>
            <a href="#/it/donna/decollete_cod44721899ng.html"
              ><img
                class="lazy"
                alt="Décolleté"
                data-src="./images/440x560-15.webp"
                width="220"
                height="280"
            /></a>
          </li>
          <li>
            <a href="#/it/donna/mocassini_cod44721744sl.html"
              ><img
                class="lazy"
                alt="Mocassini"
                data-src="./images/440x560-16.webp"
                width="220"
                height="280"
            /></a>
          </li>
          <li>
            <a href="#/it/donna/stivaletti_cod44716730kr.html"
              ><img
                class="lazy"
                alt="Stivaletti"
                data-src="./images/440x560-17.webp"
                width="220"
                height="280"
            /></a>
          </li>
          <li>
            <a href="#/it/donna/decollete_cod44718734xl.html"
              ><img
                class="lazy"
                alt="Décolleté"
                data-src="./images/440x560-18.webp"
                width="220"
                height="280"
            /></a>
          </li>
          <li>
            <a href="#/it/donna/decollete_cod44721796uk.html"
              ><img
                class="lazy"
                alt="Décolleté"
                data-src="./images/440x560-19.webp"
                width="220"
                height="280"
            /></a>
          </li>
        </ul>
      </div>
      <div id="results2" class="results">
        <ul>
          <li>
            <a href="#/it/donna/francesine_cod44717679mj.html"
              ><img
                alt="Francesine"
                src="./images/440x560-20.webp"
                width="220"
                height="280"
            /></a>
          </li>
          <li>
            <a href="#/it/donna/stivaletti_cod44724594vu.html"
              ><img
                alt="Stivaletti"
                src="./images/440x560-21.webp"
                width="220"
                height="280"
            /></a>
          </li>
          <li>
            <a href="#/it/donna/decollete_cod44726148aq.html"
              ><img
                class="lazy"
                alt="Décolleté"
                data-src="./images/440x560-22.webp"
                width="220"
                height="280"
            /></a>
          </li>
          <li>
            <a href="#/it/donna/mocassini_cod44719629nt.html"
              ><img
                class="lazy"
                alt="Mocassini"
                data-src="./images/440x560-23.webp"
                width="220"
                height="280"
            /></a>
          </li>
          <li>
            <a href="#/it/donna/mocassini_cod44725329kq.html"
              ><img
                class="lazy"
                alt="Mocassini"
                data-src="./images/440x560-24.webp"
                width="220"
                height="280"
            /></a>
          </li>
          <li>
            <a href="#/it/donna/stivali_cod44724026qs.html"
              ><img
                class="lazy"
                alt="Stivali"
                data-src="./images/440x560-25.webp"
                width="220"
                height="280"
            /></a>
          </li>
          <li>
            <a href="#/it/donna/stivaletti_cod44720256gw.html"
              ><img
                class="lazy"
                alt="Stivaletti"
                data-src="./images/440x560-26.webp"
                width="220"
                height="280"
            /></a>
          </li>
          <li>
            <a href="#/it/donna/stivaletti_cod44722062id.html"
              ><img
                class="lazy"
                alt="Stivaletti"
                data-src="./images/440x560-27.webp"
                width="220"
                height="280"
            /></a>
          </li>
          <li>
            <a href="#/it/donna/mocassini_cod44722402rh.html"
              ><img
                class="lazy"
                alt="Mocassini"
                data-src="./images/440x560-28.webp"
                width="220"
                height="280"
            /></a>
          </li>
          <li>
            <a href="#/it/donna/stivaletti_cod44726296vu.html"
              ><img
                class="lazy"
                alt="Stivaletti"
                data-src="./images/440x560-29.webp"
                width="220"
                height="280"
            /></a>
          </li>
          <li>
            <a href="#/it/donna/stivaletti_cod44725755ct.html"
              ><img
                class="lazy"
                alt="Stivaletti"
                data-src="./images/440x560-30.webp"
                width="220"
                height="280"
            /></a>
          </li>
          <li>
            <a href="#/it/donna/stivaletti_cod44725348nv.html"
              ><img
                class="lazy"
                alt="Stivaletti"
                data-src="./images/440x560-31.webp"
                width="220"
                height="280"
            /></a>
          </li>
          <li>
            <a href="#/it/donna/stivaletti_cod44721879xx.html"
              ><img
                class="lazy"
                alt="Stivaletti"
                data-src="./images/440x560-32.webp"
                width="220"
                height="280"
            /></a>
          </li>
          <li>
            <a href="#/it/donna/cuissardes_cod44729472iq.html"
              ><img
                class="lazy"
                alt="Cuissardes"
                data-src="./images/440x560-33.webp"
                width="220"
                height="280"
            /></a>
          </li>
          <li>
            <a href="#/it/donna/decollete_cod44725388jv.html"
              ><img
                class="lazy"
                alt="Décolleté"
                data-src="./images/440x560-34.webp"
                width="220"
                height="280"
            /></a>
          </li>
          <li>
            <a href="#/it/donna/stivaletti_cod44721854ce.html"
              ><img
                class="lazy"
                alt="Stivaletti"
                data-src="./images/440x560-35.webp"
                width="220"
                height="280"
            /></a>
          </li>
          <li>
            <a href="#/it/donna/sneakers-tennis-shoes-basse_cod44727690jp.html"
              ><img
                class="lazy"
                alt="Sneakers &amp; Tennis shoes basse"
                data-src="./images/440x560-36.webp"
                width="220"
                height="280"
            /></a>
          </li>
          <li>
            <a href="#/it/donna/mocassini_cod44727501hh.html"
              ><img
                class="lazy"
                alt="Mocassini"
                data-src="./images/440x560-37.webp"
                width="220"
                height="280"
            /></a>
          </li>
          <li>
            <a href="#/it/donna/sneakers-tennis-shoes-basse_cod44727038aq.html"
              ><img
                class="lazy"
                alt="Sneakers &amp; Tennis shoes basse"
                data-src="./images/440x560-38.webp"
                width="220"
                height="280"
            /></a>
          </li>
          <li>
            <a href="#/it/donna/mocassini_cod44704882bq.html"
              ><img
                class="lazy"
                alt="Mocassini"
                data-src="./images/440x560-39.webp"
                width="220"
                height="280"
            /></a>
          </li>
          <li>
            <a href="#/it/donna/mocassini_cod44734002vc.html"
              ><img
                class="lazy"
                alt="Mocassini"
                data-src="./images/440x560-40.webp"
                width="220"
                height="280"
            /></a>
          </li>
        </ul>
      </div>
    </div>

    <script src="../dist/lazyload.min.js"></script>
    <script>
      (function () {
        function logElementEvent(eventName, element) {
          console.log(Date.now(), eventName, element.getAttribute("data-src"));
        }

        var callback_enter = function (element) {
          logElementEvent("🔑 ENTERED", element);
        };
        var callback_exit = function (element) {
          logElementEvent("🚪 EXITED", element);
        };
        var callback_loading = function (element) {
          logElementEvent("⌚ LOADING", element);
        };
        var callback_loaded = function (element) {
          logElementEvent("👍 LOADED", element);
        };
        var callback_error = function (element) {
          logElementEvent("💀 ERROR", element);
          element.src =
            "./images/440x560-Error.webp";
        };
        var callback_finish = function () {
          logElementEvent("✔️ FINISHED", document.documentElement);
        };
        var callback_cancel = function (element) {
          logElementEvent("🔥 CANCEL", element);
        };

        var ll1 = new LazyLoad({
          container: document.getElementById("results1"),
          // Assign the callbacks defined above
          callback_enter: callback_enter,
          callback_exit: callback_exit,
          callback_cancel: callback_cancel,
          callback_loading: callback_loading,
          callback_loaded: callback_loaded,
          callback_error: callback_error,
          callback_finish: callback_finish
        });

        var ll2 = new LazyLoad({
          container: document.getElementById("results2"),
          // Assign the callbacks defined above
          callback_enter: callback_enter,
          callback_exit: callback_exit,
          callback_loading: callback_loading,
          callback_loaded: callback_loaded,
          callback_error: callback_error,
          callback_finish: callback_finish
        });
      })();
    </script>
  </body>
</html>


================================================
FILE: demos/container_single.html
================================================
<!DOCTYPE html>
<html>
  <head lang="en">
    <meta charset="UTF-8" />
    <title>
      Single scrolling container - Lazyload demos
    </title>
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <style>
      ul,
      li {
        list-style-type: none;
        margin: 0;
        padding: 0;
      }

      a,
      img {
        display: block;
      }

      img {
        border: 0;
        width: 220px;
        height: 280px;
      }

      img:not([src]) {
        visibility: hidden;
      }

      #results1 {
        height: 564px;
        overflow: scroll;
        border: 1px dotted #f00;
      }
    </style>
  </head>

  <body>
    <h1>Single scrolling container demo</h1>
    <div id="results1" class="results">
      <ul>
        <li>
          <a href="#/it/donna/stivaletti_cod44721746jj.html"
            ><img
              alt="Stivaletti"
              src="./images/440x560-01.webp"
              width="220"
              height="280"
          /></a>
        </li>
        <li>
          <a href="#/it/donna/open-toe_cod44740806jx.html"
            ><img
              alt="Open toe"
              src="./images/440x560-02.webp"
              width="220"
              height="280"
          /></a>
        </li>
        <li>
          <a href="#/it/donna/sneakers-tennis-shoes-basse_cod44735977gr.html"
            ><img
              class="lazy"
              alt="Sneakers &amp; Tennis"
              data-src="./images/440x560-03.webp"
              width="220"
              height="280"
          /></a>
        </li>
        <li>
          <a href="#/it/donna/sneakers-tennis-shoes-basse_cod44738717am.html"
            ><img
              class="lazy"
              alt="Sneakers &amp; Tennis shoes basse"
              data-src="./images/440x560-04.webp"
              width="220"
              height="280"
          /></a>
        </li>
        <li>
          <a href="#/it/donna/sneakers-tennis-shoes-alte_cod44739940cb.html"
            ><img
              class="lazy"
              alt="Sneakers &amp; Tennis shoes alte"
              data-src="./images/440x560-05.webp"
              width="220"
              height="280"
          /></a>
        </li>
        <li>
          <a href="#/it/donna/sneakers-tennis-shoes-alte_cod44740860xg.html"
            ><img
              class="lazy"
              alt="Sneakers &amp; Tennis shoes alte"
              data-src="./images/440x560-06.webp"
              width="220"
              height="280"
          /></a>
        </li>
        <li>
          <a href="#/it/donna/sneakers-tennis-shoes-basse_cod44738719vn.html"
            ><img
              class="lazy"
              alt="Sneakers &amp; Tennis shoes basse"
              data-src="./images/440x560-07.webp"
              width="220"
              height="280"
          /></a>
        </li>
        <li>
          <a href="#/it/donna/sneakers-tennis-shoes-basse_cod44739938wk.html"
            ><img
              class="lazy"
              alt="Sneakers &amp; Tennis shoes basse"
              data-src="./images/440x560-08.webp"
              width="220"
              height="280"
          /></a>
        </li>
        <li>
          <a href="#/it/donna/stivali_cod44736534fq.html"
            ><img
              class="lazy"
              alt="Stivali"
              data-src="./images/440x560-09.webp"
              width="220"
              height="280"
          /></a>
        </li>
        <li>
          <a href="#/it/donna/stivali_cod44735388ui.html"
            ><img
              class="lazy"
              alt="Stivali"
              data-src="./images/440x560-10.webp"
              width="220"
              height="280"
          /></a>
        </li>
        <li>
          <a href="#/it/donna/stivaletti_cod44739165ev.html"
            ><img
              class="lazy"
              alt="Stivaletti"
              data-src="./images/440x560-11.webp"
              width="220"
              height="280"
          /></a>
        </li>
        <li>
          <a href="#/it/donna/stivaletti_cod44739454hf.html"
            ><img
              class="lazy"
              alt="Stivaletti"
              data-src="./images/440x560-12.webp"
              width="220"
              height="280"
          /></a>
        </li>
        <li>
          <a href="#/it/donna/stivali_cod44719480km.html"
            ><img
              class="lazy"
              alt="Stivali"
              data-src="./images/440x560-13.webp"
              width="220"
              height="280"
          /></a>
        </li>
        <li>
          <a href="#/it/donna/stivaletti_cod44719687td.html"
            ><img
              class="lazy"
              alt="Stivaletti"
              data-src="./images/440x560-14.webp"
              width="220"
              height="280"
          /></a>
        </li>
        <li>
          <a href="#/it/donna/decollete_cod44721899ng.html"
            ><img
              class="lazy"
              alt="Décolleté"
              data-src="./images/440x560-15.webp"
              width="220"
              height="280"
          /></a>
        </li>
        <li>
          <a href="#/it/donna/mocassini_cod44721744sl.html"
            ><img
              class="lazy"
              alt="Mocassini"
              data-src="./images/440x560-16.webp"
              width="220"
              height="280"
          /></a>
        </li>
        <li>
          <a href="#/it/donna/stivaletti_cod44716730kr.html"
            ><img
              class="lazy"
              alt="Stivaletti"
              data-src="./images/440x560-17.webp"
              width="220"
              height="280"
          /></a>
        </li>
        <li>
          <a href="#/it/donna/decollete_cod44718734xl.html"
            ><img
              class="lazy"
              alt="Décolleté"
              data-src="./images/440x560-18.webp"
              width="220"
              height="280"
          /></a>
        </li>
        <li>
          <a href="#/it/donna/decollete_cod44721796uk.html"
            ><img
              class="lazy"
              alt="Décolleté"
              data-src="./images/440x560-19.webp"
              width="220"
              height="280"
          /></a>
        </li>
        <li>
          <a href="#/it/donna/francesine_cod44717679mj.html"
            ><img
              class="lazy"
              alt="Francesine"
              data-src="./images/440x560-20.webp"
              width="220"
              height="280"
          /></a>
        </li>
        <li>
          <a href="#/it/donna/stivaletti_cod44724594vu.html"
            ><img
              class="lazy"
              alt="Stivaletti"
              data-src="./images/440x560-21.webp"
              width="220"
              height="280"
          /></a>
        </li>
        <li>
          <a href="#/it/donna/decollete_cod44726148aq.html"
            ><img
              class="lazy"
              alt="Décolleté"
              data-src="./images/440x560-22.webp"
              width="220"
              height="280"
          /></a>
        </li>
        <li>
          <a href="#/it/donna/mocassini_cod44719629nt.html"
            ><img
              class="lazy"
              alt="Mocassini"
              data-src="./images/440x560-23.webp"
              width="220"
              height="280"
          /></a>
        </li>
        <li>
          <a href="#/it/donna/mocassini_cod44725329kq.html"
            ><img
              class="lazy"
              alt="Mocassini"
              data-src="./images/440x560-24.webp"
              width="220"
              height="280"
          /></a>
        </li>
        <li>
          <a href="#/it/donna/stivali_cod44724026qs.html"
            ><img
              class="lazy"
              alt="Stivali"
              data-src="./images/440x560-25.webp"
              width="220"
              height="280"
          /></a>
        </li>
        <li>
          <a href="#/it/donna/stivaletti_cod44720256gw.html"
            ><img
              class="lazy"
              alt="Stivaletti"
              data-src="./images/440x560-26.webp"
              width="220"
              height="280"
          /></a>
        </li>
        <li>
          <a href="#/it/donna/stivaletti_cod44722062id.html"
            ><img
              class="lazy"
              alt="Stivaletti"
              data-src="./images/440x560-27.webp"
              width="220"
              height="280"
          /></a>
        </li>
        <li>
          <a href="#/it/donna/mocassini_cod44722402rh.html"
            ><img
              class="lazy"
              alt="Mocassini"
              data-src="./images/440x560-28.webp"
              width="220"
              height="280"
          /></a>
        </li>
        <li>
          <a href="#/it/donna/stivaletti_cod44726296vu.html"
            ><img
              class="lazy"
              alt="Stivaletti"
              data
Download .txt
gitextract_cukr4pm0/

├── .babelrc
├── .eslintignore
├── .eslintrc.json
├── .gitattributes
├── .github/
│   ├── CONTRIBUTING.md
│   ├── ISSUE_TEMPLATE/
│   │   ├── bug_report.md
│   │   ├── feature_request.md
│   │   └── support-request.md
│   └── workflows/
│       ├── ci.yml
│       └── playwright.yml
├── .gitignore
├── .prettierrc
├── .vscode/
│   └── settings.json
├── CHANGELOG.md
├── CODE_OF_CONDUCT.md
├── LICENSE
├── README.md
├── UPGRADE.md
├── _config.yml
├── bower.json
├── currentFeature.md
├── demos/
│   ├── async.html
│   ├── async_multiple.html
│   ├── background_images.html
│   ├── background_images_image-set.html
│   ├── background_images_multi.html
│   ├── container_multiple.html
│   ├── container_single.html
│   ├── dynamic_content.html
│   ├── dynamic_content_nodeset.html
│   ├── embedded.html
│   ├── error_no_restore.html
│   ├── error_restore.html
│   ├── esm.html
│   ├── fade_in.html
│   ├── hundreds.html
│   ├── iframes/
│   │   ├── i01.html
│   │   ├── i02.html
│   │   └── i03.html
│   ├── iframes.html
│   ├── image_basic.html
│   ├── image_hidden.html
│   ├── image_no_classes.html
│   ├── image_ph_external.html
│   ├── image_ph_inline.html
│   ├── image_srcset.html
│   ├── image_srcset_lazy_sizes.html
│   ├── image_srcset_sizes.html
│   ├── images/
│   │   ├── 220x280-01.avif
│   │   ├── 220x280-02.avif
│   │   ├── 220x280-03.avif
│   │   ├── 220x280-04.avif
│   │   ├── 220x280-05.avif
│   │   ├── 220x280-06.avif
│   │   ├── 220x280-07.avif
│   │   ├── 220x280-08.avif
│   │   ├── 220x280-09.avif
│   │   ├── 220x280-10.avif
│   │   ├── 220x280-11.avif
│   │   ├── 220x280-12.avif
│   │   ├── 220x280-13.avif
│   │   ├── 220x280-14.avif
│   │   ├── 220x280-15.avif
│   │   ├── 220x280-16.avif
│   │   ├── 220x280-17.avif
│   │   ├── 220x280-18.avif
│   │   ├── 220x280-19.avif
│   │   ├── 220x280-20.avif
│   │   ├── 220x280-21.avif
│   │   ├── 220x280-22.avif
│   │   ├── 220x280-23.avif
│   │   ├── 220x280-24.avif
│   │   ├── 220x280-25.avif
│   │   ├── 220x280-26.avif
│   │   ├── 220x280-27.avif
│   │   ├── 220x280-28.avif
│   │   ├── 220x280-29.avif
│   │   ├── 220x280-30.avif
│   │   ├── 220x280-31.avif
│   │   ├── 220x280-32.avif
│   │   ├── 220x280-33.avif
│   │   ├── 220x280-34.avif
│   │   ├── 220x280-35.avif
│   │   ├── 220x280-36.avif
│   │   ├── 220x280-37.avif
│   │   ├── 220x280-38.avif
│   │   ├── 220x280-39.avif
│   │   ├── 220x280-40.avif
│   │   ├── 440x560-01.avif
│   │   ├── 440x560-02.avif
│   │   ├── 440x560-03.avif
│   │   ├── 440x560-04.avif
│   │   ├── 440x560-05.avif
│   │   ├── 440x560-06.avif
│   │   ├── 440x560-07.avif
│   │   ├── 440x560-08.avif
│   │   ├── 440x560-09.avif
│   │   ├── 440x560-10.avif
│   │   ├── 440x560-11.avif
│   │   ├── 440x560-12.avif
│   │   ├── 440x560-13.avif
│   │   ├── 440x560-14.avif
│   │   ├── 440x560-15.avif
│   │   ├── 440x560-16.avif
│   │   ├── 440x560-17.avif
│   │   ├── 440x560-18.avif
│   │   ├── 440x560-19.avif
│   │   ├── 440x560-20.avif
│   │   ├── 440x560-21.avif
│   │   ├── 440x560-22.avif
│   │   ├── 440x560-23.avif
│   │   ├── 440x560-24.avif
│   │   ├── 440x560-25.avif
│   │   ├── 440x560-26.avif
│   │   ├── 440x560-27.avif
│   │   ├── 440x560-28.avif
│   │   ├── 440x560-29.avif
│   │   ├── 440x560-30.avif
│   │   ├── 440x560-31.avif
│   │   ├── 440x560-32.avif
│   │   ├── 440x560-33.avif
│   │   ├── 440x560-34.avif
│   │   ├── 440x560-35.avif
│   │   ├── 440x560-36.avif
│   │   ├── 440x560-37.avif
│   │   ├── 440x560-38.avif
│   │   ├── 440x560-39.avif
│   │   └── 440x560-40.avif
│   ├── lazily_load_lazyLoad.html
│   ├── lazy_functions.html
│   ├── load.html
│   ├── load_all.html
│   ├── native_lazyload.html
│   ├── native_lazyload_conditional.html
│   ├── object.html
│   ├── picture_media.html
│   ├── picture_type_avif.html
│   ├── popup_layer.html
│   ├── print.html
│   ├── restore_destroy.html
│   ├── sliders_css_only.html
│   ├── swiper.html
│   ├── thresholds.html
│   ├── video.html
│   └── video_autoplay.html
├── dist/
│   ├── esm/
│   │   ├── autoInitialize.js
│   │   ├── callback.js
│   │   ├── cancelOnExit.js
│   │   ├── class.js
│   │   ├── constants.js
│   │   ├── counters.js
│   │   ├── data.js
│   │   ├── defaults.js
│   │   ├── dom.js
│   │   ├── elementStatus.js
│   │   ├── environment.js
│   │   ├── event.js
│   │   ├── forEachSource.js
│   │   ├── intersectionHandlers.js
│   │   ├── intersectionObserver.js
│   │   ├── lazyload.js
│   │   ├── load.js
│   │   ├── native.js
│   │   ├── online.js
│   │   ├── originalAttributes.js
│   │   ├── reset.js
│   │   ├── restore.js
│   │   ├── set.js
│   │   ├── tempImage.js
│   │   └── unobserve.js
│   ├── lazyload.iife.js
│   └── lazyload.js
├── funding.yml
├── jest.config.cjs
├── package.json
├── playwright.config.js
├── rollup.config.mjs
├── src/
│   ├── autoInitialize.js
│   ├── callback.js
│   ├── cancelOnExit.js
│   ├── class.js
│   ├── constants.js
│   ├── counters.js
│   ├── data.js
│   ├── defaults.js
│   ├── dom.js
│   ├── elementStatus.js
│   ├── environment.js
│   ├── event.js
│   ├── forEachSource.js
│   ├── intersectionHandlers.js
│   ├── intersectionObserver.js
│   ├── lazyload.js
│   ├── load.js
│   ├── native.js
│   ├── online.js
│   ├── originalAttributes.js
│   ├── reset.js
│   ├── restore.js
│   ├── set.js
│   ├── tempImage.js
│   └── unobserve.js
├── tests/
│   ├── e2e/
│   │   ├── background_image.spec.js
│   │   ├── background_image_multi.spec.js
│   │   └── image_basic.spec.js
│   └── unit/
│       ├── cancelOnExit.test.js
│       ├── lib/
│       │   ├── expectExtend.js
│       │   └── getFakeInstance.js
│       ├── load.test.js
│       ├── originalAttributes.test.js
│       ├── reset.test.js
│       ├── restore.test.js
│       └── set.test.js
├── todo.md
├── typings/
│   └── lazyload.d.ts
└── utils/
    └── index.html
Download .txt
SYMBOL INDEX (9 symbols across 2 files)

FILE: src/constants.js
  constant SRC (line 1) | const SRC = "src";
  constant SRCSET (line 2) | const SRCSET = "srcset";
  constant SIZES (line 3) | const SIZES = "sizes";
  constant POSTER (line 4) | const POSTER = "poster";
  constant ORIGINALS (line 5) | const ORIGINALS = "llOriginalAttrs";
  constant DATA (line 6) | const DATA = "data";

FILE: typings/lazyload.d.ts
  type ILazyLoadOptions (line 1) | interface ILazyLoadOptions {
  type ILazyLoadInstance (line 283) | interface ILazyLoadInstance {
  type ILazyLoad (line 338) | interface ILazyLoad {
Condensed preview — 216 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (949K chars).
[
  {
    "path": ".babelrc",
    "chars": 164,
    "preview": "{\n  \"ignore\": [\"node_modules/**\"],\n  \"presets\": [[\"@babel/env\", { \"modules\": false }]],\n  \"env\": {\n    \"test\": {\n      \""
  },
  {
    "path": ".eslintignore",
    "chars": 12,
    "preview": "dist/**/*.js"
  },
  {
    "path": ".eslintrc.json",
    "chars": 1740,
    "preview": "{\n\t\"parserOptions\": {\n\t\t\"ecmaVersion\": 6,\n\t\t\"sourceType\": \"module\"\n\t},\n\t\"env\": {\n\t\t\"browser\": true,\n\t\t\"jest\": true\n\t},\n\t"
  },
  {
    "path": ".gitattributes",
    "chars": 482,
    "preview": "# Auto detect text files and perform LF normalization\n* text=auto\n\n# Custom for Visual Studio\n*.cs     diff=csharp\n*.sln"
  },
  {
    "path": ".github/CONTRIBUTING.md",
    "chars": 680,
    "preview": "Thank you for taking the time to contribute!\n\nTo report a bug or request an enhancement or a feature, use the [issues pa"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/bug_report.md",
    "chars": 958,
    "preview": "---\nname: Bug report\nabout: Create a report to help us improve\ntitle: ''\nlabels: 'TYPE: Bug'\nassignees: ''\n\n---\n\n**Descr"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/feature_request.md",
    "chars": 612,
    "preview": "---\nname: Feature request\nabout: Suggest an idea for this project\ntitle: ''\nlabels: 'TYPE: Enhancement'\nassignees: ''\n\n-"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/support-request.md",
    "chars": 1009,
    "preview": "---\nname: Support request\nabout: Ask a question or support\ntitle: ''\nlabels: 'TYPE: Question'\nassignees: ''\n\n---\n\n**Is y"
  },
  {
    "path": ".github/workflows/ci.yml",
    "chars": 632,
    "preview": "name: Node.js CI\n\non:\n  - push\n  - pull_request\n\njobs:\n  build:\n\n    runs-on: ${{ matrix.os }}\n\n    strategy:\n      matr"
  },
  {
    "path": ".github/workflows/playwright.yml",
    "chars": 709,
    "preview": "name: Playwright Tests\non:\n  push:\n    branches: [main, master, develop, \"feature/**\"]\n  pull_request:\n    branches: [ma"
  },
  {
    "path": ".gitignore",
    "chars": 336,
    "preview": "Thumbs.db\nehthumbs.db\n\nDesktop.ini\n\n$RECYCLE.BIN/\n\n*.cab\n*.msi\n*.msm\n*.msp\n\n.DS_Store\n.AppleDouble\n.LSOverride\n\nIcon\n\n._"
  },
  {
    "path": ".prettierrc",
    "chars": 88,
    "preview": "{\n  \"tabWidth\": 2,\n  \"useTabs\": false,\n  \"printWidth\": 100,\n  \"trailingComma\": \"none\"\n}\n"
  },
  {
    "path": ".vscode/settings.json",
    "chars": 156,
    "preview": "{\n  \"editor.codeActionsOnSave\": {\n    \"source.fixAll.eslint\": \"explicit\"\n  },\n  \"editor.tabSize\": 4,\n  \"editor.defaultFo"
  },
  {
    "path": "CHANGELOG.md",
    "chars": 30419,
    "preview": "# CHANGELOG\n\n## Version 19\n\n#### 19.1.3\n\n- File `CHANGELOG.md` is now included in the package and installed along with i"
  },
  {
    "path": "CODE_OF_CONDUCT.md",
    "chars": 3358,
    "preview": "# Contributor Covenant Code of Conduct\n\n## Our Pledge\n\nIn the interest of fostering an open and welcoming environment, w"
  },
  {
    "path": "LICENSE",
    "chars": 1073,
    "preview": "MIT License\n\nCopyright (c) 2025 Andrea Verlicchi\n\nPermission is hereby granted, free of charge, to any person obtaining "
  },
  {
    "path": "README.md",
    "chars": 60924,
    "preview": "LazyLoad is a lightweight (2.4 kB) and flexible script that **speeds up your web application** by deferring the loading "
  },
  {
    "path": "UPGRADE.md",
    "chars": 3732,
    "preview": "# 🗺 HOW TO UPDATE FROM PREVIOUS VERSIONS\n\n## Version 16 to 17\n\n**If you were NOT setting the `elements_selector` option*"
  },
  {
    "path": "_config.yml",
    "chars": 239,
    "preview": "theme: jekyll-theme-slate\ntitle: vanilla-lazyload\ndescription: LazyLoad is a fast, lightweight and flexible script that "
  },
  {
    "path": "bower.json",
    "chars": 839,
    "preview": "{\n  \"name\": \"vanilla-lazyload\",\n  \"homepage\": \"https://verlok.github.io/vanilla-lazyload/\",\n  \"authors\": [\"Andrea Verlic"
  },
  {
    "path": "currentFeature.md",
    "chars": 160,
    "preview": "# Current feature:\n\n- Unobserve all elements on `loadAll()`. It's better for performance. It solves #469.\n- Added some h"
  },
  {
    "path": "demos/async.html",
    "chars": 14039,
    "preview": "<!DOCTYPE html>\n<html>\n  <head lang=\"en\">\n    <meta charset=\"UTF-8\" />\n    <title>\n      Async loading - Lazyload demos\n"
  },
  {
    "path": "demos/async_multiple.html",
    "chars": 15468,
    "preview": "<!DOCTYPE html>\n<html>\n  <head lang=\"en\">\n    <meta charset=\"UTF-8\" />\n    <title>\n      Async loading, multiple instanc"
  },
  {
    "path": "demos/background_images.html",
    "chars": 9730,
    "preview": "<!DOCTYPE html>\n<html>\n  <head lang=\"en\">\n    <meta charset=\"UTF-8\" />\n    <title>Background images - Lazyload demos</ti"
  },
  {
    "path": "demos/background_images_image-set.html",
    "chars": 10388,
    "preview": "<!DOCTYPE html>\n<html>\n  <head lang=\"en\">\n    <meta charset=\"UTF-8\" />\n    <title>Background images with \"image-set\" - L"
  },
  {
    "path": "demos/background_images_multi.html",
    "chars": 14209,
    "preview": "<!DOCTYPE html>\n<html>\n  <head lang=\"en\">\n    <meta charset=\"UTF-8\" />\n    <title>Multiple background images - Lazyload "
  },
  {
    "path": "demos/container_multiple.html",
    "chars": 15266,
    "preview": "<!DOCTYPE html>\n<html>\n  <head lang=\"en\">\n    <meta charset=\"UTF-8\" />\n    <title>\n      Multiple scrolling container - "
  },
  {
    "path": "demos/container_single.html",
    "chars": 13916,
    "preview": "<!DOCTYPE html>\n<html>\n  <head lang=\"en\">\n    <meta charset=\"UTF-8\" />\n    <title>\n      Single scrolling container - La"
  },
  {
    "path": "demos/dynamic_content.html",
    "chars": 7895,
    "preview": "<!DOCTYPE html>\n<html>\n  <head lang=\"en\">\n    <meta charset=\"UTF-8\" />\n    <title>\n      Dynamic content - Lazyload demo"
  },
  {
    "path": "demos/dynamic_content_nodeset.html",
    "chars": 7081,
    "preview": "<!DOCTYPE html>\n<html>\n  <head lang=\"en\">\n    <meta charset=\"UTF-8\" />\n    <title>\n      Dynamic content passing nodeset"
  },
  {
    "path": "demos/embedded.html",
    "chars": 737,
    "preview": "<!DOCTYPE html>\n<html>\n  <head lang=\"en\">\n    <meta charset=\"UTF-8\" />\n    <title>Basic - Lazyload demos</title>\n    <me"
  },
  {
    "path": "demos/error_no_restore.html",
    "chars": 14096,
    "preview": "<!DOCTYPE html>\n<html>\n  <head lang=\"en\">\n    <meta charset=\"UTF-8\" />\n    <title>\n      Error, no restore - Lazyload de"
  },
  {
    "path": "demos/error_restore.html",
    "chars": 18261,
    "preview": "<!DOCTYPE html>\n<html>\n  <head lang=\"en\">\n    <meta charset=\"UTF-8\" />\n    <title>\n      Error, restore - Lazyload demos"
  },
  {
    "path": "demos/esm.html",
    "chars": 13448,
    "preview": "<!DOCTYPE html>\n<html>\n  <head lang=\"en\">\n    <meta charset=\"UTF-8\" />\n    <title>ESM version - Lazyload demos</title>\n "
  },
  {
    "path": "demos/fade_in.html",
    "chars": 14055,
    "preview": "<!DOCTYPE html>\n<html>\n  <head lang=\"en\">\n    <meta charset=\"UTF-8\" />\n    <title>\n      Fade in effect - Lazyload demos"
  },
  {
    "path": "demos/hundreds.html",
    "chars": 95472,
    "preview": "<!DOCTYPE html>\n<html>\n  <head lang=\"en\">\n    <meta charset=\"UTF-8\" />\n    <title>\n      Hundreds of items - Lazyload de"
  },
  {
    "path": "demos/iframes/i01.html",
    "chars": 67,
    "preview": "<h1>iframe 01</h1>\n<p>Hello, I'm in iframe</p>\n<p>Lazily loaded</p>"
  },
  {
    "path": "demos/iframes/i02.html",
    "chars": 67,
    "preview": "<h1>iframe 02</h1>\n<p>Hello, I'm in iframe</p>\n<p>Lazily loaded</p>"
  },
  {
    "path": "demos/iframes/i03.html",
    "chars": 67,
    "preview": "<h1>iframe 03</h1>\n<p>Hello, I'm in iframe</p>\n<p>Lazily loaded</p>"
  },
  {
    "path": "demos/iframes.html",
    "chars": 3803,
    "preview": "<!DOCTYPE html>\n<html>\n  <head lang=\"en\">\n    <meta charset=\"UTF-8\" />\n    <title>\n      Lazy iframes - Lazyload demos\n "
  },
  {
    "path": "demos/image_basic.html",
    "chars": 14085,
    "preview": "<!DOCTYPE html>\n<html>\n  <head lang=\"en\">\n    <meta charset=\"UTF-8\" />\n    <title>\n      Basic - Lazyload demos\n    </ti"
  },
  {
    "path": "demos/image_hidden.html",
    "chars": 5631,
    "preview": "<!DOCTYPE html>\n<html>\n  <head lang=\"en\">\n    <meta charset=\"UTF-8\" />\n    <title>\n      Hidden images - Lazyload demos\n"
  },
  {
    "path": "demos/image_no_classes.html",
    "chars": 14037,
    "preview": "<!DOCTYPE html>\n<html>\n  <head lang=\"en\">\n    <meta charset=\"UTF-8\" />\n    <title>\n      Basic - Lazyload demos\n    </ti"
  },
  {
    "path": "demos/image_ph_external.html",
    "chars": 15655,
    "preview": "<!DOCTYPE html>\n<html>\n  <head lang=\"en\">\n    <meta charset=\"UTF-8\" />\n    <title>\n      Images with external placeholde"
  },
  {
    "path": "demos/image_ph_inline.html",
    "chars": 18273,
    "preview": "<!DOCTYPE html>\n<html>\n  <head lang=\"en\">\n    <meta charset=\"UTF-8\" />\n    <title>\n      Images with inline placeholder "
  },
  {
    "path": "demos/image_srcset.html",
    "chars": 15703,
    "preview": "<!DOCTYPE html>\n<html>\n  <head lang=\"en\">\n    <meta charset=\"UTF-8\" />\n    <title>\n      Images with srcset without size"
  },
  {
    "path": "demos/image_srcset_lazy_sizes.html",
    "chars": 17176,
    "preview": "<!DOCTYPE html>\n<html>\n  <head lang=\"en\">\n    <meta charset=\"UTF-8\" />\n    <title>\n      Images with srcset and lazy siz"
  },
  {
    "path": "demos/image_srcset_sizes.html",
    "chars": 16987,
    "preview": "<!DOCTYPE html>\n<html>\n  <head lang=\"en\">\n    <meta charset=\"UTF-8\" />\n    <title>\n      Images with srcset and eager si"
  },
  {
    "path": "demos/lazily_load_lazyLoad.html",
    "chars": 35700,
    "preview": "<!DOCTYPE html>\n<html>\n  <head lang=\"en\">\n    <meta charset=\"UTF-8\" />\n    <title>\n      Lazyly load lazyload - Lazyload"
  },
  {
    "path": "demos/lazy_functions.html",
    "chars": 13996,
    "preview": "<!DOCTYPE html>\n<html>\n  <head lang=\"en\">\n    <meta charset=\"UTF-8\" />\n    <title>\n      Lazy functions - Lazyload demos"
  },
  {
    "path": "demos/load.html",
    "chars": 12051,
    "preview": "<!DOCTYPE html>\n<html lang=\"en\">\n  <head>\n    <meta charset=\"utf-8\" />\n    <meta name=\"viewport\" content=\"width=device-w"
  },
  {
    "path": "demos/load_all.html",
    "chars": 15054,
    "preview": "<!DOCTYPE html>\n<html>\n  <head lang=\"en\">\n    <meta charset=\"UTF-8\" />\n    <title>\n      Load all - Lazyload demos\n    <"
  },
  {
    "path": "demos/native_lazyload.html",
    "chars": 11129,
    "preview": "<!DOCTYPE html>\n<html>\n  <head lang=\"en\">\n    <meta charset=\"UTF-8\" />\n    <title>Native lazy loading - Lazyload demos</"
  },
  {
    "path": "demos/native_lazyload_conditional.html",
    "chars": 7136,
    "preview": "<!DOCTYPE html>\n<html>\n  <head lang=\"en\">\n    <meta charset=\"UTF-8\" />\n    <title>Conditional native lazy loading - Lazy"
  },
  {
    "path": "demos/object.html",
    "chars": 3854,
    "preview": "<!DOCTYPE html>\n<html>\n  <head lang=\"en\">\n    <meta charset=\"UTF-8\" />\n    <title>\n      Lazy object - Lazyload demos\n  "
  },
  {
    "path": "demos/picture_media.html",
    "chars": 23962,
    "preview": "<!DOCTYPE html>\n<html>\n  <head lang=\"en\">\n    <meta charset=\"UTF-8\" />\n    <title>Picture with media attribute in source"
  },
  {
    "path": "demos/picture_type_avif.html",
    "chars": 25753,
    "preview": "<!DOCTYPE html>\n<html>\n  <head lang=\"en\">\n    <meta charset=\"UTF-8\" />\n    <meta name=\"viewport\" content=\"width=device-w"
  },
  {
    "path": "demos/popup_layer.html",
    "chars": 14410,
    "preview": "<!DOCTYPE html>\n<html>\n  <head lang=\"en\">\n    <meta charset=\"UTF-8\" />\n    <title>\n      Popup layer - Lazyload demos\n  "
  },
  {
    "path": "demos/print.html",
    "chars": 17136,
    "preview": "<!DOCTYPE html>\n<html>\n  <head lang=\"en\">\n    <meta charset=\"UTF-8\" />\n    <title>\n      Print - Lazyload demos\n    </ti"
  },
  {
    "path": "demos/restore_destroy.html",
    "chars": 15077,
    "preview": "<!DOCTYPE html>\n<html>\n  <head lang=\"en\">\n    <meta charset=\"UTF-8\" />\n    <title>Restore and Destroy - Lazyload demos</"
  },
  {
    "path": "demos/sliders_css_only.html",
    "chars": 8543,
    "preview": "<!DOCTYPE html>\n<html>\n  <head lang=\"en\">\n    <meta charset=\"UTF-8\" />\n    <title>Swipey CSS only - Lazyload demos</titl"
  },
  {
    "path": "demos/swiper.html",
    "chars": 10152,
    "preview": "<!DOCTYPE html>\n<html>\n  <head lang=\"en\">\n    <meta charset=\"UTF-8\" />\n    <title>Swiper lazily initialized - Lazyload d"
  },
  {
    "path": "demos/thresholds.html",
    "chars": 17257,
    "preview": "<!DOCTYPE html>\n<html>\n  <head lang=\"en\">\n    <meta charset=\"UTF-8\" />\n    <title>\n      Threshold and thresholds - Lazy"
  },
  {
    "path": "demos/video.html",
    "chars": 3422,
    "preview": "<!DOCTYPE html>\n<html>\n  <head lang=\"en\">\n    <meta charset=\"UTF-8\" />\n    <title>Lazy video - Lazyload demos</title>\n  "
  },
  {
    "path": "demos/video_autoplay.html",
    "chars": 3477,
    "preview": "<!DOCTYPE html>\n<html>\n  <head lang=\"en\">\n    <meta charset=\"UTF-8\" />\n    <title>Lazy autoplay video - Lazyload demos</"
  },
  {
    "path": "dist/esm/autoInitialize.js",
    "chars": 332,
    "preview": "const t=function(t,e){let n;const i=\"LazyLoad::Initialized\",o=new t(e);try{n=new CustomEvent(i,{detail:{instance:o}})}ca"
  },
  {
    "path": "dist/esm/callback.js",
    "chars": 118,
    "preview": "const o=(o,t,i,n)=>{o&&\"function\"==typeof o&&(void 0===n?void 0===i?o(t):o(t,i):o(t,i,n))};export{o as safeCallback};\n"
  },
  {
    "path": "dist/esm/cancelOnExit.js",
    "chars": 506,
    "preview": "import{removeEventListeners as o}from\"./event.js\";import{resetSourcesImg as r}from\"./reset.js\";import{restoreImg as t}fr"
  },
  {
    "path": "dist/esm/class.js",
    "chars": 183,
    "preview": "import{runningOnBrowser as s}from\"./environment.js\";const o=(o,t)=>{s&&\"\"!==t&&o.classList.add(t)},t=(o,t)=>{s&&\"\"!==t&&"
  },
  {
    "path": "dist/esm/constants.js",
    "chars": 153,
    "preview": "const s=\"src\",t=\"srcset\",r=\"sizes\",e=\"poster\",a=\"llOriginalAttrs\",c=\"data\";export{c as DATA,a as ORIGINALS,e as POSTER,r"
  },
  {
    "path": "dist/esm/counters.js",
    "chars": 270,
    "preview": "const o=(o,t)=>{o&&(o.loadingCount+=t)},t=o=>{o&&(o.toLoadCount-=1)},n=(o,t)=>{o&&(o.toLoadCount=t)},a=o=>o.loadingCount"
  },
  {
    "path": "dist/esm/data.js",
    "chars": 585,
    "preview": "import{statusNative as t,statusLoading as e,statusError as l,statusLoaded as u,statusApplied as n}from\"./elementStatus.j"
  },
  {
    "path": "dist/esm/defaults.js",
    "chars": 814,
    "preview": "import{isBot as l,runningOnBrowser as e}from\"./environment.js\";const a={elements_selector:\".lazy\",container:l||e?documen"
  },
  {
    "path": "dist/esm/dom.js",
    "chars": 360,
    "preview": "import{hasEmptyStatus as e,hasStatusError as r}from\"./data.js\";const t=e=>Array.prototype.slice.call(e),l=e=>e.container"
  },
  {
    "path": "dist/esm/elementStatus.js",
    "chars": 193,
    "preview": "const e=\"loading\",d=\"loaded\",o=\"applied\",r=\"entered\",a=\"error\",n=\"native\";export{o as statusApplied,r as statusEntered,a"
  },
  {
    "path": "dist/esm/environment.js",
    "chars": 239,
    "preview": "const e=\"undefined\"!=typeof window,i=e&&!(\"onscroll\"in window)||\"undefined\"!=typeof navigator&&/(gle|ing|ro)bot|crawl|sp"
  },
  {
    "path": "dist/esm/event.js",
    "chars": 1631,
    "preview": "import{addClass as r,removeClass as o}from\"./class.js\";import{safeCallback as s}from\"./callback.js\";import{hasStatusNati"
  },
  {
    "path": "dist/esm/forEachSource.js",
    "chars": 258,
    "preview": "const e=e=>{let t=[];for(let r,a=0;r=e.children[a];a+=1)\"SOURCE\"===r.tagName&&t.push(r);return t},t=(t,r)=>{const a=t.pa"
  },
  {
    "path": "dist/esm/intersectionHandlers.js",
    "chars": 607,
    "preview": "import{safeCallback as t}from\"./callback.js\";import{load as o}from\"./load.js\";import{hadStartedLoading as s,setStatus as"
  },
  {
    "path": "dist/esm/intersectionObserver.js",
    "chars": 600,
    "preview": "import{onEnter as r,onExit as e}from\"./intersectionHandlers.js\";import{shouldUseNative as o}from\"./native.js\";import{res"
  },
  {
    "path": "dist/esm/lazyload.js",
    "chars": 1457,
    "preview": "import{getExtendedSettings as t}from\"./defaults.js\";import{autoInitialize as o}from\"./autoInitialize.js\";import{load as "
  },
  {
    "path": "dist/esm/load.js",
    "chars": 636,
    "preview": "import{setBackground as t,setMultiBackground as o,setImgsetBackground as r,setSources as m,setSourcesNative as e}from\"./"
  },
  {
    "path": "dist/esm/native.js",
    "chars": 300,
    "preview": "import{loadNative as o}from\"./load.js\";import{setToLoadCount as e}from\"./counters.js\";const t=[\"IMG\",\"IFRAME\",\"VIDEO\"],r"
  },
  {
    "path": "dist/esm/online.js",
    "chars": 506,
    "preview": "import{runningOnBrowser as n}from\"./environment.js\";import{resetStatus as o}from\"./data.js\";import{removeClass as e}from"
  },
  {
    "path": "dist/esm/originalAttributes.js",
    "chars": 784,
    "preview": "import{ORIGINALS as t,SRC as e,POSTER as r,SRCSET as o,SIZES as n,DATA as a}from\"./constants.js\";const c=[e],s=[e,r],u=["
  },
  {
    "path": "dist/esm/reset.js",
    "chars": 253,
    "preview": "import{SRC as t,SRCSET as r,SIZES as o}from\"./constants.js\";import{forEachPictureSource as e}from\"./forEachSource.js\";co"
  },
  {
    "path": "dist/esm/restore.js",
    "chars": 849,
    "preview": "import{removeClass as s}from\"./class.js\";import{resetStatus as o,hasEmptyStatus as a,hasStatusNative as r}from\"./data.js"
  },
  {
    "path": "dist/esm/set.js",
    "chars": 2073,
    "preview": "import{SRC as t,POSTER as a,DATA as s,SIZES as o,SRCSET as r}from\"./constants.js\";import{getData as e,setStatus as m}fro"
  },
  {
    "path": "dist/esm/tempImage.js",
    "chars": 170,
    "preview": "const e=e=>{e.llTempImage=document.createElement(\"IMG\")},l=e=>{delete e.llTempImage},m=e=>e.llTempImage;export{e as addT"
  },
  {
    "path": "dist/esm/unobserve.js",
    "chars": 196,
    "preview": "const e=(e,n)=>{if(!n)return;const r=n._observer;r&&r.unobserve(e)},n=e=>{e.disconnect()},r=(n,r,o)=>{r.unobserve_entere"
  },
  {
    "path": "dist/lazyload.iife.js",
    "chars": 24590,
    "preview": "var LazyLoad = (function () {\n  'use strict';\n\n  const runningOnBrowser = typeof window !== \"undefined\";\n  const isBot ="
  },
  {
    "path": "dist/lazyload.js",
    "chars": 24877,
    "preview": "(function (global, factory) {\n  typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory("
  },
  {
    "path": "funding.yml",
    "chars": 67,
    "preview": "github: verlok\nko_fi: verlok\ncustom: \"https://www.paypal.me/verlok\""
  },
  {
    "path": "jest.config.cjs",
    "chars": 229,
    "preview": "/** @type {import('jest').Config} */\nmodule.exports = {\n  verbose: true,\n  testMatch: [\"<rootDir>/tests/unit/**/*.test.j"
  },
  {
    "path": "package.json",
    "chars": 2272,
    "preview": "{\n  \"name\": \"vanilla-lazyload\",\n  \"version\": \"19.1.3\",\n  \"description\": \"LazyLoad is a lightweight (2.4 kB) and flexible"
  },
  {
    "path": "playwright.config.js",
    "chars": 1795,
    "preview": "// @ts-check\nconst { defineConfig, devices } = require('@playwright/test');\n\n/**\n * Read environment variables from file"
  },
  {
    "path": "rollup.config.mjs",
    "chars": 1100,
    "preview": "import terser from \"@rollup/plugin-terser\";\nimport resolve from \"@rollup/plugin-node-resolve\";\nimport babel from \"@rollu"
  },
  {
    "path": "src/autoInitialize.js",
    "chars": 1019,
    "preview": "/* Creates instance and notifies it through the window element */\nconst createInstance = function(classObj, options) {\n "
  },
  {
    "path": "src/callback.js",
    "chars": 300,
    "preview": "export const safeCallback = (callback, arg1, arg2, arg3) => {\n  if (!callback || typeof callback !== 'function') {\n    r"
  },
  {
    "path": "src/cancelOnExit.js",
    "chars": 799,
    "preview": "import { removeEventListeners } from \"./event\";\nimport { resetSourcesImg } from \"./reset\";\nimport { restoreImg } from \"."
  },
  {
    "path": "src/class.js",
    "chars": 406,
    "preview": "import { runningOnBrowser } from \"./environment\";\n\nexport const addClass = (element, className) => {\n  if (!runningOnBro"
  },
  {
    "path": "src/constants.js",
    "chars": 191,
    "preview": "export const SRC = \"src\";\nexport const SRCSET = \"srcset\";\nexport const SIZES = \"sizes\";\nexport const POSTER = \"poster\";\n"
  },
  {
    "path": "src/counters.js",
    "chars": 493,
    "preview": "export const updateLoadingCount = (instance, delta) => {\n  if (!instance) return;\n  instance.loadingCount += delta;\n};\n\n"
  },
  {
    "path": "src/data.js",
    "chars": 1234,
    "preview": "import { statusApplied, statusError, statusLoaded, statusLoading, statusNative } from \"./elementStatus\";\n\nconst dataPref"
  },
  {
    "path": "src/defaults.js",
    "chars": 1054,
    "preview": "import { isBot, runningOnBrowser } from \"./environment\";\n\nconst defaultSettings = {\n  elements_selector: \".lazy\",\n  cont"
  },
  {
    "path": "src/dom.js",
    "chars": 606,
    "preview": "import { hasEmptyStatus, hasStatusError } from \"./data\";\n\nexport const toArray = (nodeSet) => Array.prototype.slice.call"
  },
  {
    "path": "src/elementStatus.js",
    "chars": 232,
    "preview": "export const statusLoading = \"loading\";\nexport const statusLoaded = \"loaded\";\nexport const statusApplied = \"applied\";\nex"
  },
  {
    "path": "src/environment.js",
    "chars": 308,
    "preview": "export const runningOnBrowser = typeof window !== \"undefined\";\n\nexport const isBot =\n  (runningOnBrowser && !(\"onscroll\""
  },
  {
    "path": "src/event.js",
    "chars": 3576,
    "preview": "import { addClass, removeClass } from \"./class\";\nimport { safeCallback } from \"./callback\";\nimport { hasStatusNative, se"
  },
  {
    "path": "src/forEachSource.js",
    "chars": 598,
    "preview": "const getSourceTags = (parentTag) => {\n  let sourceTags = [];\n  for (let i = 0, childTag; (childTag = parentTag.children"
  },
  {
    "path": "src/intersectionHandlers.js",
    "chars": 1153,
    "preview": "import { safeCallback } from \"./callback\";\nimport { load } from \"./load\";\nimport { hadStartedLoading, hasEmptyStatus, se"
  },
  {
    "path": "src/intersectionObserver.js",
    "chars": 1202,
    "preview": "import { onEnter, onExit } from \"./intersectionHandlers\";\nimport { shouldUseNative } from \"./native\";\nimport { resetObse"
  },
  {
    "path": "src/lazyload.js",
    "chars": 2666,
    "preview": "import { getExtendedSettings } from \"./defaults\";\nimport { autoInitialize } from \"./autoInitialize\";\nimport { load } fro"
  },
  {
    "path": "src/load.js",
    "chars": 1304,
    "preview": "import { setBackground, setImgsetBackground, setMultiBackground, setSources, setSourcesNative } from \"./set\";\nimport { s"
  },
  {
    "path": "src/native.js",
    "chars": 517,
    "preview": "import { loadNative } from \"./load\";\nimport { setToLoadCount } from \"./counters\";\n\nconst tagsWithNativeLazy = [\"IMG\", \"I"
  },
  {
    "path": "src/online.js",
    "chars": 860,
    "preview": "import { runningOnBrowser } from \"./environment\";\nimport { resetStatus } from \"./data\";\nimport { removeClass } from \"./c"
  },
  {
    "path": "src/originalAttributes.js",
    "chars": 1622,
    "preview": "import { DATA, ORIGINALS, POSTER, SIZES, SRC, SRCSET } from \"./constants.js\";\n\nexport const attrsSrc = [SRC];\nexport con"
  },
  {
    "path": "src/reset.js",
    "chars": 435,
    "preview": "import { SIZES, SRC, SRCSET } from \"./constants.js\";\nimport { forEachPictureSource } from \"./forEachSource\";\n\nconst remo"
  },
  {
    "path": "src/restore.js",
    "chars": 1887,
    "preview": "import { removeClass } from \"./class\";\n\nimport { hasEmptyStatus, hasStatusNative, resetStatus } from \"./data\";\nimport { "
  },
  {
    "path": "src/set.js",
    "chars": 5020,
    "preview": "import { DATA, POSTER, SIZES, SRC, SRCSET } from \"./constants.js\";\nimport { getData, setStatus } from \"./data\";\nimport {"
  },
  {
    "path": "src/tempImage.js",
    "chars": 244,
    "preview": "export const addTempImage = (element) => {\n  element.llTempImage = document.createElement(\"IMG\");\n};\n\nexport const delet"
  },
  {
    "path": "src/unobserve.js",
    "chars": 381,
    "preview": "export const unobserve = (element, instance) => {\n  if (!instance) return;\n  const observer = instance._observer;\n  if ("
  },
  {
    "path": "tests/e2e/background_image.spec.js",
    "chars": 1345,
    "preview": "import { expect, test } from \"@playwright/test\";\n\nconst pagesWithSimpleImages = [\n  { url: \"/demos/background_images.htm"
  },
  {
    "path": "tests/e2e/background_image_multi.spec.js",
    "chars": 1383,
    "preview": "import { expect, test } from \"@playwright/test\";\n\nconst pagesWithSimpleImages = [\n  { url: \"/demos/background_images_mul"
  },
  {
    "path": "tests/e2e/image_basic.spec.js",
    "chars": 1140,
    "preview": "import { expect, test } from \"@playwright/test\";\n\nconst pagesWithSimpleImages = [\n  { url: \"/demos/image_basic.html\", de"
  },
  {
    "path": "tests/unit/cancelOnExit.test.js",
    "chars": 3638,
    "preview": "import expectExtend from \"./lib/expectExtend\";\nimport getFakeInstance from \"./lib/getFakeInstance\";\nimport { expect, bef"
  },
  {
    "path": "tests/unit/lib/expectExtend.js",
    "chars": 1310,
    "preview": "const extensions = {\n  toHaveAttributeValue: (element, attributeName, valueToVerify) => {\n    const actualValue = elemen"
  },
  {
    "path": "tests/unit/lib/getFakeInstance.js",
    "chars": 82,
    "preview": "export default () => {\n  return {\n    loadingCount: 0,\n    toLoadCount: 0\n  };\n};\n"
  },
  {
    "path": "tests/unit/load.test.js",
    "chars": 1260,
    "preview": "import expectExtend from \"./lib/expectExtend\";\nimport getFakeInstance from \"./lib/getFakeInstance\";\nimport { expect, bef"
  },
  {
    "path": "tests/unit/originalAttributes.test.js",
    "chars": 1582,
    "preview": "import expectExtend from \"./lib/expectExtend\";\nimport getFakeInstance from \"./lib/getFakeInstance\";\nimport { getExtended"
  },
  {
    "path": "tests/unit/reset.test.js",
    "chars": 1200,
    "preview": "import expectExtend from \"./lib/expectExtend\";\nimport getFakeInstance from \"./lib/getFakeInstance\";\nimport { getExtended"
  },
  {
    "path": "tests/unit/restore.test.js",
    "chars": 12966,
    "preview": "import expectExtend from \"./lib/expectExtend\";\nimport getFakeInstance from \"./lib/getFakeInstance\";\nimport { beforeEach,"
  },
  {
    "path": "tests/unit/set.test.js",
    "chars": 9462,
    "preview": "import expectExtend from \"./lib/expectExtend\";\nimport getFakeInstance from \"./lib/getFakeInstance\";\nimport { getExtended"
  },
  {
    "path": "todo.md",
    "chars": 716,
    "preview": "# TODO\n\n## 1\n\nCheck why the demo `./demos/restore_destroy.html` is not working. What was it supposed to do? :D\n\n\n## To c"
  },
  {
    "path": "typings/lazyload.d.ts",
    "chars": 11264,
    "preview": "export interface ILazyLoadOptions {\n  /**\n     * The CSS selector of the elements to load lazily, which will be selecte"
  },
  {
    "path": "utils/index.html",
    "chars": 13015,
    "preview": "<!DOCTYPE html>\n<html>\n  <head lang=\"en\">\n    <meta charset=\"UTF-8\" />\n    <title>Self-host images generator</title>\n   "
  }
]

// ... and 80 more files (download for full content)

About this extraction

This page contains the full source code of the verlok/vanilla-lazyload GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 216 files (868.7 KB), approximately 224.7k tokens, and a symbol index with 9 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!