├── docs ├── templates │ ├── greeting.html │ ├── footer.html │ ├── header.html │ ├── welcome.html │ ├── nested.html │ ├── head.html │ ├── nav.html │ └── countries.html ├── .DS_Store ├── images │ ├── uk.png │ ├── france.png │ ├── germany.png │ └── html-include-logo.png ├── data │ ├── france.json │ ├── germany.json │ └── uk.json ├── css │ └── style.css ├── index.html ├── nested-demo.html ├── welcome-demo.html ├── simple-demo.html ├── greeting-demo.html ├── mustache-demo.html ├── lazy-demo.html └── js │ └── HTMLInclude.js ├── .DS_Store ├── LICENSE ├── HTMLInclude.min.js ├── HTMLInclude.js └── README.md /docs/templates/greeting.html: -------------------------------------------------------------------------------- 1 |

Hello %name%!!

2 | -------------------------------------------------------------------------------- /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Paul-Browne/HTMLInclude/HEAD/.DS_Store -------------------------------------------------------------------------------- /docs/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Paul-Browne/HTMLInclude/HEAD/docs/.DS_Store -------------------------------------------------------------------------------- /docs/images/uk.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Paul-Browne/HTMLInclude/HEAD/docs/images/uk.png -------------------------------------------------------------------------------- /docs/images/france.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Paul-Browne/HTMLInclude/HEAD/docs/images/france.png -------------------------------------------------------------------------------- /docs/images/germany.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Paul-Browne/HTMLInclude/HEAD/docs/images/germany.png -------------------------------------------------------------------------------- /docs/templates/footer.html: -------------------------------------------------------------------------------- 1 | 4 | -------------------------------------------------------------------------------- /docs/templates/header.html: -------------------------------------------------------------------------------- 1 |
2 |

This is the content of header.html!

3 |
4 | -------------------------------------------------------------------------------- /docs/templates/welcome.html: -------------------------------------------------------------------------------- 1 |

%welcome% %welcome% %name%!!

2 |

I am very %emotion% to meet you!

3 | -------------------------------------------------------------------------------- /docs/images/html-include-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Paul-Browne/HTMLInclude/HEAD/docs/images/html-include-logo.png -------------------------------------------------------------------------------- /docs/data/france.json: -------------------------------------------------------------------------------- 1 | { 2 | "country": "France", 3 | "population": "67 million", 4 | "size": "643,801 km²", 5 | "lang": "French" 6 | } 7 | -------------------------------------------------------------------------------- /docs/data/germany.json: -------------------------------------------------------------------------------- 1 | { 2 | "country": "Germany", 3 | "population": "83 million", 4 | "size": "357,386 km²", 5 | "lang": "German" 6 | } 7 | -------------------------------------------------------------------------------- /docs/data/uk.json: -------------------------------------------------------------------------------- 1 | { 2 | "country": "United Kingdom", 3 | "population": "66 million", 4 | "size": "242,495 km²", 5 | "lang": "English" 6 | } 7 | -------------------------------------------------------------------------------- /docs/templates/nested.html: -------------------------------------------------------------------------------- 1 |
2 |

Nested includes example

3 |
4 | 5 | -------------------------------------------------------------------------------- /docs/css/style.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 10px; 3 | font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu,Cantarell, "Helvetica Neue", sans-serif; 4 | } 5 | 6 | img{ 7 | max-width: 100%; 8 | height: auto; 9 | vertical-align: middle; 10 | } -------------------------------------------------------------------------------- /docs/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /docs/nested-demo.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 |
9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /docs/templates/head.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /docs/welcome-demo.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 |
9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /docs/simple-demo.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 |
9 |

Bunch of regular content

10 |
11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /docs/greeting-demo.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 |
9 |
10 |
11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /docs/mustache-demo.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 |
9 |
10 |
11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /docs/templates/nav.html: -------------------------------------------------------------------------------- 1 | 26 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 paulbrowne 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /HTMLInclude.min.js: -------------------------------------------------------------------------------- 1 | /*! HTMLInclude v1.1.1 | MIT License | github.com/paul-browne/HTMLInclude */ 2 | !function(l,d){l.HTMLInclude||(l.HTMLInclude=function(){function r(t,e){return t.getBoundingClientRect().top<=+e+l.innerHeight}function a(t,e){var o=new XMLHttpRequest;o.onreadystatechange=function(){4==o.readyState&&200==o.status&&e.forEach(function(t){var e=t.getAttribute("data-replace"),n=o.responseText;e&&e.split(",").forEach(function(t){var e=t.trim().split(":");n=n.replace(new RegExp(e[0],"g"),e[1])}),t.outerHTML=n;for(var r=(new DOMParser).parseFromString(n,"text/html").querySelectorAll("SCRIPT"),a=0,i=r.length;a 2 | 3 | 4 | 5 | 10 | 11 | 12 |
13 |

Open the dev tools, and inspect the network.

14 |

scroll down

15 |

scroll down

16 |

scroll down

17 |

scroll down

18 |

scroll down

19 |

scroll down

20 |

scroll down

21 |

scroll down

22 |

scroll down

23 |

scroll down

24 |

scroll down

25 |

scroll down

26 |

scroll down

27 |

scroll down

28 |

scroll down

29 |

scroll down

30 |

scroll down

31 |

scroll down

32 |

scroll down

33 |

scroll down

34 |

scroll down

35 |

scroll down

36 |
37 |
38 |
39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /HTMLInclude.js: -------------------------------------------------------------------------------- 1 | /*! HTMLInclude v1.1.1 | MIT License | github.com/paul-browne/HTMLInclude */ 2 | !function(w, d) { 3 | if (!w.HTMLInclude) { 4 | w.HTMLInclude = function() { 5 | function isInViewport(element, offset) { 6 | return element.getBoundingClientRect().top <= (+offset + w.innerHeight); 7 | } 8 | function ajax(url, elements) { 9 | var xhr = new XMLHttpRequest(); 10 | xhr.onreadystatechange = function() { 11 | if (xhr.readyState == 4 && xhr.status == 200) { 12 | elements.forEach(function(element) { 13 | var dataReplace = element.getAttribute("data-replace"); 14 | var z = xhr.responseText; 15 | if (dataReplace) { 16 | dataReplace.split(",").forEach(function(el) { 17 | var o = el.trim().split(":"); 18 | z = z.replace(new RegExp(o[0], "g"), o[1]); 19 | }); 20 | } 21 | element.outerHTML = z; 22 | var scripts = new DOMParser().parseFromString(z, 'text/html').querySelectorAll("SCRIPT"); 23 | var i = 0; 24 | var j = scripts.length; 25 | while (i < j) { 26 | var newScript = d.createElement("SCRIPT"); 27 | scripts[i].src ? newScript.src = scripts[i].src : newScript.innerHTML = scripts[i].innerHTML; 28 | d.head.appendChild(newScript); 29 | i++; 30 | } 31 | }); 32 | } 33 | }; 34 | xhr.open("GET", url, true); 35 | xhr.send(); 36 | } 37 | function lazyLoad(element, offset) { 38 | w.addEventListener("scroll", function scrollFunc() { 39 | if (isInViewport(element, offset)) { 40 | w.removeEventListener("scroll", scrollFunc); 41 | ajax(element.getAttribute("data-include"), [element]); 42 | } 43 | }) 44 | } 45 | var store = {}; 46 | var dis = d.querySelectorAll('[data-include]:not([data-in])'); 47 | var i = dis.length; 48 | while (i--) { 49 | var di = dis[i].getAttribute('data-include'); 50 | var laziness = dis[i].getAttribute('data-lazy'); 51 | dis[i].setAttribute("data-in", ""); 52 | if (!laziness || (laziness && isInViewport(dis[i], laziness))) { 53 | store[di] = store[di] || []; 54 | store[di].push(dis[i]); 55 | } else { 56 | lazyLoad(dis[i], laziness); 57 | } 58 | } 59 | for (var key in store) { 60 | ajax(key, store[key]); 61 | } 62 | } 63 | } 64 | w.HTMLInclude(); 65 | }(window, document) -------------------------------------------------------------------------------- /docs/js/HTMLInclude.js: -------------------------------------------------------------------------------- 1 | /*! HTMLInclude v1.1.1 | MIT License | github.com/paul-browne/HTMLInclude */ 2 | !function(w, d) { 3 | if (!w.HTMLInclude) { 4 | w.HTMLInclude = function() { 5 | function isInViewport(element, offset) { 6 | return element.getBoundingClientRect().top <= (+offset + w.innerHeight); 7 | } 8 | function ajax(url, elements) { 9 | var xhr = new XMLHttpRequest(); 10 | xhr.onreadystatechange = function() { 11 | if (xhr.readyState == 4 && xhr.status == 200) { 12 | elements.forEach(function(element) { 13 | var dataReplace = element.getAttribute("data-replace"); 14 | var z = xhr.responseText; 15 | if (dataReplace) { 16 | dataReplace.split(",").forEach(function(el) { 17 | var o = el.trim().split(":"); 18 | z = z.replace(new RegExp(o[0], "g"), o[1]); 19 | }); 20 | } 21 | element.outerHTML = z; 22 | var scripts = new DOMParser().parseFromString(z, 'text/html').querySelectorAll("SCRIPT"); 23 | var i = 0; 24 | var j = scripts.length; 25 | while (i < j) { 26 | var newScript = d.createElement("SCRIPT"); 27 | scripts[i].src ? newScript.src = scripts[i].src : newScript.innerHTML = scripts[i].innerHTML; 28 | d.head.appendChild(newScript); 29 | i++; 30 | } 31 | }); 32 | } 33 | }; 34 | xhr.open("GET", url, true); 35 | xhr.send(); 36 | } 37 | function lazyLoad(element, offset) { 38 | w.addEventListener("scroll", function scrollFunc() { 39 | if (isInViewport(element, offset)) { 40 | w.removeEventListener("scroll", scrollFunc); 41 | ajax(element.getAttribute("data-include"), [element]); 42 | } 43 | }) 44 | } 45 | var store = {}; 46 | var dis = d.querySelectorAll('[data-include]:not([data-in])'); 47 | var i = dis.length; 48 | while (i--) { 49 | var di = dis[i].getAttribute('data-include'); 50 | var laziness = dis[i].getAttribute('data-lazy'); 51 | dis[i].setAttribute("data-in", ""); 52 | if (!laziness || (laziness && isInViewport(dis[i], laziness))) { 53 | store[di] = store[di] || []; 54 | store[di].push(dis[i]); 55 | } else { 56 | lazyLoad(dis[i], laziness); 57 | } 58 | } 59 | for (var key in store) { 60 | ajax(key, store[key]); 61 | } 62 | } 63 | } 64 | w.HTMLInclude(); 65 | }(window, document) -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # HTMLInclude 2 | 3 | Because, One simply does not 4 | 5 | ```html 6 | 7 | 8 | Content 9 | 10 | 11 | ``` 12 | 13 | But now you can 14 | 15 | ```html 16 | 17 |
18 | Content 19 |
20 | 21 | 22 | 23 | ``` 24 | 25 | ### [DEMO](https://paul-browne.github.io/HTMLInclude/simple-demo.html) 26 | 27 | --- 28 | 29 | Also, you can use `data-replace` to swap strings from within the `data-include` html. 30 | 31 | ```html 32 |
33 |
34 |
35 | ``` 36 | 37 | ###### greeting.html 38 | ```html 39 |

Hello %name%!!

40 | ``` 41 | 42 | ###### output 43 | ```html 44 |

Hello Mike!!

45 |

Hello Frank!!

46 |

Hello Bob!!

47 | ``` 48 | 49 | NOTE: If there are multiple instances of the string `%name%` then all will be replaced 50 | 51 | ### [DEMO](https://paul-browne.github.io/HTMLInclude/greeting-demo.html) 52 | 53 | --- 54 | 55 | You can swap multiple strings at a time 56 | 57 | ```html 58 |
59 | ``` 60 | 61 | ###### welcome.html 62 | ```html 63 |

%welcome% %name%!!

64 |

I am very %emotion% to meet you!

65 | ``` 66 | 67 | ###### output 68 | ```html 69 |

Hello Mike!!

70 |

I am very Happy to meet you!

71 | ``` 72 | 73 | ### [DEMO](https://paul-browne.github.io/HTMLInclude/welcome-demo.html) 74 | 75 | --- 76 | 77 | The most practical use case for the `data-replace` is when using a templating engine like mustache 78 | 79 | ```html 80 |
81 |
82 |
83 | ``` 84 | 85 | ### [DEMO](https://paul-browne.github.io/HTMLInclude/mustache-demo.html) 86 | 87 | --- 88 | 89 | You can also lazyload includes by passing `data-lazy="100"` the number is the offset, eg. the amount of pixels from the bottom of the screen before the include will load. (this number can be negative and the include will load after it has scrolled into view by that amount of pixels) 90 | 91 | ```html 92 |
93 |
94 |
95 | ``` 96 | 97 | Includes have no height, because they are empty (unless you add "loading..."), and this might cause following includes to be evaluated as "in the viewport" when they aren't. So you might want to add a fake height to includes before they are loaded like so 98 | 99 | ```css 100 | [data-include]{ 101 | min-height: 100px; 102 | } 103 | ``` 104 | 105 | ### [DEMO](https://paul-browne.github.io/HTMLInclude/lazy-demo.html) 106 | 107 | --- 108 | 109 | You can also nest `includes`, you'll need to call the `HTMLInclude()` function again 110 | 111 | ```html 112 |
113 | ``` 114 | 115 | ##### nested.html 116 | ```html 117 |
118 | 119 | ``` 120 | 121 | ### [DEMO](https://paul-browne.github.io/HTMLInclude/nested-demo.html) 122 | -------------------------------------------------------------------------------- /docs/templates/countries.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 12 | 13 | 28 | --------------------------------------------------------------------------------