jQuery之html()的实现
一、有这样一段 html
<div class="divOne"> <p>嘿嘿嘿</p> </div> <div class="divOne"> <p>哈哈哈</p> </div>
二、jQuery 的 html() 方法
(1)当直接调用 $().html()
时,.html()
的作用是只读取第一个目标元素的innerHTML
简单实现:
function customHtml(value) { //默认是选取第一个目标元素 let elem = this[0] || {}, i = 0, l = this.length; //如果是html(),即使读取目标元素的innerHTML的话 if (value === undefined && elem.nodeType === 1) { return elem.innerHTML; } //xxx //xxx }
(2)当调用$().html(value)
时,.html()
的作用是为每一个符合条件的目标元素的innerHTML
设置为 value
简单实现:
function customHtml(value) { //默认是选取第一个目标元素 let elem = this[0] || {}, i = 0, l = this.length; //如果是html(),即使读取目标元素的innerHTML的话 if (value === undefined && elem.nodeType === 1) { return elem.innerHTML; } //根据目标元素的个数,依次对符合条件的目标元素赋值 for (; i < l; i++) { elem = this[i] || {}; if (elem.nodeType === 1) { elem.innerHTML = value; } } }
(3)源码实现
源码:
// html()方法设置或返回被选元素的内容(innerHTML) // 当该方法用于返回内容时,则返回第一个匹配元素的内容 // 当该方法用于设置内容时,则重写所有匹配元素的内容 // http://www.runoob.com/jquery/html-html.html // 源码6203行左右 function html( value ) { //调用$().html()方法,即调用access()方法 //关于access()方法的讲解,请看:https://www.cnblogs.com/gongshunkai/p/5905917.html //access(this,function(),null,value,arguments.length) return jQuery.access( this, function( value ) { //读的话(.html())只读第一个匹配的目标元素的内容所以是this[0] //写的话(.html(xxx))会循环每个匹配的目标并将其innerHTML置为value var elem = this[ 0 ] || {}, i = 0, l = this.length; //当直接调用html(),并且目标元素是元素节点时,$().html()的本质是 selector.innerHTML if ( value === undefined && elem.nodeType === 1 ) { return elem.innerHTML; } // See if we can take a shortcut and just use innerHTML //如果能直接使用innerHTML来解析的话 //注意:IE的innerHTML会忽略开头的无作用域元素 if ( typeof value === "string" && !rnoInnerhtml.test( value ) && !wrapMap[ ( rtagName.exec( value ) || [ "", "" ] )[ 1 ].toLowerCase() ] ) { //Hello <b>world</b>! value = jQuery.htmlPrefilter( value ); console.log(value,'value6235') try { for ( ; i < l; i++ ) { elem = this[ i ] || {}; // Remove element nodes and prevent memory leaks if ( elem.nodeType === 1 ) { console.log(3333,'node6261') // getAll( elem, false ):获取原本selector内部的内容(标签) //先移除元素节点和注册的事件以防止内存泄漏 jQuery.cleanData( getAll( elem, false ) ); elem.innerHTML = value; } } //将elem置为0,是防止执行下面的if(elem)... elem = 0; // If using innerHTML throws an exception, use the fallback method } catch ( e ) {} } if ( elem ) { this.empty().append( value ) } }, null, value, arguments.length ) }
源码解析:
① 调用html()
,实际上是调用access()
access部分源码:
//$().html():access(this,function(),null,value,arguments.length) //源码4051行 //关于access()方法的讲解,请看:https://www.cnblogs.com/gongshunkai/p/5905917.html var access = function( elems, fn, key, value, chainable, emptyGet, raw ) { var i = 0, //1 len = elems.length, //true bulk = key == null; // Sets many values if ( toType( key ) === "object" ) { //xxx } else if ( value !== undefined ) { console.log('access->value!==undefined','value4053') chainable = true; //xxx if ( bulk ) { // Bulk operations run against the entire set //走这边 if ( raw ) { // 将elems/selector,value传入function并执行 // call(this,param) fn.call( elems, value ); //这里将 function 置为空值后,就不会执行 if(fn)...了 fn = null; // ...except when executing function values } //不走这边 else { bulk = fn; fn = function( elem, key, value ) { return bulk.call( jQuery( elem ), value ); }; } } //xxx //xxx //xxx };
也就是说:调用jQuery.access()
相当于调用了fn.call( elems, value )
,即自定义的方法jQuery.access(this, function(value) {xxx})
② .html()
的情况调用这部分源码:
if ( value === undefined && elem.nodeType === 1 ) { return elem.innerHTML; }
③ .html("字符串")
/.html("<p>这也是字符串</p>")
的情况调用这部分源码:
// See if we can take a shortcut and just use innerHTML //如果能直接使用innerHTML来解析的话 //注意:IE的innerHTML会忽略开头的无作用域元素 if ( typeof value === "string" && !rnoInnerhtml.test( value ) && !wrapMap[ ( rtagName.exec( value ) || [ "", "" ] )[ 1 ].toLowerCase() ] ) { //Hello <b>world</b>! value = jQuery.htmlPrefilter( value ); console.log(value,'value6235') try { for ( ; i < l; i++ ) { elem = this[ i ] || {}; // Remove element nodes and prevent memory leaks if ( elem.nodeType === 1 ) { console.log(3333,'node6261') // getAll( elem, false ):获取原本selector内部的内容(标签) //先移除元素节点和注册的事件以防止内存泄漏 jQuery.cleanData( getAll( elem, false ) ); elem.innerHTML = value; } } //将elem置为0,是防止执行下面的if(elem)... elem = 0; // If using innerHTML throws an exception, use the fallback method } catch ( e ) {} }
④ .html(这里面是标签)
的情况调用这部分源码:
标签:
let p=document.createElement('p') p.innerText='哈哈哈' $(".divOne").html(p)
源码:
if ( elem ) { this.empty().append( value ); }
⑤ 总结$(".divOne").html()
的本质即 $(".divOne")[0].innerHTML
$(".divOne").html("Hello <b>world</b>!")
的本质即 $(".divOne")[i].innerHTML="Hello <b>world</b>!"
$(".divOne").html(标签)
的本质即 $(".divOne").empty().append(标签)
源码:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>jQuery之html()</title> </head> <body> <script src="jQuery.js"></script> <div class="divOne"> <p>嘿嘿嘿</p> </div> <div class="divOne"> <p>嘿嘿嘿</p> </div> <input type="text" id="inputOne"> <script> function customHtml(value) { //默认是选取第一个目标元素 let elem = this[0] || {}, i = 0, l = this.length; //如果是html(),即使读取目标元素的innerHTML的话 if (value === undefined && elem.nodeType === 1) { return elem.innerHTML; } //根据目标元素的个数,依次对符合条件的目标元素赋值 for (; i < l; i++) { elem = this[i] || {}; if (elem.nodeType === 1) { elem.innerHTML = value; } } } // html()方法设置或返回被选元素的内容(innerHTML) // 当该方法用于返回内容时,则返回第一个匹配元素的内容 // 当该方法用于设置内容时,则重写所有匹配元素的内容 // http://www.runoob.com/jquery/html-html.html // 源码6203行左右 function html( value ) { //调用$().html()方法,即调用access()方法 //关于access()方法的讲解,请看:https://www.cnblogs.com/gongshunkai/p/5905917.html //access(this,function(),null,value,arguments.length) return jQuery.access( this, function( value ) { //读的话(.html())只读第一个匹配的目标元素的内容所以是this[0] //写的话(.html(xxx))会循环每个匹配的目标并将其innerHTML置为value var elem = this[ 0 ] || {}, i = 0, l = this.length; //当直接调用html(),并且目标元素是元素节点时,$().html()的本质是 selector.innerHTML if ( value === undefined && elem.nodeType === 1 ) { return elem.innerHTML; } // See if we can take a shortcut and just use innerHTML //如果能直接使用innerHTML来解析的话 //注意:IE的innerHTML会忽略开头的无作用域元素 if ( typeof value === "string" && !rnoInnerhtml.test( value ) && !wrapMap[ ( rtagName.exec( value ) || [ "", "" ] )[ 1 ].toLowerCase() ] ) { //Hello <b>world</b>! value = jQuery.htmlPrefilter( value ); console.log(value,'value6235') try { for ( ; i < l; i++ ) { elem = this[ i ] || {}; // Remove element nodes and prevent memory leaks if ( elem.nodeType === 1 ) { console.log(3333,'node6261') // getAll( elem, false ):获取原本selector内部的内容(标签) //先移除元素节点和注册的事件以防止内存泄漏 jQuery.cleanData( getAll( elem, false ) ); elem.innerHTML = value; } } //将elem置为0,是防止执行下面的if(elem)... elem = 0; // If using innerHTML throws an exception, use the fallback method } catch ( e ) {} } if ( elem ) { this.empty().append( value ); } }, null, value, arguments.length ); } customHtml.call(document.querySelectorAll(".divOne")) customHtml.call(document.querySelectorAll(".divOne"),"Hello <b>world</b>!") // console.log($(".divOne").html()) // $(".divOne").html("Hello <b>world</b>!") // let p=document.createElement('p') // p.innerText='哈哈哈gggg' // $(".divOne").html(p) // console.log(p,'p19') // $("#divOne").text('<p>aaaa</p>') // $("#divOne").text(p) </script> </body> </html>
(完)
相关推荐
EdwardSiCong 2020-11-23
85477104 2020-11-17
hhanbj 2020-11-17
81427005 2020-11-11
seoppt 2020-09-13
honeyth 2020-09-13
WRITEFORSHARE 2020-09-13
84483065 2020-09-11
momode 2020-09-11
85477104 2020-08-15
83510998 2020-08-08
82550495 2020-08-03
tthappyer 2020-08-03
84901334 2020-07-28
tthappyer 2020-07-25
TONIYH 2020-07-22
tztzyzyz 2020-07-20
83510998 2020-07-18
81463166 2020-07-17