JSFiddle - React, Tailwind, and code Playground
HTML
<script src="http://ajax.aspnetcdn.com/ajax/knockout/knockout-3.0.0.js"></script>
<div data-bind="template: {afterRender: hide}">
<div data-bind="html: html"></div>
</div>
<div id="spinner" style="display: none">Loading...</div>
<button onclick="go()">Go!</button>
CSS
#spinner {
position: absolute;
top: 20px;
left: 20px;
background-color: white;
border: 1px solid green;
}
JavaScript
// Use a non-observable array to build the 3000 items
plain_items = [];
// Build 3000 items, which is enough to make my Macbook Air block for 3 seconds to render
// the simple template above.
for (var i = 0; i <= 5000; i++) {
plain_items.push(i)
}
// Put the items in a VM
list = function() {
this.items = ko.observableArray()
this.html = ko.computed(function() {
var html = "", i = 0, item
for (i = 0; i < this.items().length; i++) {
var item = this.items()[i];
html = html + "<div>" + item + "</div>"
}
return html;
}, this)
}
vm = new list()
// Trigger the rendering from a button click
go = function() {
// Show the spinner immediately...
$("#spinner").show();
// ... by using a timeout.
window.setTimeout(function() {
ko.applyBindings(vm)
vm.items(plain_items)
}, 1)
}
// Hide the spinner by applying this function to a template: {afterRender: ...} binding
hide = function() {
$("#spinner").hide()
}