概况
ios-给AttributedString增多属性以至怎么着去取,
ios-给AttributedString加多属性以致哪些去取,不常大家或者会需求给AttributedString也正是属性字符串设置属性,然后在别的八个地方进行拍卖,大家也足以由此这些点子进行传值,具体操作可以如下所示这里大家是先创设一个数组,创制完毕之后,大家再去通过设置属性,那样大家能够在此外多个地点可以去获取到它的值,然后经过遍历可以做相应的操作。下边包车型大巴三个措施这里面包车型大巴range,传入的是叁个地方,那样大家再把range给收取来就足以博得的是在底下那么些index索引处所获得的天性的安装的限制,也可以这么解释effectiveRange参数是援用参数,该参数反映了在所检索的岗位上,字符串中存有当前的性质的节制。
- (nullable id)attribute:(NSAttributedStringKey)attrName atIndex:(NSUInteger)location effectiveRange:(nullable NSRangePointer)
range;
用法如下所示
NSArray * array = [[NSArray alloc]init];
[email protected][@(1)];
NSMutableAttributedString * attributedText = [[NSMutableAttributedString alloc]init];
NSAttributedString * attributedString = [[NSAttributedString alloc]initWithString:@"哈哈哈"];
[attributedText appendAttributedString:attributedString];
NSAttributedString * attributedString1 = [[NSAttributedString alloc]initWithString:@"没没没"];
[attributedText appendAttributedString:attributedString1];
[attributedText addAttribute:@"NSAttributeKey" value:array range:NSMakeRange(0, 1)];
[attributedText enumerateAttributesInRange:NSMakeRange(0, attributedText.length) options:0 usingBlock:^(NSDictionary
* _Nonnull attrs, NSRange range, BOOL * _Nonnull stop) {
//NSLog(@"%@",attrs[@"NSAttributeKey"]);
id value = [attributedText attribute:@"NSAttributeKey" atIndex:0 effectiveRange:NULL];
NSLog(@"%@",value);
}];
ios-给AttributedString增多属性以至怎么着去取,一时我们或然会要求给AttributedString也正是性质字...
前方的话
为了让开拓职员更方便地垄断页面,DOM定义了“范围”(range)接口。通过约束能够挑选文书档案中的二个区域,而不用构思节点的尽头(接收在后台完结,对客商是不可以知道的)。在例行的DOM操作无法更有效地改进文挡时,使用约束往往能够达到目标。本文将详细介绍DOM范围
开创范围
Document类型中定义了createRange()方法。在卓殊DOM的浏览器中,那几个办法属于document对象。使用hasFeature()可能直接检验该格局,都能够明显浏览器是还是不是补助范围
[注意]IE8-浏览器不援助
var supportsRange = document.implementation.hasFeature("Range", "2.0");
var alsoSupportsRange =(typeof document.createRange == "function");
要是浏览器辅助范围,那么就足以接纳createRange()来创设DOM范围,如下所示
var range = document.createRange();
与节点相同,新创建的节制也直接与创立它的文书档案关联在联合,不能用来此外文档。创造了节制之后,接下去就可以运用它在后台选拔文书档案中的特定部分。而创造范围并设置了其岗位然后,还是能针对范围的原委实践很三种操作,从而完结对底层DOM树的越来越小巧的主宰
各种范围由三个Range类型的实例表示,那些实例具备众多属性和方法。下列属性提供了眼下界定在文书档案中的地点音信
startContainer:包含范围起点的节点(即选区中第一个节点的父节点)
startoffset:范围在startContainer中起点的偏移量。如果startContainer是文本节点、注释节点或CDATA节点,那么startoffset就是范围起点之前跳过的字符数量。否则,startoffset就是范围中第一个子节点的索引
endContainer:包含范围终点的节点(即选区中最后一个节点的父节点)
endOffset:范围在endContainer中终点的偏移量(与startoffset遵循相同的取值规则)
commonAncestorContainer:startContainer和endContainer共同的祖先节点在文档树中位置最深的那个
在把范围放到文书档案中一定的义务时,那几个属性都会被赋值
简轻巧单采取
要利用范围来采撷文书档案中的生龙活虎有的,最简易的方法正是选择selectNode()或selectNodeContents()。这多个措施都接纳三个参数,即二个DOM节点,然后利用该节点中的消息来填充范围。个中,selectNode()方法采纳一切节点,包罗其子节点;而selectNodeContents()方法则只选择节点的子节点
<!DOCTYPE html>
<html>
<body>
<p id="p1"><b>Hello</b> world!</p>
</body>
</html>
大家得以行使下列代码来创制范围
var range1 = document.createRange();
var range2 = document.createRange();
var p1 = document.getElementById("p1");
//Range {startContainer: body, startOffset: 1, endContainer: body, endOffset: 2, collapsed: false…}
range1.selectNode(p1);
//Range {startContainer: p#p1, startOffset: 0, endContainer: p#p1, endOffset: 2, collapsed: false…}
range2.selectNodeContents(p1);
这里开创的多个范围饱含文书档案中分歧的局地:rang1含有<p>成分及其全数子成分,而rang2包蕴<b>元素、文本节点"Hello"和文件节点"world!"
在调用selectNode()时,startContainer、endContainer和commonAncestorContainer都等于传入节点的父节点,相当于其一事例中的document.body。而startoffset属性等于给定节点在其父节点的childNodes集合中的索引(在这里个事例中是1——因为门户特别DOM的浏览器将空格算作贰个文本节点),endOffset等于startoffset加1(因为只选用了贰个节点)
在调用selectNodeContents()时,startContainer、endContainer和commonAncestorContainer等于传入的节点,即这几个例子中的<p>元素。而startoffset属性始终等于0,因为范围从给定节点的首先个头节点开端。最终,endOffset等于子节点的多寡(node.childNodes.length),在此个事例中是2
别的,为了越来越精致地调控将何以节点包蕴在界定中,还是能够运用下列方法
setStartBefore(refNode):将范围的起点设置在refNode之前,因此refNode也就是范围选区中的第一个子节点。同时会将startContainer属性设置为refNode.parentNode,将startoffset属性设置为refNode在其父节点的childNodes集合中的索引
setStartAfter(refNode):将范围的起点设置在refNode之后,因此refNode也就不在范围之内了,其下一个同辈节点才是范围选区中的第一个子节点。同时会将startContainer属性设置为refNode.parentNode,将startoffset属性设置为refNode在其父节点的childNodes集合中的索引加1
setEndBefore(refNode):将范围的终点设置在refNode之前,因此refNode也就不在范围之内了,其上一个同辈节点才是范围选区中的最后一个子节点。同时会将endContainer属性设置为refNode.parentNode,将endOffset属性设置为refNode在其父节点的childNodes集合中的索引
setEndAfter(refNode):将范围的终点设置在refNode之后,因此refNode也就是范围选区中的最后一个子节点。同时会将endContainer属性设置为refNode.parentNode,将endOffset属性设置为refNode在其父节点的childNodes集合中的索引加1
调用这个主意时,全数属性会活动安装好。不过,要想制造复杂的限量选区,也能够一向钦赐那么些属性的值
复杂接收
要创建复杂的约束就得使用setStart()和setEnd()方法。那八个艺术都领受五个参数:三个参谋节点和三个偏移量值。对setStart()来讲,参照节点会成为startContainer。而偏移量值会产生startoffset。对于setEnd()来讲,参照节点会造成endContainer,而偏移量值会形成endOffset。能够应用那七个办法来模拟selectNode()和selectNodeContents()。来看上面包车型客车事例
var range1 = document.createRange();
var range2 = document.createRange();
var p1 = document.getElementById("p1");
var p1Index = -1;
var i, len;
for (i=0, len=p1.parentNode.childNodes.length; i < len; i++) {
if (p1.parentNode.childNodes[i] == p1) {
p1Index = i;
break;
}
}
range1.setStart(p1.parentNode, p1Index);
range1.setEnd(p1.parentNode, p1Index + 1);
range2.setStart(p1, 0);
range2.setEnd(p1, p1.childNodes.length);
明显,要选取这些节点(使用range1),就务须分明当前节点(p1)在其父节点的childNodes集结中的索引。而要选用那些节点的情节(使用range2),也不要总结什么;只要通过setStart()和setEnd()设置暗中同意值就能够。模仿selectNode()和selectNodeContents()并非setStart()和setEnd()的主要用处,它们更胜一筹之处在于能够接受节点的大器晚成有的
假如只想选拔前边HTML示例代码中从“Hello"的"llo"到"world!"的"o"——十分轻便产生
第一步是获得具备节点的援引,如下所示:
var p1 = document.getElementById("p1");
var helloNode = p1.firstChild.firstChild;
var worldNode = p1.lastChild;
实际上,"Hello”文本节点是<p>成分的儿子节点,因为它自己是<b>成分的三个子节点。因而,p1.firstchild获取的是<b>,而p1.firstchild.firstchild收获的才是以此文件节点。"world!"文本节点是<p>元素的第叁个子节点(也是终极三个子节点),因而能够运用p1.lastChild得到该节点。然后,必需在成立范围时钦命相应的源点和极端,如下所示
var range = document.createRange();
range.setStart(helloNode, 2);
range.setEnd(worldNode, 3);
因为那个限定的选区应该从"Hello"中"e"的末尾开始,所以在setStart()中盛传helloNode的还要,传入了偏移量2(即"e"的下三个职位;"H"的职位是0)。设置选区的尖峰时,在setEnd()中传出worldNode的同不时间传入了偏移量3,表示选区之外的首先个字符的职分,那个字符是”r",它的职位是3(地点0上还应该有三个空格)。如下所示
由于helloNode和worldNode都是文件节点,由此它们各自成为了新建范围的startContainer和endContainer。那时候startoffset和endOffset分别用于显明多个节点所包括的公文中之处,实际不是用于鲜明子节点的职位(就疑似流传的参数为要金秋点时那么)。这个时候的commonAncestorContainer是<p>成分,也正是同有时间含有那八个节点的首先个祖先成分
当然,仅仅是筛选了文档中的某豆蔻梢头有个别用途并不大。但首要的是,接受之后才足以对选区实行操作
操作范围内容
在开创范围时,内部会为那几个限定创立二个文档片段,范围所属的万事节点都被加多到了那一个文书档案片段中。为了创立这些文书档案片段,范围内容的格式必得科学有效。在前头的例子中,创制的选区分别最初和得了于五个公文节点的中间,由此不可能算是格式优良的DOM结构,也就无法透过DOM来代表。可是,范围知道小编缺少什么开标签和闭标签,它亦可再次营造有效的DOM结构以便对其开展操作
对于如今的例证来说,范围经过测算清楚选区中远远不足三个发端的<b>标签,因而就能在后台动态插手三个该标签,同一时间还有可能会在头里参加三个象征截至的</b>标签以了却"He"。于是,改善后的DOM就改成了如下所示
<p><b>He</b><b>llo</b> world!</p>
此外,文本节点"world!"也被拆分为七个公文节点,三个分包"wo",另二个包罗"rid!"。最后的DOM树下图所示,左侧是表示范围的文书档案片段的剧情
像这么创造了节制之后,就能够利用各类办法对范围的从头到尾的经过进行操作了
[注意]意味着范围的里边文档片段中的全体节点,都只是指向文书档案中相应节点的指针
【deleteContents()】
操作范围内容的第1个章程是deleteContents(),那几个点子能够从文书档案中删除范围所包罗的剧情
var p1 = document.getElementById("p1");
var helloNode = p1.firstChild.firstChild;
var worldNode = p1.lastChild;
var range = document.createRange();
range.setStart(helloNode, 2);
range.setEnd(worldNode, 3);
range.deleteContents();
实践以上代码后,页面中会展现如下HTML代码
<p><b>He</b>rld!</p>
由于节制选区在修改底层DOM结构时能够保障格式杰出,由此就算内容被剔除了,最后的DOM结构依然是格式优质的
【extractContents()】
与deleteContents()方法平日,extractContents()方法也会从文书档案中移除范围选区。但差别在于,extractContents()会回来范围的文书档案片段。利用那几个重临的值,能够将限定的剧情插入到文书档案中的其余地方。如下所示:
var p1 = document.getElementById("p1");
var helloNode = p1.firstChild.firstChild;
var worldNode = p1.lastChild;
var range = document.createRange();
range.setStart(helloNode, 2);
range.setEnd(worldNode, 3);
var fragment = range.extractContents();
p1.parentNode.appendChild(fragment);
在此个例子中,将提收取来的文书档案片段添加到了文书档案<body>成分的最后
[注意]在将文书档案片段传入appendChild()方法中时,增加到文书档案中的只是一些的子节点,而非片段自个儿
<p><b>He</b>rld!</p>
<b>llo</b> wo
【cloneContents】
还会有意气风发种做法是利用cloneContents()创造范围对象的三个别本,然后在文档别的地点插入该别本
var p1 = document.getElementById("p1");
var helloNode = p1.firstChild.firstChild;
var worldNode = p1.lastChild;
var range = document.createRange();
range.setStart(helloNode, 2);
range.setEnd(worldNode, 3);
var fragment = range.cloneContents();
p1.parentNode.appendChild(fragment);
那么些主意与extractContents()特别左近,因为它们都回到文档片段。它们的重大分裂在于,cloneContents()再次回到的文书档案片段富含的是限量中节点的别本,并非实在的节点。奉行上边的操作后,页面中的HTML代码如下所示:
<p><b>Hello</b> world!</p>
<b>llo</b> wo
[注意]在调用cloneContents()方法以前,拆分的节点并不会产生格式优良的文书档案片段。换句话说,原始的HTML在DOM被改造从前会一贯维持不改变
安排范围内容
利用范围,可以去除或复制内容,还是能像前边介绍的那么操作范围中的内容。使用insertNode()方法能够向范围选区的发端处插入贰个节点。如若在头里例子中的HTML前边插入以下HTML代码
Inserted text
那么能够采纳下列代码:
var p1 = document.getElementById("p1");
var helloNode = p1.firstChild.firstChild;
var worldNode = p1.lastChild;
var range = document.createRange();
var span = document.createElement("span");
range.setStart(helloNode, 2);
range.setEnd(worldNode, 3);
span.style.color = "red";
span.appendChild(document.createTextNode("Inserted text"));
range.insertNode(span);
运维以上javascript代码,就能获得如下HTML代码
<p id="p1"><b>HeInserted textllo</b> world</p>
[注意]<span>无独有偶被插入到了"Hello"中的"llo"前边,而该职位正是节制选区的上马地方。使用这种技巧能够插入一些声援提示新闻,举例在开发新窗口的链接旁边插入风流倜傥幅图像
【surroundContents()】
除了向范围里边插入内容之外,还是能围绕范围插入内容,那时候快要采用surroundContents()方法。那些办法接纳一个参数,即围绕范围内容的节点。在缠绕范围插入内容时,后台会实行下列步骤
1、提抽出范围中的内容(相仿实践extractContents())
2、将给定节点插入到文书档案中原本范围所在的职分上
3、将文书档案片段的原委加多到给定节点中
能够应用这种技艺来出色展现网页中的有个别词句,譬如下列代码
var p1 = document.getElementById("p1");
var helloNode = p1.firstChild.firstChild;
var worldNode = p1.lastChild;
var range = document.createRange();
range.selectNode(helloNode);
var span = document.createElement("span");
span.style.backgroundColor = "yellow";
range.surroundContents(span);
以上代码会给范围选区加上三个香艳的背景。拿到的HTML代码如下所示
<p><b>Hello</b> world!</p>
为了插入<span>,范围必需含有全部DOM选区,而不能仅仅包蕴选中的DOM节点