이번 글에서는 jQuery의 show 및 chain call에 대해 알아보겠습니다. 도움이 필요한 친구들이 모두 참고할 수 있기를 바랍니다.
jQuery는 오랫동안 사용되어 왔지만 일부 API의 구현은 정말 파악하기 어렵습니다. 다음은 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的元素这种隐藏情况:$('<div>block</div>')未append return window.getComputedStyle(node, null).getPropertyValue('display') === 'none'; } jQuery.prototype.init.prototype = jQuery.prototype; window.$ = jQuery; })(window);
먼저 숨기기 기능으로 몸을 풀어보세요. 이전 글에서 언급했듯이 jQuery는 획득한 nodeList를 배열로 처리하므로 먼저 forEach를 사용하여 배열의 각 노드를 처리합니다.
다음으로, 숨기려면 각 노드의 style.display를 'none'으로 설정하면 됩니다. 아주 간단하죠? ( ⊙0 ) . oldDisplay를 무시하고 지금은 이것을 반환하세요╰( ̄▽ ̄)╮
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; }
여기서 isHidden은 요소가 숨겨져 있는지 확인하는 데 사용됩니다. 이미 숨겨진 요소를 처리할 필요가 없습니다. <를 건너뛰기만 하면 됩니다. 🎜>
function isHidden(node) { //忽略未append进document的元素这种隐藏情况:$('<div>block</div>')未append return window.getComputedStyle(node, null).getPropertyValue('display') === 'none'; }
node.oldDisplay = getDisplay(node);
<style> div{ display:none; } </style> <div>display:none</div>$('div').show()
요소 표시의 기본값을 얻는 방법입니다.
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; }
//有oldDispaly则设置 if(node.oldDisplay) node.style.display = node.oldDisplay; //没有则设置为元素默认值或元素当前值 else node.style.display = getDisplay(node);
<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>
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); } }) }
Chain call은 이 상황과 유사합니다.
$('div').show().hide().css('height','300px').toggle()
div{ display:none !important; } <div>大家自己开脑洞,怎么处理吧(⊙0⊙)</div>
jQuery Tutorial (비디오 )