【笔记】jQuery源码(文档处理)
发布日期:2021-06-24 18:23:37 浏览次数:2 分类:技术文章

本文共 3034 字,大约阅读时间需要 10 分钟。

前言

内容主要是跟着慕课网上的jQuery源码解析系列课程以及自己的实践+理解来写的,可能会有错误,欢迎指出^_^。

以往笔记:
【笔记】jQuery源码(第一天):

第二天:文档处理

这里相关的方法主要有:

jQuery.fn.extend({      text: function() {},      append: function() {},      prepend: function() {},      before: function() {},      after: function() {},      clone: function() {},      html: function() {},        replaceWith: function() {},       domManip: function() {},  })

domManip方法

我们在使用appendChild()等方法添加内容的时候,必须是元素类型。但是在jQuery里面我们可以传入字符串来添加内容,还有添加script等操作。domManip方法就是一个处理中间过渡的函数。

所以针对所有接口的操作,jQuery会抽象出一种参数的处理方案,domManip方法主要做的事情如下:
1:解析参数,字符串,函数,对象。
2:针对大数据引入文档碎片处理。
3:如果参数中包含script的处理。

以及一些细节问题:

IE下面innerHTML会忽略没作用域元素,no-scope element(script,link,style,meta,noscript)等,所以这类通过innerHTML创建需要加前缀。
innerHTML在IE下面会对字符串进行trimLeft操作,去掉空白。
innerHTML不会执行脚本的代码,如果支持defer除外。
很多标签不能作为div的子元素、td、tr, tbody等等 jQuery是合集对象,文档碎片的与事件的复制问题。

模拟简单的append()

function buildFragment(elems, context) {    //创建Document的文档碎片    var fragment = context.createDocumentFragment(),        nodes = [],        i = 0,        elem,        l = elems.length;    for (; i < l; i++) {        elem = elems[i];        //创建一个元素div做为容器        tmp = fragment.appendChild(context.createElement("div"));        //放到文档碎片中        tmp.innerHTML = elem;        }    //在这个例子里,运行到此处fragment相当于
慕课网
return fragment;}/** parentEles:被塞内容的容器->数组* target:要添加的内容* callback:创建成功后调用的函数*/function domManip(parentEles, target, callback) { var l = parentEles.length; if (l) { //创建一个碎片,以document形式获取父元素中的第一个 //ownerDocument获取元素所属的Document var fragment = buildFragment([target], parentEles[0].ownerDocument); //获取创建成功的DOM、也就是我们需要添加的对象 first = fragment.childNodes[0]; //把结果返回给回调函数处理 if (first) { callback.call(parentEles, first); } }}function append(parentEles, target) { /** * parentEles:被塞内容的容器 * elem: 要添加的内容 */ return domManip([parentEles], target, function(elem) { //回调函数获取经过domManip处理后的DOM节点,可以直接添加 parentEles.appendChild(elem) });}append(document.getElementById('test'),'
通过append加入慕课网
')

Tip:这里的代码我稍微修改了一下,因为似乎有一些并没有用,可能是老师在放的时候是侧重讲这个点的,其他的没删干净。而且这个结果其实是向test添加了一个内容是<div><div>通过append加入慕课网</div></div>,按照常理应该没有外面包裹的div,但是childNodes[0]也好firstchild也好,都只能获取到这个结果,如果div里面有多个div要添加,直接再获取它下面的节点好像也不太好,所以我觉得这里应该是一个粗略的模拟。

处理script

div.innerHTML = "<script>alert('慕课网')";不会被执行,但是$('div').append("<script>alert('慕课网')")可以。它类似的函数调用过程是:.append()-> .domManip() -> buildFragment() ->clean()。

我们假设要进行append(document.querySelectorAll('div')[0],"<script>alert('慕课网')" )操作,改进原来的domManip方法:

//关闭脚本执行function disableScript(elem) {    elem.type = (elem.getAttribute("type") !== null) + "/" + elem.type;    //"

这里最后的/^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g正则解析图如下:

图片描述
可以看出是用于去除脚本代码里的空白字符以及注释和CDATA标记的。
另外补充clean()函数的作用:

clean() 中会动态产生一个div, 将div 的innerHTML设为传入的字符串,再用getElementsByTagName('script') 的方式把所有的script 抓出来另行储存。clean()执行完毕回到domManip() 中, domManip() 再将script 们一一拿出来执行。

代码中没有模拟实现,但是看得出clean()函数的作用其实就是把混杂的代码中的脚本单独抽出来进行处理。

转载地址:https://blog.csdn.net/weixin_34248258/article/details/88867264 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:php实现webservice(实测C#及java可调用)
下一篇:vue-design 桌面端页面可视化构建程序

发表评论

最新留言

留言是一种美德,欢迎回访!
[***.207.175.100]2024年04月02日 12时47分03秒