.toggle()和.wrap()、.unwrap()引发的一个问题

前言

——本文有点自嗨

正文

在做《jQuery基础教程》(第四版)课后练习的时候,有一题是这样要求的:在单击作者名字时,把文本改为粗体(通过标签,而不是操作类或css属性),然后在随后的单击中,删除之前的<b>元素,就是说在粗体文本与正常文本之间切换

简单的代码就这样了

<p>a wonderful author</p>

于是想到了.wrap()方法(将每一个匹配的元素分别包装起来

$(document).ready(function() {
	$('p').click(function() {
		$(this).wrap('<b></b>');
	});
});

效果是这样的(google控制台效果)

<b><p>a wonderful author</p></b>

看起来总觉得怪怪的,块级元素被行内元素包裹

于是想到了.wrapInner()方法(将每一个匹配的元素的子内容(包括文本节点)包装起来

$(document).ready(function() {
	$('p').click(function() {
		$(this).wrapInner('<b></b>');
	});
});

效果是这样的(google控制台效果)

<p><b>a wonderful author</b></p>

插播

还有个.wrapAll()方法别忘啦(将每一个匹配的元素作为一个整体包装起来),注意和.wrap()的区别:一个是整体,一个是分别

下面进行第二步,哪里来的回哪里去

<b>标签回去(删除)?
既然用了.wrap(),那就用.unwrap()(这里先不说.wrapInner()
但是这个怎么用呢?单击奇数次添加,单击偶数次删除
好啦!好像有个.toggle(fn1, fn2)可以实现(坑爹的W3School这样说得)
于是乎

$(document).ready(function() {
	$('p').toggle(function() {
		$(this).wrap('<b></b>');
	}, function() {
		$(this).unwrap();
	});
});

入坑

结果......(google控制台效果)

<p style="display: none;">a wonderful author</p>

作者直接消失了(死的好冤枉啊.....),将p的display设置为了none。

为什么会这样呢(在W3School实验的好好的)

经过网上搜索,万万没想到.toggle(fn1, fn2)在1.9版本被移除了、被移除了、被移除了....

所以只能按照.toggle()另一个定义执行(如果元素是可见的,切换为隐藏的;如果元素是隐藏的,切换为可见的。

而W3School上实验是成功的,是因为加了jQuery Migrate(迁移)插件

爬坑(此处不留爷自有留爷处)

$(document).ready(function() {
	var a = false;
	$('p').click(function() {
		if (!a) {
			$('p').wrap('<b></b>');
			a = true;
		} else {
			$('p').unwrap();
			a = false;
		}
	});
});

还是得回到最初的click上,这里先给声明一个变量a,并赋值false
第一次单击变粗体,并给a赋值true,这样下次单击就可以执行else语句删除粗体,同时给a赋值false
这样如此反复,就达到了交替切换的效果。

这是个很典型的解决方法,以后遇到此类情况都可以这样处理(如此好的方案当然是网上找到的)

自挖坑

作为处女座,其实是希望使用.wrapInner()来代替.wrap()的

$(document).ready(function() {
	var a = 0;
	$('p').click(function() {
		if (a === 0) {
			$('p').wrapInner('<b></b>');
			a = 1;
		} else {
			$('p').unwrap();
			a = 0;
		}
	});
});

结果你猜怎么着,第一次单击是这样的,好好的(google控制台效果)

<p><b>a wonderful author</b></p>

第二次单击呢?没反应、没反应、没反应.......

这是为什么呢

万万没想到.unwrap()是个偏心的人(删除元素的父元素,能快速取消.wrap()方法的效果),只和.wrap()搭配使用,不管.wrapInner()

公道话

依旧万万没想到.unwrap()方法呢,其实只是负责删除元素的父元素,不管有没有使用.wrap()方法。
只是恰好.wrap()是给元素添加了父元素

例如给<p>加个父元素div

<div><p>a wonderful author</p></div>

用.unwrap()试下

$(document).ready(function() {
	$('p').click(function() {
		$('p').unwrap();
	});
});

结果div就没了(google控制台效果)

<p>a wonderful author</p>

如果<p>元素还有父元素,只要单击,就会像剥洋葱一样,一层一层的剥到body(body不能剥)

总结:以后尽量用.wrap()喽

posted @ 2016-03-17 23:48  u14e  阅读(233)  评论(0编辑  收藏  举报