microtask-demo1

HTML

<script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
<div id="content">
    		<div class="code-source"><span id="1st">console.log(' start');</span>

<span id="2st">setTimeout(function() {</span>
<span id="3st">	console.log('setTimeout');</span>
}, 0);

<span id="4st">Promise.resolve().then(function() {</span>
<span id="5st">	console.log('promise1');</span>
}).then(function() {
<span id="6st"> 	console.log('promise2');</span>
});

<span id="7st">console.log('script end');</span></div>
    		<div class="tasks queue-wrapper">
    			<div id="task-title" class="queue-title">tasks</div>
    			<div id="task-content" class="queue-content"></div>
    		</div>
    		<div class="microtask queue-wrapper">
    			<div id="microtask-title" class="queue-title">microtasks</div>
    			<div id="microtask-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: 500px;
  margin: 0 auto;
  border: 1px solid gray;
  background-color: #e0e0e0;
}

.code-source {
  position: relative;
  width: 680px;
  height: 290px;
  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: 90px;
  height: 100%;
  padding: 0 5px;
  background-color: #bdbdbd;
  line-height: 40px;
  color: #242424;
  font-size: 16px;
}

.queue-content {
  display: inline-block;
  width: 590px;
  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

(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');
	}
	//语句高亮器
	var target = 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);
			},
			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();
				},...