|
| 1 | +# Fallback Plan for Loading CSS and JS of Bootstrap 4 |
| 2 | +## Shows how to load Bootstrap from local if that from remote failed |
| 3 | +### For Bootstrap 4.0.0 ~ 4.3.1(at least) |
| 4 | +### Some discussions |
| 5 | +1. [Stack Overflow](https://stackoverflow.com/questions/25748112/load-local-bootstrap-css-and-js-if-load-fail-from-remote): load local bootstrap css and js if load fail from remote |
| 6 | +2. [Edd Mann](https://eddmann.com/posts/providing-local-js-and-css-resources-for-cdn-fallbacks/): Providing Local JS and CSS Resources for CDN Fallbacks |
| 7 | +3. [freeCodeCapm](https://www.freecodecamp.org/forum/t/using-a-fallback-code-in-case-bootstraps-cdn-is-down/160753): Using a fallback code in case bootstrap’s cdn is down |
| 8 | +### Discussions for this project |
| 9 | +By trial and error, I finally found out a better way to check and reload files when failed to load from remote. |
| 10 | + 1. It use [defer](https://stackoverflow.com/a/17914854) function to make sure jQuery is loaded. |
| 11 | + 2. It'll try only `999 times` on loading jQuery, so that you won't waste resource on keep trying. (modify as needed) |
| 12 | + 3. You cannot use `document.write()` as what jQuery does to Poper.js and Bootstrap.js since it'll [delete](https://www.w3schools.com/jsref/met_doc_write.asp) all existing HTML. |
| 13 | + 4. Also, you cannot use `$("body").append()` as what bootstrap css does, since it [won't works](https://stackoverflow.com/questions/610995/cant-append-script-element) |
| 14 | + 5. And the `<script></script>` tag should be in the DOM for debugging, so use [`appendChild()`](https://stackoverflow.com/questions/610995/cant-append-script-element#comment17105918_611016) instead. |
| 15 | + 6. Sample HTML code is avalible in [repository](/LoadBootstrap.html), while the key part (JS code) is shown below. |
| 16 | +```html |
| 17 | +<script> |
| 18 | + // MODIFY ALL URLS FOR SRC TO YOUR OWN PATH ON LOCALHOST |
| 19 | + // Test if jQuery is loaded. If not, load it locally. |
| 20 | + window.jQuery || |
| 21 | + console.log("Local jQuery") || |
| 22 | + document.write('<script type="text/javascript" src="/static/js/jquery-3.3.1.slim.min.js"><\/script>'); |
| 23 | +
|
| 24 | + // First, make sure jQuery is loaded. |
| 25 | + function defer(method, i = 0) { // defer method 50ms until jQuery is ready or counter exceed 999 |
| 26 | + if (window.jQuery) { method(); } |
| 27 | + else if (i < 999) { setTimeout(function () { defer(method, ++i) }, 50); } |
| 28 | + } |
| 29 | + function externalJS(url, log) { |
| 30 | + let script = document.createElement("script"); script.type = 'text/javascript'; script.src = url; |
| 31 | + $("body")[0].appendChild(script); // use appendChild() rather than append() |
| 32 | + if (log) { console.log(log); } |
| 33 | + } |
| 34 | + defer(function () { |
| 35 | + // Second, test Bootstrap.css by its body color. |
| 36 | + // Should be "rgb(33, 37, 41)" (#212529) if loaded. (For Bootstrap 4.0.0 ~ 4.3.1 (at least)) |
| 37 | + $("body").css("color") === "rgb(33, 37, 41)" || |
| 38 | + console.log("Local Bootstrap CSS") || |
| 39 | + $("head").append('<link rel="stylesheet" href="/static/css/bootstrap.min.css">'); |
| 40 | +
|
| 41 | + // Last, test if Proper.js, Bootstrap.js and Bootstrap.css are loaded. |
| 42 | + window.Popper || externalJS("/static/js/popper.min.js", "Local Popper"); |
| 43 | + window.jQuery.fn.modal || externalJS("/static/js/bootstrap.min.js", "Local Bootstrap JS"); |
| 44 | + }); |
| 45 | +</script> |
| 46 | +``` |
| 47 | + |
0 commit comments