{"id":18389550,"url":"https://github.com/anseki/eager-image-loader","last_synced_at":"2025-04-07T02:34:28.727Z","repository":{"id":57218152,"uuid":"44915845","full_name":"anseki/eager-image-loader","owner":"anseki","description":"The eager-loading for image files on the web page that loads the files according to your plan. This differs from the lazy-loading, for example, this can be used to avoid that the user waits for the loading.","archived":false,"fork":false,"pushed_at":"2022-08-19T03:01:55.000Z","size":620,"stargazers_count":25,"open_issues_count":0,"forks_count":9,"subscribers_count":6,"default_branch":"master","last_synced_at":"2025-03-22T11:45:01.699Z","etag":null,"topics":["background","backgroundimage","button","document-order","eager-load","fast","file","image","img","lazy-load","load","on-demand","pre-load","scroll","serial","src","ui","usability","user-scrolls"],"latest_commit_sha":null,"homepage":"http://anseki.github.io/eager-image-loader/","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/anseki.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-10-25T15:27:52.000Z","updated_at":"2024-11-13T17:12:54.000Z","dependencies_parsed_at":"2022-08-28T21:01:58.298Z","dependency_job_id":null,"html_url":"https://github.com/anseki/eager-image-loader","commit_stats":null,"previous_names":[],"tags_count":5,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/anseki%2Feager-image-loader","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/anseki%2Feager-image-loader/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/anseki%2Feager-image-loader/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/anseki%2Feager-image-loader/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/anseki","download_url":"https://codeload.github.com/anseki/eager-image-loader/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247583462,"owners_count":20962036,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["background","backgroundimage","button","document-order","eager-load","fast","file","image","img","lazy-load","load","on-demand","pre-load","scroll","serial","src","ui","usability","user-scrolls"],"created_at":"2024-11-06T01:43:43.546Z","updated_at":"2025-04-07T02:34:23.718Z","avatar_url":"https://github.com/anseki.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# EagerImageLoader\n\n[![npm](https://img.shields.io/npm/v/eager-image-loader.svg)](https://www.npmjs.com/package/eager-image-loader) [![GitHub issues](https://img.shields.io/github/issues/anseki/eager-image-loader.svg)](https://github.com/anseki/eager-image-loader/issues) [![dependencies](https://img.shields.io/badge/dependencies-No%20dependency-brightgreen.svg)](package.json) [![license](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)\n\nThe eager-loading for image files on the web page that loads the files according to your plan.  \nThis differs from the lazy-loading, for example, this can be used to avoid that the user waits for the loading.\n\n[![ss-01](ss-01.gif)](https://anseki.github.io/eager-image-loader/)\n[![ss-02](ss-02.gif)](https://anseki.github.io/eager-image-loader/)\n\n**See \u003ca href=\"https://anseki.github.io/eager-image-loader/\"\u003eDEMO\u003c/a\u003e**\n\n**Lazy-Loading vs. Eager-Loading**\n\nThe **lazy-loading** is very useful for the user which left your web page before the user read all. It avoids forcing that user to pay the network cost for the images the user didn't see, in the mobile networks. The image files are not loaded until it's presumed that each image is seen by the user. Therefore the user often be kept waiting it.\n\nThe **eager-loading** (i.e. EagerImageLoader) loads the image files according to specific plan or document order.  \nFor example, it loads a first image file in a hurry without other loading interfering. And after the loading a first image file finished, it starts the loading a second image file while the user is seeing a first image or reading something. As necessary, it loads the remaining image files in the order in which they would be seen by the user, one by one(default).\n\nBy default, it loads without a break. You can control that it starts and stops. For example, like the lazy-loading, EagerImageLoader loads the image files when the user scrolls the window.  \nAlso, it can pre-load the image files before those are used.\n\n```html\n\u003cscript src=\"eager-image-loader.min.js\"\u003e\u003c/script\u003e\n\u003cscript\u003enew EagerImageLoader()\u003c/script\u003e\n\n\u003c!--\nA minimum required is above code.\nYou can use this even if all of the HTML is not loaded yet.\nFor example, this can be in the head.\n--\u003e\n\n\u003cimg data-src=\"img-1.png\"\u003e\n\n\u003ciframe data-src=\"img-2.svg\"\u003e\u003c/iframe\u003e\n\u003cobject data-data=\"img-3.svg\"\u003e\u003c/object\u003e\n\n\u003cdiv data-background=\"img-4.png\"\u003e\u003c/div\u003e\n\u003cbutton data-background=\"img-5.png\"\u003e\u003c/button\u003e\n\n\u003c!--\nBy default, EagerImageLoader starts automatically.\nIt finds out the 5 elements above.\nSerially, it loads the each image file,\nand it set that file to the each element.\n--\u003e\n```\n\n## Constructor\n\n```js\nloader = new EagerImageLoader([targets[, options]])\n```\n\n### \u003ca name=\"constructor-targets\"\u003e\u003c/a\u003e`targets`\n\n*Type:* string, HTMLElement, NodeList, HTMLCollection, Elements, Object or Array  \n*Default:* `'[data-src],[data-data],[data-background]'`\n\nThe elements that specify the image files that are loaded.\n\nThe string such as `'#img-1'` is the CSS selector to select `\u003cimg id=\"img-1\"\u003e` element. The CSS selector might select multiple elements.  \nAlso, you can specify the HTMLElement such as a return value of `document.querySelector('#img-1')` or `document.getElementById('img-1')`. Note that those methods might not be able to get the target element before the HTML is loaded sufficiently (target DOM structure is ready). EagerImageLoader selects the target elements by given string after that. Therefore you can specify the string even if the HTML is not loaded yet.\n\nBy default, the URL of the image file is got via the `data-src`, `data-data` or `data-background` attribute of that element.\n\n- If that is the element that accepts the `src` attribute (e.g. `\u003cimg\u003e`, `\u003cinput\u003e`, `\u003ciframe\u003e`, etc.), the URL that was got via the `data-src` attribute of that element is set to the `src` attribute of that element after the image file was loaded.  \nFor example: `\u003cimg data-src=\"img-1.png\"\u003e`\n- If that is the element that accepts the `data` attribute (e.g. `\u003cobject\u003e`), the URL that was got via the `data-data` attribute of that element is set to the `data` attribute of that element after the image file was loaded.  \nFor example: `\u003cobject data-data=\"img-1.svg\"\u003e`\n- If that is any element that doesn't accept both the `src` and  `data` attribute (e.g. `\u003cdiv\u003e`, `\u003cbody\u003e`, `\u003csection\u003e`, etc.), the URL that was got via the `data-background` attribute of that element is set to the `style.backgroundImage` property of that element after the image file was loaded.  \nFor example: `\u003cdiv data-background=\"img-1.png\"\u003e`\n\nOr, you can specify an URL via the [`imageTarget`](#imagetarget) object.\n\nYou can specify the loading order via the Array. EagerImageLoader loads those according to the order of that Array.  \nFor example:\n\n```js\nnew EagerImageLoader([\n  '#img-1',\n  '#img-2',\n  '#img-3'\n]);\n```\n\n1. Start to load `'#img-1'`. (It means a image file `'#img-1'` points. The same hereinafter.)\n2. Start to load `'#img-2'` after `'#img-1'` was loaded.\n3. Start to load `'#img-3'` after `'#img-2'` was loaded.\n\nThe multiple image files in nested Array are loaded at the same time.  \nFor example:\n\n```js\nnew EagerImageLoader([\n  '#img-1',\n  ['#img-2a', '#img-2b', '#img-2c'],\n  '#img-3'\n]);\n```\n\n1. Start to load `'#img-1'`. (It means a image file `'#img-1'` points. The same hereinafter.)\n2. Start to load `'#img-2a'`, `'#img-2b'`, and `'#img-2c'` at the same time after `'#img-1'` was loaded.\n3. Start to load `'#img-3'` after 3 files above was loaded.\n\nIf the specific string as the CSS selector such as `'img.pic'` selects multiple elements, it is considered as an Array that includes those elements in document order.  \nFor example, the following 2 codes work same:\n\n```js\n// Single selector that selects 3 elements\nnew EagerImageLoader('#img-1,#img-2,#img-3');\n```\n\n```js\nnew EagerImageLoader([\n  '#img-1',\n  '#img-2',\n  '#img-3'\n]);\n```\n\n*Note that multiple elements are selected in document order via the string as the CSS selector.* If the codes above are used in the HTML code that is `\u003cimg id=\"img-3\"\u003e\u003cimg id=\"img-2\"\u003e\u003cimg id=\"img-1\"\u003e`, 2 codes work not same.\n\nThat string in the Array is considered as a nested Array. That is, those are loaded at the same time.  \nFor example, the following 2 codes work same:\n\n```js\nnew EagerImageLoader([\n  '#img-1',\n  '#img-2a,#img-2b,#img-2c', // Single selector that selects 3 elements\n  '#img-3'\n]);\n```\n\n```js\nnew EagerImageLoader([\n  '#img-1',\n  ['#img-2a', '#img-2b', '#img-2c'], // 3 are loaded at the same time.\n  '#img-3'\n]);\n```\n\nAlso, NodeList, HTMLCollection or Elements such as a return value of `document.querySelectorAll('img')` or `document.getElementsByTagName('img')` that includes multiple elements is considered as an Array that includes those elements. Note that those methods might not be able to get the target elements before the HTML is loaded sufficiently (target DOM structure is ready). EagerImageLoader selects the target elements by given string after that. Therefore you can specify the string even if the HTML is not loaded yet.\n\nIf something as multiple elements is specified in the nested Array, it is flattened in that nested Array.  \nFor example, the following 2 codes work same:\n\n```js\nnew EagerImageLoader([\n  '#img-1',\n              // 2nd selector in below selects 3 elements.\n  ['#img-2a', '#img-2b-x,#img-2b-y,#img-2b-z', '#img-2c'],\n  '#img-3'\n]);\n```\n\n```js\nnew EagerImageLoader([\n  '#img-1',\n  // 5 are loaded at the same time.\n  ['#img-2a', '#img-2b-x', '#img-2b-y', '#img-2b-z', '#img-2c'],\n  '#img-3'\n]);\n```\n\nIf `targets` argument is not specified, the elements that have `data-src`, `data-data` or `data-background` attribute are selected as the targets.\n\n#### `imageTarget`\n\nYou can specify the `imageTarget` object instead of others above at everywhere.  \nFor example:\n\n```js\nnew EagerImageLoader([\n  '#img-1',\n  { element: '#img-2', src: 'foo.png' }, // imageTarget object\n  '#img-3'\n]);\n```\n\nIt can have following properties.\n\n##### `element`\n\n*Type:* string, HTMLElement, NodeList, HTMLCollection, or Elements  \n*Default:* `undefined`\n\nThis works the same as case that something except for `imageTarget` object is specified, if a single element is specified.  \nFor example, `'#img-1'` works the same as `{ element: '#img-1' }`.\n\nIf one that includes multiple elements is specified, it is considered as an Array that includes copied `imageTarget` objects that have `element` property as each element, in document order. Note that those `imageTarget` objects are always put into the nested Array. That is, those are loaded at the same time.  \nFor example, the following 2 codes work same:\n\n```js\nnew EagerImageLoader([\n  { element: '#img-1,#img-2,#img-3', src: 'foo.png' }\n]);\n```\n\n```js\nnew EagerImageLoader([\n  [\n    { element: '#img-1', src: 'foo.png' },\n    { element: '#img-2', src: 'foo.png' },\n    { element: '#img-3', src: 'foo.png' }\n  ]\n]);\n```\n\nYou can specify `new Image()` to pre-load the image file you use later.\n\n```js\nnew EagerImageLoader(\n  // This image file is not shown until the button is pushed.\n  { element: new Image(), src: 'button-pushed.png' },\n);\n```\n\n##### `src`, `data`, `background`\n\n*Type:* string  \n*Default:* `undefined`\n\nThe URL of the image file that is loaded.\n\n- `src` is used when the [`element`](#element) property points the element that accepts the `src` attribute (e.g. `\u003cimg\u003e`, `\u003cinput\u003e`, `\u003ciframe\u003e`, etc.). The URL that is specified to this `src` property is set to the `src` attribute of that element after the image file was loaded.\n- `data` is used when the [`element`](#element) property points the element that accepts the `data` attribute (e.g. `\u003cobject\u003e`). The URL that is specified to this `data` property is set to the `data` attribute of that element after the image file was loaded.\n- `background` is used when the [`element`](#element) property points the element that doesn't accept both the `src` and  `data` attribute (e.g. `\u003cdiv\u003e`, `\u003cbody\u003e`, `\u003csection\u003e`, etc.). The URL that is specified to this `background` property is set to the `style.backgroundImage` property of that element after the image file was loaded.\n\nIf these are not specified, it tries to get the URL via the `data-src`, `data-data` or `data-background` attribute of that element.\n\nFor example, show the low-definition image until the original image file is loaded:\n\n```html\n\u003cdiv id=\"div-1\"\u003e\u003cimg src=\"img-1-low.jpg\"\u003e\u003c/div\u003e\n\u003cdiv id=\"div-2\"\u003e\u003cimg src=\"img-2-low.jpg\"\u003e\u003c/div\u003e\n\u003cdiv id=\"div-3\"\u003e\u003cimg src=\"img-3-low.jpg\"\u003e\u003c/div\u003e\n```\n\n```js\nnew EagerImageLoader([1, 2, 3].map(function(id) {\n  return {\n    element: '#div-' + id,\n    background: 'img-' + id + '.png'\n  };\n}));\n```\n\n```css\ndiv \u003e img         { visibility: hidden; }\ndiv.loading \u003e img { visibility: visible; }\n```\n\n##### `start`, `load`, `error`, `abort`\n\n*Type:* function  \n*Default:* `undefined`\n\nThe event handlers of the loading.\n\nThe Event object that is passed to these event handlers has `imageTarget` property that refers to this `imageTarget` object. The `this` in these event handlers also refers to this `imageTarget` object.  \nAlso, it has `eagerImageLoader` property that refers to the current instance itself.\n\nThe additional properties are added to this `imageTarget` object.\n\n- `startTime` property is the time-value (milliseconds since Unix Epoch) as the time when the loading the image file of this `imageTarget` object started.\n- `endTime` property is the time-value as the time when the loading it finished.\n\nFor example:\n\n```js\nnew EagerImageLoader({\n  element: '#img-1',\n  src: 'foo.png',\n\n  load: function(event) {\n    console.log('Loaded File: ' + this.src);\n    console.log('Loading Time: ' + (this.endTime - this.startTime) + 'ms');\n  },\n  error: function(event) {\n    console.error(event);\n  }\n});\n```\n\n```js\nvar loader = new EagerImageLoader({\n  element: '#img-1,#img-2,#img-3',\n  load: function() {\n    // Enable the \"Next\" button of Carousel Panel.\n    frameInit(loader.stepIndex - 1);\n    // Or, frameInit(event.eagerImageLoader.stepIndex - 1);\n  }\n});\n```\n\n```js\nnew EagerImageLoader({\n  element: '#img-1,#img-2,#img-3',\n  start: effectForLoading,\n  load: effectForShowing\n});\n```\n\nSee [`stop`](#stop) method also.\n\n##### `stopLoading`\n\n*Type:* boolean  \n*Default:* `false`\n\nIf `true` is specified, EagerImageLoader stops the loading, when the loading the image file of this `imageTarget` object (and all image files that start loading the same time) finished.  \nThe stopped loading can be resumed by [`start`](#start) method.\n\nFor example, it loads the image files that are parts of the UI (e.g. buttons, headers, menu items, etc.) when the page is opened, and it stops, and it loads other image files when the user scrolls the window.\n\n```js\nvar loader = new EagerImageLoader([\n  { // UI parts\n    element: '#button-1,#button-2,#button-3,#menu-1,#menu-2,',\n    stopLoading: true\n  },\n  // other images\n  '#picture-1,#picture-2,#picture-3'\n]);\n\nwindow.addEventListener('scroll', function() {\n  if (!loader.done \u0026\u0026 loader.stopped) {\n    loader.start();\n  }\n}, false);\n```\n\n### \u003ca name=\"constructor-options\"\u003e\u003c/a\u003e`options`\n\n`options` Object that is passed to the constructor can have following properties.\n\n#### `autoStart`\n\n*Type:* boolean  \n*Default:* `true`\n\nBy default, EagerImageLoader starts the loading automatically. If `false` is specified to this option, it does not start the loading until [`start`](#start) method is called.  \nFor example:\n\n```js\nvar loader = new EagerImageLoader(null, {autoStart: false});\n\nstartButton.addEventListener('click', function() {\n  loader.start();\n}, false);\n```\n\n#### `complete`\n\n*Type:* function  \n*Default:* `undefined`\n\nThe callback that is called when the loading is finished.  \n`this` in this function refers to the current instance itself.\n\nFor example:\n\n```js\nnew EagerImageLoader(\n  '#button-1,#button-2,#button-3,#menu-1,#menu-2,', // UI parts\n  {\n    complete: function() {\n      console.log('All %i steps are done.', this.targets.length);\n      controlPanelInit(); // Enable UI.\n    }\n  }\n);\n```\n\n#### `loadingClass`\n\n*Type:* string  \n*Default:* `'loading'`\n\nAdd this class name to the element when the loading the image file that element points is started, and remove it when that loading is finished.\n\n## Methods\n\n### `start`\n\n```js\nloader = loader.start()\n```\n\nStart the loading. Or resume the loading that was stopped by [`stop`](#stop) method or [`stopLoading`](#stoploading) property of [`imageTarget`](#imagetarget) object.  \nThis method returns the current instance itself.\n\n### `stop`\n\n```js\nloader = loader.stop()\n```\n\nStop the loading.  \nThe stopped loading can be resumed by [`start`](#start) method.  \nThis method returns the current instance itself.\n\nFor example, it switches to the lazy-loading, when the page was opened in the mobile network (i.e. the loading is slow):\n\n```js\nnew EagerImageLoader({\n  element: '#img-1',\n\n  load: function(event) {\n    var loadingTime = this.endTime - this.startTime,\n      speed = FILE_SIZE / (loadingTime / 1000) * 8; // bits per second\n    if (speed \u003c 74 * 1024 * 1024) { // less than 74 Mbps\n      // Switch to lazy-loading when network is slow.\n      event.eagerImageLoader.stop();\n      switch2LazyLoad();\n    }\n  }\n});\n```\n\n## Properties\n\n### \u003ca name=\"properties-targets\"\u003e\u003c/a\u003e`targets`\n\n*Type:* Array  \n*Read Only*\n\nThe [`targets`](#constructor-targets) Array that was passed to the [constructor](#constructor) and parsed and optimized.\n\n### `options`\n\n*Type:* Object\n\nThe [`options`](#constructor-options) Object that was passed to the [constructor](#constructor).\n\n### `stepIndex`\n\n*Type:* number  \n*Read Only*\n\nThe index of [`targets`](#properties-targets) Array.  \nThis is the index of the cycles of the loading. That is, it might not be the number of the files that are loaded because a single cycle might include multiple targets.\n\n### `stopped`\n\n*Type:* boolean  \n*Read Only*\n\nThe boolean to indicate whether the loading was stopped by [`stop`](#stop) method or [`stopLoading`](#stoploading) property of [`imageTarget`](#imagetarget) object.\n\n### `done`\n\n*Type:* boolean  \n*Read Only*\n\nThe boolean to indicate whether the loading was finished.\n\n---\n\nThanks for images: [Unsplash](https://unsplash.com/), [PxHere](https://pxhere.com/)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fanseki%2Feager-image-loader","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fanseki%2Feager-image-loader","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fanseki%2Feager-image-loader/lists"}