task-demo2
HTML
<script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
<div id="content">
<div class="code-source"><span id="high1">function fn1() {}</span>
<span id="high4">function fn2() {</span>
<span id="high2">fn1();</span>
}
<span id="high5">function fn3() {</span>
<span id="high3">fn2();</span>
}</div>
<div class="tasks queue-wrapper">
<div id="task-title" class="queue-title">event queue</div>
<div id="task-content" class="queue-content"></div>
</div>
<div class="js-stack queue-wrapper">
<div id="stack-title" class="queue-title">JS stack</div>
<div id="stack-content" class="queue-content"></div>
</div>
<div class="log queue-wrapper">
<div id="log-title" class="queue-title">log</div>
<div id="log-content" class="queue-content"></div>
</div>
<div id="prev-btn">prev</div>
<div id="next-btn">next</div>
<div class="alert-window"></div>
</div>
CSS
* {
margin: 0;
padding: 0;
font-family: 'Microsoft Yahei';
}
#content {
position: relative;
width: 700px;
height: 400px;
margin: 0 auto;
border: 1px solid gray;
background-color: #e0e0e0;
}
.code-source {
position: relative;
width: 680px;
height: 230px;
background-color: #3b3b3b;
overflow: auto;
color: #ececec;
white-space: pre-wrap;
font-size: 16px;
padding: 0 10px;
}
.code-source p {}
.queue-wrapper {
position: relative;
width: 100%;
height: 40px;
border-top: 1px solid gray;
border-bottom: 1px solid gray;
font-size: 0;
}
.queue-title {
display: inline-block;
vertical-align: top;
width: 100px;
height: 100%;
padding: 0 5px;
background-color: #bdbdbd;
line-height: 40px;
color: #242424;
font-size: 16px;
}
.queue-content {
display: inline-block;
width: 580px;
height: 100%;
line-height: 40px;
padding: 0 5px;
background-color: #ececec;
vertical-align: top;
font-size: 16px;
font-size: 0;
}
.queue-item {
display: inline-block;
width: auto;
height: 35px;
padding: 0 4px;
margin: 0 2px;
background-color: #e0e05b;
vertical-align: middle;
font-size: 16px;
line-height: 35px;
color: #393939;
}
.queue-highlighted {
background-color: #ff5100;
}
span.selected {
background-color: #959595;
}
#next-btn {
position: absolute;
width: 50px;
height: 35px;
right: 10px;
bottom: 3px;
background-color: gray;
text-align: center;
line-height: 35px;
border: 1px solid #8d8d8d;
border-radius: 4px;
box-shadow: 1px 1px 4px 0px;
cursor: pointer;
-webkit-touch-callout: none;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
#prev-btn {
position: absolute;
width: 50px;
height: 35px;
left: 10px;
bottom: 3px;
background-color: gray;
text-align: center;
line-height: 35px;
border: 1px solid #8d8d8d;
border-radius: 4px;
box-shadow: 1px 1px 4px 0px;
cursor:...
JavaScript
'use strict';
(function() {
var taskContent = document.getElementById("task-content");
var microContent = document.getElementById("microtask-content");
var stackContent = document.getElementById("stack-content");
var logContent = document.getElementById("log-content");
var nextBtn = document.getElementById("next-btn");
var prevBtn = document.getElementById("prev-btn");
var $alert = $(".alert-window");
//语句高亮器
var mark = function(selector) {
$(".code-source span").removeClass('selected');
$(selector).addClass('selected');
location.hash = selector.substring(selector.lastIndexOf("#"), selector.length);
}
//事件循环器
var eventLoop = (function() {
var events = [];
var domBackups = [];
var eventBackups = [];
return {
push: function(event) {
events.push(event);
return this;
},
next: function() {
var event = events.shift();
if (!event) {
return;
}
var content = document.getElementById("content");
$(content).find('*').stop(false, true);
var temp = content.cloneNode(true);
domBackups.push(temp);
eventBackups.push(event);
event();
},
rollback: function() {
var temp = domBackups.pop();
if (!temp) {
return;
}
events = Array.from([eventBackups.pop()]).concat(events);
var content = document.getElementById("content");
document.body.insertBefore(temp, content);
document.body.removeChild(content);
taskContent = document.getElementById("task-content");
microContent = document.getElementById("microtask-content");
stackContent = document.getElementById("stack-content");
logContent = document.getElementById("log-content");
nextBtn = document.getElementById("next-btn");
prevBtn = document.getElementById("prev-btn");
$alert = $(".alert-window");
nextBtn.addEventListener("click", function(event) {
eventLoop.next();
}, false);
prevBtn.addEventListener("click", function(event) {
eventLoop.rollback();
},...