-
Notifications
You must be signed in to change notification settings - Fork 0
Slow Operations
4thex edited this page Dec 3, 2014
·
7 revisions
Using the
ProgressEventinterface and the HTML5progresselement.
index.html
<!DOCTYPE html>
<html>
<head>
<title>Progress</title>
<link rel="stylesheet" href="styles.css">
<script src="deck.js"></script>
<script src="shuffler.js"></script>
<script src="progress.js"></script>
<script src="main.js"></script>
</head>
<body>
<div id="result">0</div>
<form>
<input id="shuffle" type="button" value="Shuffle" />
</form>
</body>
</html>deck.js
// Namespace
if(!NSMscsbend) {
var NSMscsbend = {};
}
NSMscsbend.deck = function(spec) {
var that = {
sequence: [
"AS", "2S", "3S", "4S", "5S", "6S", "7S", "8S", "9S", "10S", "JS", "QS", "KS",
"AH", "2H", "3H", "4H", "5H", "6H", "7H", "8H", "9H", "10H", "JH", "QH", "KH",
"AD", "2D", "3D", "4D", "5D", "6D", "7D", "8D", "9D", "10D", "JD", "QD", "KD",
"AC", "2C", "3C", "4C", "5C", "6C", "7C", "8C", "9C", "10C", "JC", "QC", "KC",
]
};
return that;
};shuffler.js
// Namespace
if(!NSMscsbend) {
var NSMscsbend = {};
}
NSMscsbend.shuffler = function(spec) {
var that = {
spec: spec
};
var state = {
running: false,
totalExecuted: 0,
swapIndex: 0,
sequence: spec.sequence
};
var steps = spec.swaps * 10;
var pick = function() {
var result = Math.floor(Math.random() * state.sequence.length);
return result;
};
var report = function(executed) {
state.totalExecuted += executed;
if(!(state.totalExecuted % Math.floor(steps/1000))) {
var event = new ProgressEvent("progress",
{
lengthComputable: true,
loaded: state.totalExecuted,
total: steps
});
that.onprogress(event);
return true;
}
return false;
};
that.execute = function() {
state.running = true;
while(state.swapIndex < spec.swaps) {
var firstIndex = pick(state.sequence.length);
var secondIndex = pick(state.sequence.length);
var first = state.sequence[firstIndex];
var second = state.sequence[secondIndex];
state.sequence[firstIndex] = second;
state.sequence[secondIndex] = first;
state.swapIndex++;
if(report(10)) {
state.timer = window.setTimeout(that.execute, 0);
return;
}
}
state.running = false;
state.swapIndex = 0;
state.totalExecuted = 0;
that.spec.complete(state.sequence);
};
that.cancel = function() {
if(!state.running) return;
state.running = false;
state.swapIndex = 0;
state.totalExecuted = 0;
if(state.timer) {
window.clearTimeout(state.timer);
}
};
var listeners = [];
that.addEventListener = function(type, listener) {
listeners.push({type: type, listener: listener});
};
that.removeEventListener = function(type, listener) {
var remaining = listeners.filter(function(element) {
return element.type === type && element.listener === listener;
});
return remaining;
};
that.onprogress = function(event) {
listeners.forEach(function(element, index, array) {
if(element.type === "progress") {
element.listener(event);
}
});
};
return that;
};progress.js
// Namespace
if(!NSMscsbend) {
var NSMscsbend = {};
}
NSMscsbend.progressBar = function(spec) {
var that = {};
var cleanup = function() {
container.remove();
spec.element.disabled = false;
};
spec.element.disabled = true;
var container = document.createElement("div");
container.style.width = "100%";
var bar = document.createElement("progress");
bar.style.width = "100%";
container.appendChild(bar);
var button = document.createElement("input");
button.style.width = "8em";
button.setAttribute("type", "button");
button.setAttribute("value", "Cancel");
button.addEventListener("click", function(event) {
cleanup();
oncancel();
});
container.appendChild(button);
var sibling;
if(sibling = spec.element.nextElementSibling) {
document.insertBefore(container, sibling);
} else {
spec.element.parentNode.appendChild(container);
}
that.onprogress = function(event) {
bar.setAttribute("value", event.loaded);
bar.setAttribute("max", event.total);
if(event.loaded === event.total) {
cleanup();
}
};
var oncancel = function() {
if(spec.cancel) {
spec.cancel();
}
};
return that;
};main.js
(function(){
window.addEventListener("load", function(event) {
var button = document.querySelector("#shuffle");
var resultElement = document.querySelector("#result");
var deck = NSMscsbend.deck();
button.addEventListener("click", function(event) {
var argument = {
sequence: deck.sequence,
swaps: 100000,
complete: function(sequence) {
resultElement.innerText = sequence.join();
}
};
var shuffler = NSMscsbend.shuffler(argument);
var progressBar = NSMscsbend.progressBar({
element: button,
cancel: shuffler.cancel
});
shuffler.addEventListener("progress", progressBar.onprogress);
shuffler.execute();
});
});
}());Introduction
[Install CDE](Install CDE)
[A Ringing Bell](A Ringing Bell)
[Projectile Movement](Projectile Movement)
[Map with location](Map with location)
[Slide 15 Puzzle](Slide 15 Puzzle)
[A Running Man](A Running Man)
Sudoku
[Package Chrome Application](Package Chrome Application)
[Uploading Your Application](Uploading Your Application)