1073Javascript Images Sliders and Lightboxes

An evolving list of JS Image Sliders and Lightboxes.

Image Sliders

Slick - "the last carousel you'll ever need"

Swiper - "The Most Modern Mobile Touch Slider"

  • v11.1.12, September 1, 2024
  • 39.5k Github stars

Lightbox

Slick + Lightbox

  • Building upong Slick
  • no longer in development

Gallery/Slider AND Lightbox

PhotoSwipe

  • v5.4.4
  • 23.9k Github stars

TODO:

  • make examples and test

1053Creating & Displaying a Local Javacript-based Clock

Problem

Organizing meeting across time-zones can lead to mis-communication of the meeting start-times, especially when daylight-saving-time changes are involed.

Solution

Show the Meeting Start Time AND the current Local Time at the Meeting Website.

var f = new Intl.DateTimeFormat([], {
  timeZone: 'Asia/Tokyo',
  hour: 'numeric',
  minute: 'numeric',
  second: 'numeric',
  hourCycle: 'h23'
})
var setTime = () => document.getElementById('time').innerHTML = f.format(new Date())
setTime()
setInterval(() => setTime(), 1000)
</script>

Intl.DateTimeFormat creates a new Intl formatter. Time to be displayed: Asia/Tokyo. Displayed are only: hour, minute and second. The hourCycle' optionh23` sets the display to a 24h clock.

setTime is a function that sets the innerHTML of id element time to the current Date, formatted with the Intl date.

setTime() call the function once on load.

setInterval() repeatetly calls the setTime() function to update the clock.

986Displaying Text Data in a New Window

Problem: Data is stored in an array, you can not reload the page, you need to export it from the JS console.

Solution:

Create a New Window

var w = window.open()

Add a basic HTML header

w.document.writeln("<html><body><pre>")

Add your data

Assuming your data lives in an array called data, and has a sub-array with 2 values.

data.forEach(d => { w.document.writeln(d[0] + ", " + d[1])  })

Add a CSV Header

w.document.writeln("timestamp, temp")

Clear

w.document.body.innerHTML = "";

970Parsing Body JSON for quick inspection

An API dumps its output as string in the HTML body. Not really much use, not really easy to inspect it. The solutions? Parse the body with JSON.parse an inspect it in the console.

JSON.parse(document.body.textContent)
[{"id":115,"date":"2020-11-09T02:57:48","date_gmt":"2020-11-09T02:57:48","guid":{"rendered":"http:\/\/127.0.0.1\/aaa\/?
post_type=jobs&#038;p=115"},"modified":"2020-11-09T05:22:55","modified_gmt":"2020-11-09T05:22:55","slug":"another-test-
job","status":"publish","type":"jobs","link":"http:\/\/127.0.0.1\/aaa\/jobs\/another-test-job\/","title":{"rendered":"Another Test 
Job"},"parent":0,"menu_order":0,"template":"","_links":{"self":[{"href":"http:\/\/127.0.0.1\/aaa\/wp-
json\/wp\/v2\/jobs\/115"}],"collection":[{"href":"http:\/\/127.0.0.1\/aaa\/wp-json\/wp\/v2\/jobs"}],"about":
[{"href":"http:\/\/127.0.0.1\/aaa\/wp-json\/wp\/v2\/types\/jobs"}],"wp:attachment":[{"href":"http:\/\/127.0.0.1\/aaa\/wp-
json\/wp\/v2\/media?parent=115"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}},
{"id":96,"date":"2020-11-09T02:48:51","date_gmt":"2020-11-09T02:48:51","guid":{"rendered":"http:\/\/127.0.0.1\/aaa\/?
post_type=jobs&#038;p=96"},"modified":"2020-11-09T05:23:30","modified_gmt":"2020-11-09T05:23:30","slug":"test-
job","status":"publish","type":"jobs","link":"http:\/\/127.0.0.1\/aaa\/jobs\/test-job\/","title":{"rendered":"Test 
Job"},"parent":0,"menu_order":0,"template":"","_links":{"self":[{"href":"http:\/\/127.0.0.1\/aaa\/wp-
json\/wp\/v2\/jobs\/96"}],"collection":[{"href":"http:\/\/127.0.0.1\/aaa\/wp-json\/wp\/v2\/jobs"}],"about":
[{"href":"http:\/\/127.0.0.1\/aaa\/wp-json\/wp\/v2\/types\/jobs"}],"wp:attachment":[{"href":"http:\/\/127.0.0.1\/aaa\/wp-
json\/wp\/v2\/media?parent=96"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}]

964Gettting HTML Content from index.html into Vue

Vue index.html:

  <body>
    <div id="app"></div>
    <!-- built files will be auto injected -->
    <div id="modalContent" style="display:none">
      <div id="modal1">
        Hello Modal Content Hello Modal Content
      </div>
    </div>
  </body>

Why add another hidden div to index.html? To be able to edit/add content without rebuilding and running npm run build.

In Vue:

  document.getElementById('modal1').innerHTML

Actually basic JS, nothing special to Vue.

963General JS Variables in Vue

Accesses JS from outside Vue:

index.html

...
<script>
  var test = "test";
</script>
...

In Vue:

  window.test

Obvious, but nevertheless

874CodeMirror – A Browser-based Text Editor

https://codemirror.net/

825Prototypal Inheritance and it’s Problem with Objects

Prototypal inheritance in Javascript is one of these features that sets it apart from other languages. A quick reminder:

var myDog = {};
myDog.legs = 4;
myDog.type = "Dachshund";
myDog.color = "brown";
myDog.says = "wau wau wau";

var yourDog = Object.create(myDog);
yourDog.says = "wan wan wan";

console.log(yourDog.type, yourDog.says);
> "Dachshund", "wau wau wau";

console.log(myDog.type, myDog.says);
> "Dachshund", "wan wan wan";

myDog is the prototype for yourDog, together they for a prototype chain. Any properties that would be added in myDog would also be accessible in yourDog. If yourDog adds a property with the same name (yourDog.says), this new property is returned when called. If a property is not defined, but present in the prototype, it will shine through.

So far so good.

Let's say we have an Array of dogs and we would like to prototypal inherit that whole array.

var myDogs = []
// fill array with dog objects

Following the pattern from above, the way to make a yourDogs array should be like that:

var yourDogs = Object.create(myDogs);

Let's update the first dog of the new yourDogs array to say something else:

yourDogs[0].says = "wow wow wow";

One would expect, that - because of the prototypal inheritance - that the changed value would only hide the original value. Let's check:

console.log(myDogs[0].says);
> "wow wow wow";

Ouch. The value was not as expected added to the prototypal branch only, but also to the original object. The prototype object and its chained offspring have the same object. Why is that? The answer is, that only variable types of Number, String, Boolean, etc are passed by value. Objects - and Arrays are objects - are passed by reference. (Check with typeof() to confirm the type of a variable.). That means the objects in our arrays are one and the same, and therefore any change in would will also occur in the other.

Seems logical, but still expectations are betrayed.

Let's consider the following case, this time without dogs. You have an array with objects and you want to apply a filter to some properties of the objects, which should be collected in another array. But - and this is crucial - you don't want the original array objects to change.

var original = [];
// add many, many objects

Because we saw before, that any changes in a new object would also reflect in the old one, we might be tempted to make a deep copy of the new one and then make our changes.

var copy = [];
$.extend(true, copy, original);     // Yes, that's jQuery
copy.map(function(element) {
    // make our changes to element
    //return element;
}

It's works, but it's rather kludgy. It takes quite a long time to make the deep copy and the prototypal chain breaks by doing that. Note also that the return of the map() function is not assigned to a new variable, and that the function does not need to return anything actually - because we are operating on the object directly.

A better solution would be this:

var better = copy.map(function(element) {
    var protoype = Object.create(element);  // create prototypal inheritance
    // make our changes to element
    return protoype;
}

better is now an array of objects which are prototypal linked to the original array. Any newly added properties will only be added to the new array - covering any properties which are already present in the original one.

console.log(original[0].dog.says);
> "wau wau wau"
console.log(better[0].dog.says);
> "wau wau wau"

better[0].dog.says = "wuff wuff wuff";

console.log(original[0].dog.says);
> "wau wau wau"
console.log(better[0].dog.says);
> "wuff wuff wuff"

That would I would have expected in the beginning. The nice things about Javascript is, that even when in works in unexpected ways, it's usually fairly trivial to align it again with your imagination. And sorry for bringing the dogs back.

819Single, Multiple Files and Javascript’s FileReader API

Getting a single file (with convenience jQuery event handler)

     
$('#open #chooseFile').change(function(e){
    var fileList = e.target.files;
    // get the one and only file
    var file = fileList[0];
    // further process file content...
    var reader = new FileReader();
    reader.readAsText(file, "text/plain");      
    reader.onload = localLoaded;
    reader.onerror = localError;
    // ...
});

Getting multiple files:

           

$('#open #chooseFile').change(function(e){
    var fileList = e.target.files;
    // loop over the files

    for (var i=0, file; file=fileList[i]; i++) {
        var reader = new FileReader();
        reader.readAsText(file, "text/plain");      
        reader.onload = localLoaded;
        reader.onerror = localError;
        // ...
    }
});

814Swapping Array Items in Javascript

var myArray = ["a", "c", "b"];
myArray.swap(1, 2);
console.log(myArray);
// ["a", "b", "c"];

Array.prototype.swap=function(a, b) {
    this[a]= this.splice(b, 1, this[a])[0];
    return this;
}

It could also be done with a temp var, but this solution seems to be the most elegant. The key to this is in the additional arguments the splice() function can accept.

splice(start, itemCount, additionalItems ...)

splice() removes elements denominated by the start and itemCount argument, and - if specified - inserts additional items at the same position.

Also important to note is that splice() returns an array. And to turn that array into an item again we need to select it directly with [0].