Rumah >hujung hadapan web >tutorial js >Struktur data dan algoritma dalam JavaScript (2): Queue_javascript kemahiran
Baris gilir ialah senarai linear yang hanya membenarkan operasi sisipan pada satu hujung dan operasi pemadaman di hujung satu lagi Barisan gilir ialah struktur data Mula-mula-Masuk-Dulu-Keluar (FIFO)
Baris gilir digunakan dengan kerap dalam reka bentuk program Oleh kerana JavaScript adalah satu utas, hanya satu tugasan boleh dilaksanakan pada bila-bila masa dan ia juga dicampur dengan mekanisme tak segerak
Masalahnya:1. Apabila operasi tak segerak dilaksanakan, kod segerak masih diteruskan, maka kod segerak bergantung kepada tak segerak dan ralat akan berlaku secara semula jadi
2. Berbilang tugasan disegerakkan dipanggil pada tempoh masa yang berbeza
Dalam animasi jQuery, kami sering menulis kod animasi berterusan
$book.animate({ opacity: 0.25, }).animate({ opacity: 0.5 }).animate({ opacity: 1 })
Perasaan intuitif yang kami ada ialah: selepas animasi pertama tamat, kelegapan elemen menjadi 0.25, dan kemudian animasi kedua mula dilaksanakan, dan kelegapan elemen menjadi 0.5, dan seterusnya. Tetapi sebenarnya, terdapat masalah penting di sini Animasi dipanggil secara tidak segerak, dan kaedah animasi dilaksanakan secara serentak, jadi baris gilir perlu direka di sini juga menyediakan kaedah baris gilir yang direka khas untuk animasi
Baris gilir juga merupakan senarai linear khas Dalam JavaScript, kita boleh terus menggunakan tatasusunan untuk melaksanakan reka bentuk sedemikian Kaedah push() tatasusunan boleh menambah elemen pada penghujung tatasusunan, dan kaedah shift() boleh memadamkan elemen pertama tatasusunan.
function Queue() { this.dataStore = []; this.enqueue = enqueue; this.dequeue = dequeue; this.first = first; this.end = end; this.toString = toString; this.empty = empty; } /////////////////////////// // enqueue()方法向队尾添加一个元素: // /////////////////////////// function enqueue(element) { this.dataStore.push(element); } ///////////////////////// // dequeue()方法删除队首的元素: // ///////////////////////// function dequeue() { return this.dataStore.shift(); } ///////////////////////// // 可以使用如下方法读取队首和队尾的元素: // ///////////////////////// function first() { return this.dataStore[0]; } function end() { return this.dataStore[this.dataStore.length - 1]; } ///////////////////////////// // toString()方法显示队列内的所有元素 // ///////////////////////////// function toString() { var retStr = ""; for (var i = 0; i < this.dataStore.length; ++i) { retStr += this.dataStore[i] + "\n"; } return retStr; } //////////////////////// // 需要一个方法判断队列是否为空 // //////////////////////// function empty() { if (this.dataStore.length == 0) { return true; } else { return false; } } var q = new Queue(); q.enqueue("Aaron1"); q.enqueue("Aaron2"); q.enqueue("Aaron3"); console.log("队列头: " + q.first()); //("Aaron1"); console.log("队列尾: " + q.end()); //("Aaron3");
Baris gilir menggunakan storan linear, jadi terdapat beberapa kelemahan storan berjujukan, seperti beratur untuk membeli tiket Jika yang pertama membelinya, yang berikut secara semula jadi akan bergerak ke hadapan dengan satu ruang, yang melibatkan keseluruhan baris gilir. Setiap ahli perlu bergerak ke hadapan, tetapi baris gilir JavaScript diterangkan oleh tatasusunan, dan lapisan bawah menyelesaikan beberapa kelemahan. Sudah tentu, terdapat juga isu dengan algoritma carian, seperti tatasusunan yang boleh digunakan untuk melaksanakan struktur senarai terpaut tunggal, dsb. Kami hanya membincangkan baris gilir JavaScript di sini
Simulasikan jQuery dan gunakan baris gilir untuk melaksanakan animasi
<div id="div1" style="width:100px;height:50px;background:red;cursor:pointer;color:#fff;text-align:center;line-height:50px;">点击</div> (function($) { window.$ = $; })(function() { var rquickExpr = /^(?:#([\w-]*))$/; function aQuery(selector) { return new aQuery.fn.init(selector); } /** * 动画 * @return {[type]} [description] */ var animation = function() { var self = {}; var Queue = []; //动画队列 var fireing = false //动画锁 var first = true; //通过add接口触发 var getStyle = function(obj, attr) { return obj.currentStyle ? obj.currentStyle[attr] : getComputedStyle(obj, false)[attr]; } var makeAnim = function(element, options, func) { var width = options.width //包装了具体的执行算法 //css3 //setTimeout element.style.webkitTransitionDuration = '2000ms'; element.style.webkitTransform = 'translate3d(' + width + 'px,0,0)'; //监听动画完结 element.addEventListener('webkitTransitionEnd', function() { func() }); } var _fire = function() { //加入动画正在触发 if (!fireing) { var onceRun = Queue.shift(); if (onceRun) { fireing = true; //next onceRun(function() { fireing = false; _fire(); }); } else { fireing = true; } } } return self = { //增加队列 add: function(element, options) { Queue.push(function(func) { makeAnim(element, options, func); }); //如果有一个队列立刻触发动画 if (first && Queue.length) { first = false; self.fire(); } }, //触发 fire: function() { _fire(); } } }(); aQuery.fn = aQuery.prototype = { run: function(options) { animation.add(this.element, options); return this; } } var init = aQuery.fn.init = function(selector) { var match = rquickExpr.exec(selector); var element = document.getElementById(match[1]) this.element = element; return this; } init.prototype = aQuery.fn; return aQuery; }()); //dom var oDiv = document.getElementById('div1'); //调用 oDiv.onclick = function() { $('#div1').run({ 'width': '500' }).run({ 'width': '300' }).run({ 'width': '1000' }); };
Ujian
<!doctype html><div id="div1" style="width:100px;height:50px;background:red;cursor:pointer;color:#fff;text-align:center;line-height:50px;" data-mce-style="width: 100px; height: 50px; background: red; cursor: pointer; color: #fff; text-align: center; line-height: 50px;">点击</div><script type="text/javascript"> (function($) { window.$ = $; })(function() { var rquickExpr = /^(?:#([\w-]*))$/; function aQuery(selector) { return new aQuery.fn.init(selector); } /** * 动画 * @return {[type]} [description] */ var animation = function() { var self = {}; var Queue = []; //动画队列 var fireing = false //动画锁 var first = true; //通过add接口触发 var getStyle = function(obj, attr) { return obj.currentStyle ? obj.currentStyle[attr] : getComputedStyle(obj, false)[attr]; } var makeAnim = function(element, options, func) { var width = options.width //包装了具体的执行算法 //css3 //setTimeout element.style.webkitTransitionDuration = '2000ms'; element.style.webkitTransform = 'translate3d(' + width + 'px,0,0)'; //监听动画完结 element.addEventListener('webkitTransitionEnd', function() { func() }); } var _fire = function() { //加入动画正在触发 if (!fireing) { var onceRun = Queue.shift(); if (onceRun) { fireing = true; //next onceRun(function() { fireing = false; _fire(); }); } else { fireing = true; } } } return self = { //增加队列 add: function(element, options) { Queue.push(function(func) { makeAnim(element, options, func); }); //如果有一个队列立刻触发动画 if (first && Queue.length) { first = false; self.fire(); } }, //触发 fire: function() { _fire(); } } }(); aQuery.fn = aQuery.prototype = { run: function(options) { animation.add(this.element, options); return this; } } var init = aQuery.fn.init = function(selector) { var match = rquickExpr.exec(selector); var element = document.getElementById(match[1]) this.element = element; return this; } init.prototype = aQuery.fn; return aQuery; }()); //dom var oDiv = document.getElementById('div1'); //调用 oDiv.onclick = function() { $('#div1').run({ 'width': '500' }).run({ 'width': '300' }).run({ 'width': '1000' }); }; </script>