一、有这样一段 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>
(完)
网友评论