网站首页  汉语字词  英语词汇  考试资料  写作素材  旧版资料

请输入您要查询的考试资料:

 

标题 jQuery链式调用与show知识浅析
内容
    这篇文章主要介绍了jQuery的XX如何实现?——2.show与链式调用 的相关资料,非常具有参考借鉴价值,感兴趣的朋友一起学习吧
    jQuery使用许久了,但是有一些API的实现实在想不通。下面将使用简化的代码来介绍,主要关注jQuery的实现思想。
    相较于上一篇,代码更新了:21~78
    (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);
    先拿hide函数热身一下。如上篇提到的,jQuery会将获取到的nodeList处理成数组,所以一上来,我们用forEach处理数组里的每一个node节点。
    接下来,我们只需要将每一个节点的style.display置为'none'即可隐藏。很简单,对吧?(⊙0⊙) 。oldDisplay和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;
    }
    其中isHidden是判断该元素是否隐藏:已经隐藏的元素就没必要再去处理了,直接跳过
    function isHidden(node) {
    //忽略未append进document的元素这种隐藏情况:$('<div>block</div>')未append
    return window.getComputedStyle(node, null).getPropertyValue('display') === 'none';
    }
    --------------------------
    接下来,来个稍繁琐的show。先抛出一个问题来引发一系列问题:
    hide某个元素只需要将display:none,那么show呢?
    display:block不就行了吗?这样确实可以将元素显示出来。但是万一元素原来的值是display:inline呢?
    那在hide处保存原来的值不就行了吗?就像以下的代码:
    node.oldDisplay = getDisplay(node);
    要是执行show前没有不执行hide呢?比如下面这种情况,不就没有oldDisplay了吗(⊙0⊙)
    <style>
    div{ display:none; }
    </style>
    <div>display:none</div>$('div').show()
    好,关键的地方到了:我们获取元素display的默认值就可以了吧?比如div默认是block,span默认是inline。
    思路有了,那么接下来的问题是:如何获取元素display的默认值?
    嘿嘿嘿,想不到吧?这里需要用点小技巧,大体思路如下:通过nodeName创建一个新的标签,再获取。
    有个地方可以再优化一下,getDisplay获取到元素display默认值后,可以使用jQuery的cache机制存起来(实际上jQuery也是这么做了)。
    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);
    以为这样就结束了?NO,show函数的情况还是挺复杂的,我们大致要应对这几种情况:
    <style>
    #none,#none2{ display: none; }
    </style>
    <body>
    <div id="div">默认值为block</div>
    <span id="span">默认值为inline</span>
    <div id="div2">修改为inline-block</div>
    <div id="none">通过css隐藏了</div>
    <div id="none2">通过css和style隐藏了</div>
    </body>
    最终,show函数变成了这鬼样ψ(╰_╯)。大致思路如下:
    名单
    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);
    }
    })
    }
    --------------------------
    链式调用就是类似这种情况:
    $('div').show().hide().css('height','300px').toggle()
    实现起来非常简单,只要在每个函数后面return this即可
    --------------------------
    有同学说:喂!这个show,hide不对吧?是不是漏了时间参数? 用setTimeOut自己实现吧~>_<~+。
    本节最主要是让大家知道jQuery需要考虑的情况非常多(很多脏活)。即时简化了代码,依然还是这么长。
    写完后,发现show还有一种情况没考虑:
    div{ display:none !important; }
    <div>大家自己开脑洞,怎么处理吧(⊙0⊙)</div>
随便看

 

在线学习网考试资料包含高考、自考、专升本考试、人事考试、公务员考试、大学生村官考试、特岗教师招聘考试、事业单位招聘考试、企业人才招聘、银行招聘、教师招聘、农村信用社招聘、各类资格证书考试等各类考试资料。

 

Copyright © 2002-2024 cuapp.net All Rights Reserved
更新时间:2025/5/18 20:18:28