热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

jQuery源码dom操作之jQuery.fn.html

写在前面前面陆陆续续写了jQuery源码的一些分析,尽可能地想要cover里面的源码细节,结果导致进度有些缓慢。jQuery的源码本来就比较晦涩

写在前面

前面陆陆续续写了jQuery源码的一些分析,尽可能地想要cover里面的源码细节,结果导致进度有些缓慢。jQuery的源码本来就比较晦涩,里面还有很多为了解决兼容问题很引入的神代码,如果不google的话压根不知道那一段段代码为什么会存在于人世。

于是就一直在重复坐着这么件事情,到处谷歌或者请教别人,这段兼容代码是为解决神马问题引入的。好不容易把所有的源码细节搞清楚,喝着咖啡对着电脑欣赏自己的劳动成果,内心却闪过一丝奇怪的感觉:我花了这么长的时间究竟做了什么?就为了搞清楚这段常理无法解释的代码?而在这之前已经有无数仁人志士在这上面浪费了自己多少宝贵的时间。

当然,学习jQuery源码对于我这种老菜鸟还是很有助益的,只不过需要换种方式,不再去抠一些无谓的细节了,有些比较难理解的东西就直接扔出来看下园里的朋友们帮忙解答下了。社会化写作似乎是更好的方式,之前也想过把系列文章扔github让别人来帮忙完善,不过显然对于大部分人来说这种方式成本还是太高,而自己写的东西暂时也没有说让人家去fork然后pull request的价值,就作罢了。

技术无关的内容就此打住,还是老老实实开始我的源码分析。里面标疑惑的地方,是还没来得及去抠的细节(一般就是一些正则神马的),围观的群众如果能够帮忙解答下那是真真的好~~

简单例子

 jQuery.fn.html()同样属于使用频率比较高的接口,从它的接口文档http://api.jquery.com/html/,可知有如下几种用法,假设有如下HTML片段

<div id&#61;"casper"><span>name:span><span>casperspan>
div>

读取&#xff1a;$(selector).html()

运行下面代码

console.log( $(&#39;#casper&#39;).html() );

输出&#xff1a;

name:casper

设置一&#xff1a;$(selector).html(value)

还是上面的HTML&#xff0c;运行下面脚本

$(&#39;#casper&#39;).html(&#39;

大家好&#xff0c;我是第一段文本

大家好&#xff0c;我是第二段文本

&#39;);

原本的HTML变成

<div id&#61;"casper"><p>大家好&#xff0c;我是第一段文本p><p>大家好&#xff0c;我是第二段文本p>div>

设置二&#xff1a;$(selector).html(callback)

在上面例子中&#xff0c;HTML变成如下

<div id&#61;"casper"><p>大家好&#xff0c;我是第一段文本p><p>大家好&#xff0c;我是第二段文本p>div>

运行如下代码&#xff0c;参数 index、html 分别代码什么&#xff0c;见下面输出即可&#xff0c;不赘述

$(&#39;#casper p&#39;).html(function(index, html){return index &#43; &#39;、原本的内容&#xff1a;&#39;&#43; html;
});

结果原来的HTML变成&#xff08;为方便查看进行了适当格式化&#xff09;

<div id&#61;"casper"><p>0、原本的内容&#xff1a;大家好&#xff0c;我是第一段文本p><p>1、原本的内容&#xff1a;大家好&#xff0c;我是第二段文本p>
div>

源码分析

下面湿jQuery.fn.html 的源码&#xff0c;就直接贴上来了&#xff0c;一点都不意外&#xff0c;又见到了全知全能的jQuery.access方法。。。这里我们先不立即展开&#xff0c;下文慢慢分析

 jQuery.fn.html源码

把传入jQuery.access的会掉方法的方法体去掉&#xff0c;我们看到如下代码&#xff0c;就是调用了下jQuery.access而已&#xff08;这里我们还不知道jQuery.access那噩梦般的参数究竟是干嘛的&#xff09;&#xff1a;

html: function( value ) {return jQuery.access( this, function( value ) {// 先隐藏掉方法体内的细节
}, null, value, arguments.length );
},

实在不知道如何下手分析jQuery.access&#xff0c;就直接跳过jQuery.access运行的内部细节&#xff0c;给出各种情况下的运行分支

源码分析之&#xff1a;fn被调用的各种情况

假设在jQuery.fn.html方法中&#xff0c;第二个传入的回调方法为fn

读取&#xff1a;$(selector).html()

html: function( value ) {return fn.call(this);
},

设置一&#xff1a;$(selector).html(value)

html: function( value ) {fn.call( this, value );return this;
},

设置二&#xff1a;$(selector).html(callback)

这里可能比较费解一点&#xff0c;得结合设置一的代码来看&#xff08;其实结合了业不容易看懂&#xff09;&#xff0c;可以看到&#xff0c;内部比较曲折&#xff0c;最终将$(selector).html(callback)转成了$(selector).html(value)来实现&#xff0c;这种转换手法在jQuery源码里很常见。

html: function( callback ) {var elems &#61; this,i &#61; 0,length &#61; elems.length;var bulk &#61; fn;// elem为dom元素&#xff0c;value为该dom元素最初的innerHTMLfn &#61; function( elem, value ) {return bulk.call( jQuery( elem ), value );};for ( ; i ) {// 第一步&#xff1a;fn( elems[i], key ) ) 返回elem[i]的innerHTML&#xff0c;相当于 $(elem[i]).html()// 第二步&#xff1a;callback.call( elems[i], i, fn( elems[i], key ) )&#xff0c;就是将 i、$(elem[i]).html()当参数传给 callback// 第三步&#xff1a;fn( elems[i], XXXX ) 到了这一步&#xff0c;其实就是 $(elem[i]).html(value)的等价形式了&#xff0c;因为第三步中已经返回了一段html文本
fn( elems[i], callback.call( elems[i], i, fn( elems[i], key ) ) );}return this;
}

源码分析之&#xff1a;fn各种情况下内部的分支逻辑

接下来到大头&#xff0c;上面说的fn的源码了&#xff0c;下面列出各种情况下&#xff0c;fn内部的处理逻辑

读取&#xff1a;$(selector).html()

fn里面的处理逻辑&#xff0c;很简单&#xff0c;将$(selector)选中的第一个dom元素的innerHTML属性返回。

疑问&#xff1a;rinlinejQuery这个正则是干嘛&#xff1f;为什么还要将elem.innerHTML先替换一下再返回&#xff1f;

var elem &#61; this[0] || {}, // this为选中的jQuery对象i &#61; 0,l &#61; this.length;if ( value &#61;&#61;&#61; undefined ) {return elem.nodeType &#61;&#61;&#61; 1 ?elem.innerHTML.replace( rinlinejQuery, "" ) :undefined;
}

设置一&#xff1a;$(selector).html(value)

代码也不算复杂&#xff0c;就是遍历下$(selector)选中的元素&#xff0c;将它们的innerHTML分别设置成value。这里麻烦点在于&#xff0c;value存在&#xff0c;还得符合一堆条件才能走进这个if&#xff0c;原谅我偷懒了

疑问&#xff1a;

!rnoInnerhtml.test( value )&#xff1a;判断神马的

( jQuery.support.htmlSerialize || !rnoshimcache.test( value ) )&#xff1a;判断神马的

( jQuery.support.leadingWhitespace || !rleadingWhitespace.test( value ) )&#xff1a;判断神马的

!wrapMap[ ( rtagName.exec( value ) || ["", ""] )[1].toLowerCase() ]&#xff1a;判断神马的

value &#61; value.replace( rxhtmlTag, "<$1>" ); 作用是神马

// See if we can take a shortcut and just use innerHTML
if ( typeof value &#61;&#61;&#61; "string" && !rnoInnerhtml.test( value ) &&( jQuery.support.htmlSerialize || !rnoshimcache.test( value ) ) &&( jQuery.support.leadingWhitespace || !rleadingWhitespace.test( value ) ) &&!wrapMap[ ( rtagName.exec( value ) || ["", ""] )[1].toLowerCase() ] ) {value &#61; value.replace( rxhtmlTag, "<$1>" );try {for (; i ) {// Remove element nodes and prevent memory leakselem &#61; this[i] || {};if ( elem.nodeType &#61;&#61;&#61; 1 ) {jQuery.cleanData( getAll( elem, false ) );elem.innerHTML &#61; value;}}elem &#61; 0;// If using innerHTML throws an exception, use the fallback method} catch(e) {}
}

设置二&#xff1a;$(selector).html(callback)

 这里直接略过&#xff0c;因为fn内部的逻辑是跟$(selector).html(value)一样的

写在后面

本文有些偷懒&#xff0c;凑合着看吧。。里面提到的疑惑&#xff0c;如果能够帮忙解答下就更好了。。。





推荐阅读
  • 事件是程序各部分之间的一种通信方式,也是异步编程的一种实现形式。本文将详细介绍EventTarget接口及其相关方法,以及如何使用监听函数处理事件。 ... [详细]
  • Web开发框架概览:Java与JavaScript技术及框架综述
    Web开发涉及服务器端和客户端的协同工作。在服务器端,Java是一种优秀的编程语言,适用于构建各种功能模块,如通过Servlet实现特定服务。客户端则主要依赖HTML进行内容展示,同时借助JavaScript增强交互性和动态效果。此外,现代Web开发还广泛使用各种框架和库,如Spring Boot、React和Vue.js,以提高开发效率和应用性能。 ... [详细]
  • .children() 方法用于获取选中元素的所有直接子元素。此方法仅遍历DOM树的一层,如需遍历多层子元素,请使用 .find() 方法。 ... [详细]
  • 周排行与月排行榜开发总结
    本文详细介绍了如何在PHP中实现周排行和月排行榜的开发,包括数据库设计、数据记录和查询方法。涉及的知识点包括MySQL的GROUP BY、WEEK和MONTH函数。 ... [详细]
  • Cookie学习小结
    Cookie学习小结 ... [详细]
  • 在HTML布局中,即使将 `top: 0%` 和 `left: 0%` 设置为元素的定位属性,浏览器中仍然会出现空白填充。这个问题通常与默认的浏览器样式、盒模型或父元素的定位方式有关。为了消除这些空白,可以考虑重置浏览器的默认样式,确保父元素的定位方式正确,并检查是否有其他CSS规则影响了元素的位置。 ... [详细]
  • 在分析和解决 Keepalived VIP 漂移故障的过程中,我们发现主备节点配置如下:主节点 IP 为 172.16.30.31,备份节点 IP 为 172.16.30.32,虚拟 IP 为 172.16.30.10。故障表现为监控系统显示 Keepalived 主节点状态异常,导致 VIP 漂移到备份节点。通过详细检查配置文件和日志,我们发现主节点上的 Keepalived 进程未能正常运行,最终通过优化配置和重启服务解决了该问题。此外,我们还增加了健康检查机制,以提高系统的稳定性和可靠性。 ... [详细]
  • centos 7.0 lnmp成功安装过程(很乱)
    下载nginx[rootlocalhostsrc]#wgethttp:nginx.orgdownloadnginx-1.7.9.tar.gz--2015-01-2412:55:2 ... [详细]
  • PHP-Casbin v3.20.0 已经发布,这是一个使用 PHP 语言开发的轻量级开源访问控制框架,支持多种访问控制模型,包括 ACL、RBAC 和 ABAC。新版本在性能上有了显著的提升。 ... [详细]
  • h5调用本地摄像头和麦克风一
    h5调用本地摄像头和麦克风一,Go语言社区,Golang程序员人脉社 ... [详细]
  • 【线段树】  本质是二叉树,每个节点表示一个区间[L,R],设m(R-L+1)2(该处结果向下取整)左孩子区间为[L,m],右孩子区间为[m ... [详细]
  • 本文详细介绍了 Java 网站开发的相关资源和步骤,包括常用网站、开发环境和框架选择。 ... [详细]
  • 本文介绍了如何使用Python爬取妙笔阁小说网仙侠系列中所有小说的信息,并将其保存为TXT和CSV格式。主要内容包括如何构造请求头以避免被网站封禁,以及如何利用XPath解析HTML并提取所需信息。 ... [详细]
  • 本文详细探讨了使用Python3编写爬虫时如何应对网站的反爬虫机制,通过实例讲解了如何模拟浏览器访问,帮助读者更好地理解和应用相关技术。 ... [详细]
  • 在iOS开发中,基于HTTPS协议的安全网络请求实现至关重要。HTTPS(全称:HyperText Transfer Protocol over Secure Socket Layer)是一种旨在提供安全通信的HTTP扩展,通过SSL/TLS加密技术确保数据传输的安全性和隐私性。本文将详细介绍如何在iOS应用中实现安全的HTTPS网络请求,包括证书验证、SSL握手过程以及常见安全问题的解决方法。 ... [详细]
author-avatar
手机用户2502921281_649
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有