Rumah  >  Artikel  >  hujung hadapan web  >  Perbincangan ringkas tentang pengetahuan berkaitan rancangan dan panggilan berantai dalam jQuery

Perbincangan ringkas tentang pengetahuan berkaitan rancangan dan panggilan berantai dalam jQuery

PHPz
PHPzke hadapan
2016-05-16 08:59:583602semak imbas

Dalam artikel ini, mari belajar tentang rancangan dan panggilan berantai dalam jQuery. Ia mempunyai nilai rujukan tertentu Rakan-rakan yang memerlukan boleh merujuk kepadanya.

Perbincangan ringkas tentang pengetahuan berkaitan rancangan dan panggilan berantai dalam jQuery

jQuery telah digunakan sejak sekian lama, tetapi pelaksanaan beberapa API sememangnya sukar untuk diketahui. Perkara berikut akan diperkenalkan menggunakan kod yang dipermudahkan, memfokuskan terutamanya pada idea pelaksanaan jQuery.

(function(window, undefined){
function jQuery(sel){
return new jQuery.prototype.init(sel);
}
jQuery.prototype = {
constructor: jQuery,
init: function(sel){
if(typeof sel === 'string'){
var that = this;
var nodeList = document.querySelectorAll(sel);
Array.prototype.forEach.call(nodeList, function(val, i){
that[i] = val;
})
this.selector = sel;
this.length = nodeList.length;
}
},
show: function(){
Array.prototype.forEach.call(this, function(node){
//if(node.style) continue; //textnode没有style
//删除style上的display:none
var display = node.style.display;
if(display === 'none'){
//dispaly置为空后,css如果有display则css的生效
//否则默认的生效
node.style.display = '';
}
//元素display值为非默认值情况,需要还原为oldDisplay:div->display:inline-block
//或 检测css上的display是否为none
if(node.style.display==='' || isHidden(node)){
//有oldDispaly则设置
if(node.oldDisplay) node.style.display = node.oldDisplay;
//没有则设置为元素默认值或元素当前值
else node.style.display = getDisplay(node);
}
})
//链式调用
return this;
},
hide: function(){
Array.prototype.forEach.call(this, function(node){
if(!isHidden(node)) {
//jQuery使用其cache机制存储信息,这里简化一下
//直接挂载在对应的dom下
node.oldDisplay = getDisplay(node);
node.style.display = 'none';
}
})
return this;
}
}
function getDisplay(node){
var display = window.getComputedStyle(node, null).getPropertyValue('display');
if(display === 'none'){
var dom = document.createElement(node.nodeName);
//插入到body中
document.body.appendChild(dom);
//即可获取到元素display的默认值
var display = window.getComputedStyle(dom, null).getPropertyValue('display');
document.body.removeChild(dom);
}
return display;
}
function isHidden(node) {
//忽略未append进document的元素这种隐藏情况:$(&#39;<div>block</div>&#39;)未append
return window.getComputedStyle(node, null).getPropertyValue(&#39;display&#39;) === &#39;none&#39;;
}
jQuery.prototype.init.prototype = jQuery.prototype;
window.$ = jQuery;
})(window);

Mula-mula memanaskan badan dengan fungsi sembunyikan. Seperti yang dinyatakan dalam artikel sebelumnya, jQuery akan memproses nodeList yang diperoleh ke dalam tatasusunan, jadi pertama, kami menggunakan forEach untuk memproses setiap nod dalam tatasusunan.

Seterusnya, kita hanya perlu menetapkan gaya.paparan setiap nod kepada 'tiada' untuk menyembunyikannya. Cukup mudah, bukan? (⊙0⊙) . Abaikan oldDisplay dan kembalikan ini buat masa ini.( ̄▽ ̄) gaya

hide: function(){
Array.prototype.forEach.call(this, function(node){
if(!isHidden(node)) {
//jQuery使用其cache机制存储信息,这里简化一下
//直接挂载在对应的dom下
node.oldDisplay = getDisplay(node);
node.style.display = &#39;none&#39;;
}
})
return this;
}

di mana isHidden digunakan untuk menentukan sama ada elemen itu tersembunyi: tidak perlu memproses elemen yang sudah tersembunyi, langkau

function isHidden(node) {
//忽略未append进document的元素这种隐藏情况:$(&#39;<div>block</div>&#39;)未append
return window.getComputedStyle(node, null).getPropertyValue(&#39;display&#39;) === &#39;none&#39;;
}

-------------------------

Seterusnya, mari kita bersusah payah sedikit tunjuk. Mula-mula bangkitkan soalan untuk mencetuskan satu siri soalan:

sembunyikan elemen tertentu hanya memerlukan paparan:tiada, tetapi bagaimana pula dengan rancangan?

Adakah paparan:sekat tidak mencukupi? Ini sememangnya akan menunjukkan elemen. Tetapi bagaimana jika nilai asal elemen ialah display:inline?

Adakah cukup untuk menyimpan nilai asal di tempat sembunyi? Sama seperti kod berikut:

node.oldDisplay = getDisplay(node);

Bagaimana jika hide tidak dilaksanakan sebelum persembahan dilaksanakan? Sebagai contoh, dalam situasi berikut, bukankah tiada Paparan lama (⊙0⊙)

<style>
div{ display:none; }
</style>
<div>display:none</div>$(&#39;div&#39;).show()

Baiklah, perkara utama adalah di sini: kita hanya boleh mendapatkan nilai lalai paparan elemen, betul tak? Sebagai contoh, p lalai untuk menyekat dan menjangkau lalai kepada sebaris.

Sekarang kita mempunyai idea, soalan seterusnya ialah: Bagaimana untuk mendapatkan nilai lalai paparan elemen?

Hehehehe, tak boleh fikir ke? Helah kecil diperlukan di sini, idea umum adalah seperti berikut: buat label baharu melalui nodeName, dan kemudian dapatkannya.

Terdapat tempat yang boleh dioptimumkan lagi Selepas getDisplay memperoleh nilai paparan lalai elemen, ia boleh disimpan menggunakan mekanisme cache jQuery (sebenarnya, jQuery juga melakukan ini).

function getDisplay(node){
var display = window.getComputedStyle(node, null).getPropertyValue(&#39;display&#39;);
if(display === &#39;none&#39;){
var dom = document.createElement(node.nodeName);
//插入到body中
document.body.appendChild(dom);
//即可获取到元素display的默认值
var display = window.getComputedStyle(dom, null).getPropertyValue(&#39;display&#39;);
document.body.removeChild(dom);
}
return display;
}

Kemudian, menggabungkan dua situasi ini:

//有oldDispaly则设置
if(node.oldDisplay) node.style.display = node.oldDisplay;
//没有则设置为元素默认值或元素当前值
else node.style.display = getDisplay(node);

Fikirkan ini adalah penghujungnya? TIDAK, situasi fungsi persembahan agak rumit Kami biasanya perlu menangani situasi ini:

<style>
#none,#none2{ display: none; }
</style>
<body>
<div id="div">默认值为block</div>
<span id="span">默认值为inline</span>
<div id="div2" style="display:inline-block;">修改为inline-block</div>
<div id="none">通过css隐藏了</div>
<div id="none2" style="display:none">通过css和style隐藏了</div>
</body>

Akhirnya, fungsi persembahan bertukar menjadi ψ(╰_╯) yang pelik ini. Idea umum adalah seperti berikut:

Perbincangan ringkas tentang pengetahuan berkaitan rancangan dan panggilan berantai dalam jQuery

show: function(){
Array.prototype.forEach.call(this, function(node){
//if(node.style) continue; //textnode没有style
//删除style上的display:none
var display = node.style.display;
if(display === &#39;none&#39;){
//dispaly置为空后,css如果有display则css的生效
//否则默认的生效
node.style.display = &#39;&#39;;
}
//元素display值为非默认值情况,需要还原为oldDisplay:div->display:inline-block
//或 检测css上的display是否为none
if(node.style.display===&#39;&#39; || isHidden(node)){
//有oldDispaly则设置
if(node.oldDisplay) node.style.display = node.oldDisplay;
//没有则设置为元素默认值或当前值
else node.style.display = getDisplay(node);
}
})
}

---------------------- -- -

Panggilan rantai adalah serupa dengan situasi ini:

$(&#39;div&#39;).show().hide().css(&#39;height&#39;,&#39;300px&#39;).toggle()

sangat mudah untuk dilaksanakan, selagi setiap fungsi Hanya kembalikan ini kemudian

-------------------------

Ya Rakan sekelas berkata: Hello! Bukankah ini menunjukkan dan bersembunyi betul? Adakah saya terlepas parameter masa? Gunakan setTimeOut untuk melaksanakannya sendiri~>_

Tujuan utama bahagian ini adalah untuk memberitahu semua orang bahawa terdapat banyak situasi yang perlu dipertimbangkan oleh jQuery (banyak kerja kotor). Walaupun kod itu dipermudahkan, ia masih begitu panjang.

Setelah selesai menulis, saya dapati terdapat satu lagi situasi yang menunjukkan tidak dipertimbangkan:

div{ display:none !important; }
<div>大家自己开脑洞,怎么处理吧(⊙0⊙)</div>

Tutorial video berkaitan yang disyorkan: Tutorial jQuery (Video )

Kenyataan:
Artikel ini dikembalikan pada:jb51.net. Jika ada pelanggaran, sila hubungi admin@php.cn Padam