原理基本是这样,如果传入的是字符串,那么让它们变成一个元素节点,不过这元素节点也可以有许多层,在最内层把要包裹的元素放进。把字符串变成元素节点的方法有如下几个。
1,createElement,IE可以连元素属性也一起创建,但只能创建一层。
2,innerHTML,不过需要对原来的字符串进行处理,IE与FF都有许多意想不到的默认行为,可以为你多加一点东西或少加一点东西。
3,createContextualFragment,由于Opera的行为有点怪异,需要选中修改元素的位置。经日本人的测试,它转换字符串成节点的效率比innerHTML高多了,也安全多了,真是强者愈强,弱者愈弱。如果是传入元素节点,需要克隆一下,要不都变成wrapAll。如果是函数,把当前元素传进去,利用它的某些属性创建一个包裹元素。
最初的实验品(这里的wrapOuter相当于jQuery的wrap):
var parseHTML = function(str) {
if(document.createRange){
var range = document.createRange()
range.setStartAfter(document.body)
return range.createContextualFragment(str)
}else{
return document.createElement(str)
}
}
var wrapOuter = function(target,html){
var wrap = parseHTML(html) ;
target.parentNode.insertBefore(wrap,target);
target.previousSibling.appendChild(target)
}
") }
[Ctrl+A 全选 注:如需引入外部Js需刷新才能执行]
发现在Opera中出了些问题,range.setStartAfter(document.body)要改成我们的目标元素才行。再者,将插入包裹元素的方式由insertBefore改为replaceChild,提高效率。
var wrapOuter = function(target,html){
var wrap = html
if(Object.prototype.toString.call(html) === "[object String]"){
if(document.createRange){
var range=document.createRange();
range.selectNodeContents(target);
wrap = range.createContextualFragment(html).firstChild;
}else {
wrap = document.createElement(str);
}
}
target.parentNode.replaceChild(wrap,target);
wrap.appendChild(target)
}
") }
[Ctrl+A 全选 注:如需引入外部Js需刷新才能执行]
//给每个匹配元素都增加一个父元素(包裹元素),
wrap:function(html){//html可以是元素节点,也可以是html片断
var _wrap = function(target,html){
var wrap;
if(is(html,"String")){
if(document.createRange){
var range=document.createRange();
range.selectNodeContents(target);
wrap = range.createContextualFragment(html).firstChild;
}else {
wrap = document.createElement(html);
}
}else if(html.nodeType){
wrap = html.cloneNode(true)
}
target.parentNode.replaceChild(wrap,target);
wrap.appendChild(target)
}
if(is(html,"Function")){
return this.each(function(el,index){
_wrap(el, html.call(el,index));
});
}
return this.each(function(el){
_wrap(el,html)
});
},
把创建包裹元素的方法抽象出来:
var _parseHTML = function(el,html){
var wrap = html ;
if(doc.createRange){
var range=doc.createRange();
range.selectNodeContents(el);
var wrap = range.createContextualFragment(html).firstChild;
range.detach();
return wrap;
}else {
return dom.parseHTML(html);
}
}
//给每个匹配元素都增加一个父元素(包裹元素),
wrap:function(html){//html可以是元素节点,也可以是html片断
var _wrap = function(target,html){
var wrap = html ;
if(!wrap.nodeType){
wrap = dom._parseHTML(target,html);
}else{
wrap = html.cloneNode(true)
}
target.parentNode.replaceChild(wrap,target);
wrap.insertBefore(target,null)
}
if(is(html,"Function")){
return this.each(function(el,index){
_wrap(el, html.call(el,index));
});
}
return this.each(function(el){
_wrap(el,html)
});
},
wrapInner:function(html){
var _wrap = function(target,html){
var wrap = html ;
if(!wrap.nodeType){
wrap = dom._parseHTML(target,html);
}else{
wrap = html.cloneNode(true)
}
target.insertBefore(wrap,target.firstChild);
for(var i=1,n=target.childNodes.length;i
}
}
if(is(html,"Function")){
return this.each(function(el,index){
_wrap(el, html.call(el,index));
});
}
return this.each(function(el){
_wrap(el,html)
});
},
//用一个标签包裹所有匹配元素
//做法:在第一个匹配元素上添加一个父元素(包裹),然后把其他匹配元素都转移到此父元素中来
//wrapAll(html) wrapAll(elem)
wrapAll:function(html){
var wrap = html;
if(!wrap.nodeType)
wrap = dom._parseHTML(this[0],html);
this[0].parentNode.replaceChild(wrap,this[0]);
return this.each(function(el){
wrap.insertBefore(el,null);
});
},
到jQuery官网看一下,发现它的包裹节点的方法升级了,每次可以包裹许多层了,而我的每次只能包一层。于是决定调用我原来的parseHTML方法,见这里。
var wrap = function(html){//html可以是元素节点,也可以是html片断
var _wrap = function(target,html){
var wrap = html ;
if(!wrap.nodeType){
if(doc.createRange){
var range=doc.createRange();
range.selectNodeContents(target);
wrap = range.createContextualFragment(html).firstChild;
}else{
wrap = dom.parseHTML(html,null,true).firstChild
}
}else{
wrap = html.cloneNode(true)
}
target.parentNode.replaceChild(wrap,target);
while ( wrap.firstChild && wrap.firstChild.nodeType === 1 ) {
wrap = wrap.firstChild;
}
wrap.insertBefore(target,null)
}
if(is(html,"Function")){
return this.each(function(el,index){
_wrap(el, html.call(el,index));
});
}
return this.each(function(el){
_wrap(el,html)
});
}
//把每一个匹配元素的子节点都用东西包裹起来
var wrapInner = function(html){
var _wrap = function(target,html){
var wrap = html ;
if(!wrap.nodeType){
wrap = dom.parseHTML(html,null,true).firstChild
}else{
wrap = html.cloneNode(true)
}
target.insertBefore(wrap,target.firstChild);
while ( wrap.firstChild && wrap.firstChild.nodeType === 1 ) {
wrap = wrap.firstChild;
}
for(var i=1,n=target.childNodes.length;i
}
}
if(is(html,"Function")){
return this.each(function(el,index){
_wrap(el, html.call(el,index));
});
}
return this.each(function(el){
_wrap(el,html)
});
}
//用一个标签包裹所有匹配元素
//做法:在第一个匹配元素上添加一个父元素(包裹),然后把其他匹配元素都转移到此父元素中来
//wrapAll(html) wrapAll(elem)
var wrapAll = function(html){
var wrap = html;
if(!wrap.nodeType){
if(doc.createRange){
var range = doc.createRange();
range.selectNodeContents(this[0]);
wrap = range.createContextualFragment(html).firstChild;
}else{
wrap = dom.parseHTML(html,null,true).firstChild
}
} else{
wrap = html.cloneNode(true)
}
this[0].parentNode.replaceChild(wrap,this[0]);
while ( wrap.firstChild && wrap.firstChild.nodeType === 1 ) {
wrap = wrap.firstChild;
}
return this.each(function(el){
wrap.insertBefore(el,null);
});
}
发现有许多重复代码,再抽象一下,对外人来说,彻底的不知所云,想必jQuery也是这样一步步搞到晦涩难懂的。
dom.mixin(dom[fn],(function(){
var wrapHelper = function(target,html ){
var wrap = html ;
if(!wrap.nodeType){
if(document.createRange){
var range=dom.doc.createRange();
range.selectNodeContents(target);
wrap = range.createContextualFragment(html).firstChild;
} else{
wrap = dom.parseHTML(html,null,true).firstChild
}
}else{
wrap = html.cloneNode(true)
}
var insertor = wrap;
while ( insertor.firstChild && insertor.firstChild.nodeType === 1 ) {
insertor = insertor.firstChild;
}
return [wrap,insertor]
}
//用一个标签包裹所有匹配元素
//做法:在第一个匹配元素上添加一个父元素(包裹),然后把其他匹配元素都转移到此父元素中来
//wrapAll(html) wrapAll(elem)
var wrapAll = function(html){
if ( dom.isFunction( html ) ) {
return this.each(function(el,index) {
dom(this).wrapAll( html.call(this, index));
});
}
var arr = wrapHelper(this[0],html);
var wrap = arr[0],insertor =arr[1];
this[0].parentNode.replaceChild(wrap,this[0]);
return this.each(function(el){
insertor.insertBefore(el,null);
});
}
//给每个匹配元素都增加一个父元素(包裹元素),
var wrap= function( html ) {
return this.each(function() {
dom( this ).wrapAll( html );
});
}
//把每一个匹配元素的子节点都用东西包裹起来
var wrapInner = function(html){
var _wrap = function(target,html){
var arr = wrapHelper(target,html);
var wrap = arr[0],insertor =arr[1];
target.insertBefore(wrap,target.firstChild);
for(var i=1,n=target.childNodes.length;i
}
}
if(is(html,"Function")){
return this.each(function(el,index){
_wrap(el, html.call(el,index));
});
}
return this.each(function(el){
_wrap(el,html)
});
}
return {
wrapAll:wrapAll,
wrap:wrap,
wrapInner:wrapInner
}
})());
unwrap方法以后再说!

去掉重复并排序的方法:1、使用“Array.from(new Set(arr))”或者“[…new Set(arr)]”语句,去掉数组中的重复元素,返回去重后的新数组;2、利用sort()对去重数组进行排序,语法“去重数组.sort()”。

本篇文章给大家带来了关于JavaScript的相关知识,其中主要介绍了关于Symbol类型、隐藏属性及全局注册表的相关问题,包括了Symbol类型的描述、Symbol不会隐式转字符串等问题,下面一起来看一下,希望对大家有帮助。

怎么制作文字轮播与图片轮播?大家第一想到的是不是利用js,其实利用纯CSS也能实现文字轮播与图片轮播,下面来看看实现方法,希望对大家有所帮助!

本篇文章给大家带来了关于JavaScript的相关知识,其中主要介绍了关于对象的构造函数和new操作符,构造函数是所有对象的成员方法中,最早被调用的那个,下面一起来看一下吧,希望对大家有帮助。

方法:1、利用“点击元素对象.unbind("click");”方法,该方法可以移除被选元素的事件处理程序;2、利用“点击元素对象.off("click");”方法,该方法可以移除通过on()方法添加的事件处理程序。

本篇文章给大家带来了关于JavaScript的相关知识,其中主要介绍了关于面向对象的相关问题,包括了属性描述符、数据描述符、存取描述符等等内容,下面一起来看一下,希望对大家有帮助。

foreach不是es6的方法。foreach是es3中一个遍历数组的方法,可以调用数组的每个元素,并将元素传给回调函数进行处理,语法“array.forEach(function(当前元素,索引,数组){...})”;该方法不处理空数组。

本篇文章给大家带来了关于JavaScript的相关知识,其中主要介绍了关于BOM操作的相关问题,包括了window对象的常见事件、JavaScript执行机制等等相关内容,下面一起来看一下,希望对大家有帮助。


热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

AI Hentai Generator
免费生成ai无尽的。

热门文章

热工具

Dreamweaver CS6
视觉化网页开发工具

WebStorm Mac版
好用的JavaScript开发工具

禅工作室 13.0.1
功能强大的PHP集成开发环境

适用于 Eclipse 的 SAP NetWeaver 服务器适配器
将Eclipse与SAP NetWeaver应用服务器集成。

安全考试浏览器
Safe Exam Browser是一个安全的浏览器环境,用于安全地进行在线考试。该软件将任何计算机变成一个安全的工作站。它控制对任何实用工具的访问,并防止学生使用未经授权的资源。