jQuery基础(1)

一、样式篇

第1章 初识jQuery

(1)环境搭建

进入官方网站获取最新的版本 http://jquery.com/download/ ,这里需要注意 jQuery 分 2 个系列版本 1.x 与 2.x,主要的区别在于** 2.x 不再兼容 IE6、7、8浏览器,这样做的目的是为了兼容移动端开发。由于减少了一些代码,使得该版本比 jQuery 1.x 更小、更快。
如果开发者比较在意老版本 IE 用户,只能使用 jQuery 1.9 及之前的版本了。我们这本课程为了兼容性问题,使用的是 1.9 版本。jQuery 每一个系列版本分为:压缩版(compressed) 与 开发版(development),我们在开发过程中使用
开发版(开发版本便于代码修改及调试),项目上线发布使用压缩版(因为压缩版本体积更小,效率更快)。
** jQuery是一个JavaScript脚本库
,不需要特别的安装,只需要我们在页面 <head> 标签内中,通过 script 标签引入 jQuery 库即可。

<!DOCTYPE HTML>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <script type="text/javascript" src="http://libs.baidu.com/jquery/1.9.1/jquery.js"></script>
    <title>环境搭建</title>
</head> 
<body>
    <script type="text/javascript"> alert($) </script>
</body>
</html>

alert 弹出以上信息,说明环境已经搭建成功了。

(2)jQueryHelloWorld体验

当页面加载完成后,在页面中以居中的方式显示“您好!通过慕课网学习 jQuery 才是最佳的途径”字样。

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8"/>
    <title>第一个简单的jQuery程序</title>
    <style type="text/css">
        div{
            padding:8px 0px;
            font-size:12px;
            text-align:center;
            border:1px solid #888;
        }
    </style>
    <script src="http://libs.baidu.com/jquery/1.9.1/jquery.min.js"></script>
    <script type="text/javascript">
            $(document).ready(function() {
                    $("div").html("您好!通过慕课网学习jQuery才是最佳的途径。");
            });
    </script>
</head>
<body>
    <div></div>
</body>
</html>

代码分析:
$(document).ready 的作用是等页面的文档(document)中的节点都加载完毕后,再执行后续的代码,因为我们在执行代码的时候,可能会依赖页面的某一个元素,我们要确保这个元素真正的的被加载完毕后才能正确的使用。

(3)jQuery对象与DOM对象

对于才开始接触jQuery库的初学者,我们需要清楚认识一点:
jQuery对象与DOM对象是不一样的
可能一时半会分不清楚哪些是jQuery对象,哪些是DOM对象,下面重点介绍一下jQuery对象,以及两者相互间的转换。

通过一个简单的例子,简单区分下jQuery对象与DOM对象:
<p id=”imooc”></p>
我们要获取页面上这个id为imooc的p元素,然后给这个文本节点增加一段文字:“您好!通过慕课网学习jQuery才是最佳的途径”,并且让文字颜色变成红色。

  1. 普通处理,通过标准JavaScript处理:
var p = document.getElementById('imooc');
p.innerHTML = '您好!通过慕课网学习jQuery才是最佳的途径';
p.style.color = 'red';

通过原生DOM模型提供的document.getElementById(“imooc”)方法获取的DOM元素就是一个DOM对象,再通过innerHTML与style属性处理文本与颜色。

  1. jQuery的处理:
var $p = $('#imooc');
$p.html('您好!通过慕课网学习jQuery才是最佳的途径').css('color','red');

通过$('#imooc')方法会得到一个$p的jQuery对象,$p是一个类数组对象。这个对象里面包含了DOM对象的信息,然后封装了很多操作方法,调用自己的方法html与css,得到的效果与标准的JavaScript处理结果是一致的。

通过标准的JavaScript操作DOM与jQuyer操作DOM的对比,我们不难发现:
(1) 通过jQuery方法包装后的对象,是一个类数组对象。它与DOM对象完全不同,唯一相似的是它们都能操作DOM。
(2) 通过jQuery处理DOM的操作,可以让开发者更专注业务逻辑的开发,而不需要我们具体知道哪个DOM节点有那些方法,也不需要关心不同浏览器的兼容性问题,我们通过jQuery提供的API进行开发,代码也会更加精短。

(4)jQuery对象转化成DOM对象

jQuery库本质上还是JavaScript代码,它只是对JavaScript语言进行包装处理,为的是提供更好更方便快捷的DOM处理与开发中经常使用的功能。我们使用jQuery的同时也能混合JavaScript原生代码一起使用。在很多场景中,我们需要jQuery与DOM能够相互的转换,它们都是可以操作的DOM元素,jQuery是一个类数组对象,而DOM对象就是一个单独的DOM元素。

如何把jQuery对象转成DOM对象?

  1. 利用数组下标的方式读取到jQuery中的DOM对象
  • HTML代码
<div>元素一</div>
<div>元素二</div>
<div>元素三</div>
  • JavaScript代码
var $div = $('div') //jQuery对象
var div = $div[0] //转化成DOM对象
div.style.color = 'red' //操作dom对象的属性

用jQuery找到所有的div元素(3个),因为jQuery对象也是一个数组结构,可以通过数组下标索引找到第一个div元素,通过返回的div对象,调用它的style属性修改第一个div元素的颜色。这里需要注意的一点是,数组的索引是从0开始的,也就是第一个元素下标是0

  1. 通过jQuery自带的get()方法
    jQuery对象自身提供一个.get()方法允许我们直接访问jQuery对象中相关的DOM节点,get方法中提供一个元素的索引:
var $div = $('div') //jQuery对象
var div = $div.get(0) //通过get方法,转化成DOM对象
div.style.color = 'red' //操作dom对象的属性

其实我们翻开源码,看看就知道了,get方法就是利用的第一种方式处理的,只是包装成一个get让开发者更直接方便的使用。

(5)DOM对象转化成jQuery对象

相比较jQuery转化成DOM,开发中更多的情况是把一个dom对象加工成jQuery对象。$(参数)是一个多功能的方法,通过传递不同的参数而产生不同的作用。

如果传递给$(DOM)函数的参数是一个DOM对象,jQuery方法会把这个DOM对象给包装成一个新的jQuery对象
通过$(dom)方法将普通的dom对象加工成jQuery对象之后,我们就可以调用jQuery的方法了

  • HTML代码
<div>元素一</div>
<div>元素二</div>
<div>元素三</div>
  • JavaScript代码
var div = document.getElementsByTagName('div'); //dom对象
var $div = $(div); //jQuery对象
var $first = $div.first(); //找到第一个div元素
$first.css('color', 'red'); //给第一个元素设置颜色

通过getElementsByTagName获取到所有div节点的元素,结果是一个dom合集对象,不过这个对象是一个数组合集(3个div元素)。通过$(div)方法转化成jQuery对象,通过调用jQuery对象中的first与css方法查找第一个元素并且改变其颜色。

第2章 jQuery选择器

一、id选择器

页面的任何操作都需要节点的支撑,开发者如何快速高效的找到指定的节点也是前端开发中的一个重点。jQuery提供了一系列的选择器帮助开发者达到这一目的,让开发者可以更少的处理复杂选择过程与性能优化,更多专注业务逻辑的编写。
jQuery几乎支持主流的css1~css3选择器的写法,我们从最简单的也是最常用的开始学起
id选择器:一个用来查找的ID,即元素的id属性 $( "#id" )
id选择器也是基本的选择器,jQuery内部使用JavaScript函数document.getElementById()来处理ID的获取。原生语法的支持总是非常高效的,所以在操作DOM的获取上,如果能采用id的话尽然考虑用这个选择器

值得注意:
id是唯一的,每个id值在一个页面中只能使用一次。如果多个元素分配了相同的id,将只匹配该id选择集合的第一个DOM元素。但这种行为不应该发生;有超过一个元素的页面使用相同的id是无效的

二、类选择器

类选择器,顾名思义,通过class样式类名来获取节点
描述:$( ".class" )
类选择器,相对id选择器来说,效率相对会低一点,但是优势就是可以多选

同样的jQuery在实现上,对于类选择器,如果浏览器支持,jQuery使用JavaScript的原生getElementsByClassName()函数来实现的

jQuery除了选择上的简单,而且没有再次使用循环处理
不难想到$(".imooc").css()方法内部肯定是带了一个隐式的循环处理,所以使用jQuery选择节点,不仅仅只是选择上的简单,同时还增加很多关联的便利操作,后续我们还会慢慢的学到其他的优势。

三、元素选择器

元素选择器:根据给定(html)标记名称选择所有的元素
描述:$( "element" )
搜索指定元素标签名的所有节点,这个是一个合集的操作。同样的也有原生方法getElementsByTagName()函数支持

第一组:通过getElementsByTagName方法得到页面所有的<div>元素
var divs = document.getElementsByTagName('div');
divs是dom合集对象,通过循环给每一个合集中的<div>元素赋予新的boder样式
第二组:同样的效果,$("p")选取所有的<p>元素,通过css方法直接赋予样式

四、全选择器(*选择器)

在CSS中,经常会在第一行写下这样一段样式
* {padding: 0; margin: 0;}
通配符*意味着给所有的元素设置默认的边距。jQuery中我们也可以通过传递*选择器来选中文档页面中的元素
描述:$( "*" )
抛开jQuery,如果要获取文档中所有的元素,通过document.getElementsByTagName()中传递"*"同样可以获取到

不难发现,id、class、tag都可以通过原生的方法获取到对应的节点,但是我们还需要考虑一个兼容性的问题。比如:

  1. IE会将注释节点实现为元素,所以在IE中调用getElementsByTagName里面会包含注释节点,这个通常是不应该的
  2. getElementById的参数在IE8及较低的版本不区分大小写
  3. IE7及较低的版本中,表单元素中,如果表单A的name属性名用了另一个元素B的ID名并且A在B之前,那么getElementById会选中A
  4. IE8及较低的版本,浏览器不支持getElementsByClassName

看到了吧,作为一名合格的前端不是那么简单的,就一个基本的选择器上面都需要做这么多兼容,幸好有jQuery的出现,让我们省了很多功夫。

五、层级选择器

文档中的所有的节点之间都是有这样或者那样的关系。我们可以把节点之间的关系可以用传统的家族关系来描述,可以把文档树当作一个家谱,那么节点与节点直接就会存在父子,兄弟,祖孙的关系了。

选择器中的层级选择器就是用来处理这种关系:
子元素、 后代元素 、兄弟元素、 相邻元素

通过一个列表,对比层级选择器的区别


仔细观察层级选择器之间还是有很多相似与不同点

  1. 层级选择器都有一个参考节点
  2. 后代选择器包含子选择器的选择的内容
  3. 一般兄弟选择器包含相邻兄弟选择的内容
  4. 相邻兄弟选择器和一般兄弟选择器所选择到的元素,必须在同一个父元素下

六、筛选选择器

很多时候我们不能直接通过基本选择器与层级选择器找到我们想要的元素,为此jQuery提供了一系列的筛选选择器用来更快捷的找到所需的DOM元素。筛选选择器很多都不是CSS的规范,而是jQuery自己为了开发者的便利延展出来的选择器

筛选选择器的用法与CSS中的伪元素相似,选择器用冒号“:”开头,通过一个列表,看看基本筛选器的描述:


注意事项:
1.:eq(), :lt(), :gt(), :even, :odd 用来筛选他们前面的匹配表达式的集合元素,根据之前匹配的元素在进一步筛选,注意jQuery合集都是从0开始索引

  1. gt是一个段落筛选,从指定索引的下一个开始,gt(1) 实际从2开始

七、内容筛选选择器

基本筛选选择器针对的都是元素DOM节点,如果我们要通过内容来过滤,jQuery也提供了一组内容筛选选择器,当然其规则也会体现在它所包含的子元素或者文本内容上

内容过滤器描述如下表:



注意事项:

  1. :contains:has都有查找的意思,但是contains查找包含“指定文本”的元素,has查找包含“指定元素”的元素
  2. 如果:contains匹配的文本包含在元素的子元素中,同样认为是符合条件的。
  3. :parent:empty是相反的,两者所涉及的子元素,包括文本节点

八、可见性筛选选择器

元素有显示状态与隐藏状态,jQuery根据元素的状态扩展了可见性筛选选择器:visible与:hidden

描述如下:


这2个选择器都是 jQuery 延伸出来的,看起来比较简单,但是元素可见性依赖于适用的样式
:hidden选择器,不仅仅包含样式是display="none"的元素,还包括隐藏表单、visibility等等

我们有几种方式可以隐藏一个元素:

  1. CSS display的值是none。
  2. type="hidden"的表单元素。
  3. 宽度和高度都显式设置为0。
  4. 一个祖先元素是隐藏的,该元素是不会在页面上显示
  5. CSS visibility的值是hidden
  6. CSS opacity的指是0

如果元素中占据文档中一定的空间,元素被认为是可见的。
可见元素的宽度或高度,是大于零。
元素的visibility: hidden 或 opacity: 0被认为是可见的,因为他们仍然占用空间布局。

不在文档中的元素是被认为是不可见的,如果当他们被插入到文档中,jQuery没有办法知道他们是否是可见的,因为元素可见性依赖于适用的样式

九、属性筛选选择器

属性选择器让你可以基于属性来定位一个元素。可以只指定该元素的某个属性,这样所有使用该属性而不管它的值,这个元素都将被定位,也可以更加明确并定位在这些属性上使用特定值的元素,这就是属性选择器展示它们的威力的地方。

描述如下:


浏览器支持:

  • [att=val]、[att]、[att|=val]、[att~=val] 属于CSS 2.1规范
  • [ns|attr]、[att^=val]、[att*=val]、[att$=val] 属于CSS3规范
  • [name!="value"] 属于jQuery 扩展的选择器

CSS选择器无论CSS2.1版本还是CSS3版本,IE7和IE8都支持,webkit、Gecko核心及Opera也都支持,只有IE6以下浏览器才不支持

在这么多属性选择器中[attr="value"][attr*="value"]是最实用的

  1. [attr="value"]能帮我们定位不同类型的元素,特别是表单form元素的操作,比如说input[type="text"],input[type="checkbox"]等
  2. [attr*="value"]能在网站中帮助我们匹配不同类型的文件

十、子元素筛选选择器

子元素筛选选择器不常使用,其筛选规则比起其它的选择器稍微要复杂点
子元素筛选选择器描述表:


注意事项:

  1. :first只匹配一个单独的元素,但是:first-child选择器可以匹配多个:即为每个父级元素匹配第一个子元素。这相当于:nth-child(1)
  2. :last 只匹配一个单独的元素, :last-child 选择器可以匹配多个元素:即,为每个父级元素匹配最后一个子元素
  3. 如果子元素只有一个的话,:first-child与:last-child是同一个
  4. :only-child匹配某个元素是父元素中唯一的子元素,就是说当前子元素是父元素中唯一的元素,则匹配
  5. jQuery实现:nth-child(n)是严格来自CSS规范,所以n值是“索引”,也就是说,从1开始计数,:nth-child(index)从1开始的,而eq(index)是从0开始的
  6. nth-child(n) 与 :nth-last-child(n) 的区别前者是从前往后计算,后者从后往前计算

十一、表单元素选择器

无论是提交还是传递数据,表单元素在动态交互页面的作用是非常重要的。jQuery中专门加入了表单选择器,从而能够极其方便地获取到某个类型的表单元素
表单选择器的具体方法描述:


注意事项:
除了input筛选选择器,几乎每个表单类别筛选器都对应一个input元素的type值。大部分表单类别筛选器可以使用属性筛选器替换。比如 $(':password') == $('[type=password]')

十二、表单对象属性筛选选择器

除了表单元素选择器外,表单对象属性筛选选择器也是专门针对表单元素的选择器,可以附加在其他选择器的后面,主要功能是对所选择的表单元素进行筛选
表单筛选选择器的描述:

注意事项:

  1. 选择器适用于复选框和单选框,对于下拉框元素, 使用 :selected 选择器
  2. 在某些浏览器中,选择器:checked可能会错误选取到<option>元素,所以保险起见换用选择器input:checked,确保只会选取<input>元素

十三、特殊选择器this

相信很多刚接触jQuery的人,很多都会对$(this)和this的区别模糊不清,那么这两者有什么区别呢?

  1. this是JavaScript中的关键字,指的是当前的上下文对象,简单的说就是方法/属性的所有者
    下面例子中,imooc是一个对象,拥有name属性与getName方法,在getName中this指向了所属的对象imooc
var imooc = {
    name:"慕课网",
    getName:function(){
        //this,就是imooc对象
        return this.name;
    }
}
imooc.getName(); //慕课网

当然在JavaScript中this是动态的,也就是说这个上下文对象都是可以被动态改变的(可以通过call,apply等方法)

  1. 同样的在DOM中this就是指向了这个html元素对象,因为this就是DOM元素本身的一个引用
    假如给页面一个P元素绑定一个事件:
p.addEventListener('click',function(){
    //this === p
    //以下两者的修改都是等价的
    this.style.color = "red";
    p.style.color = "red";
},false);

通过addEventListener绑定的事件回调中,this指向的是当前的dom对象,所以再次修改这样对象的样式,只需要通过this获取到引用即可
this.style.color = "red"
但是这样的操作其实还是很不方便的,这里面就要涉及一大堆的样式兼容,如果通过jQuery处理就会简单多了,我们只需要把this加工成jQuery对象

  1. 换成jQuery的做法:
$('p').click(function(){
    //把p元素转化成jQuery的对象
    var $this= $(this) 
    $this.css('color','red')
})

通过把$()方法传入当前的元素对象的引用this,把这个this加工成jQuery对象,我们就可以用jQuery提供的快捷方法直接处理样式了

总体:

  1. this,表示当前的上下文对象是一个html对象,可以调用html对象所拥有的属性和方法。
  2. $(this),代表的上下文对象是一个jquery的上下文对象,可以调用jQuery的方法和属性值。

第3章 jQuery的属性与样式

一、.attr().removeAttr()

每个元素都有一个或者多个特性,这些特性的用途就是给出相应元素或者其内容的附加信息。如:在img元素中,src就是元素的特性,用来标记图片的地址。

操作特性的DOM方法主要有3个,getAttribute方法、setAttribute方法和removeAttribute方法,就算如此在实际操作中还是会存在很多问题,这里先不说。而在jQuery中用一个attr()与removeAttr()就可以全部搞定了,包括兼容问题

jQuery中用attr()方法来获取和设置元素属性,attr是attribute(属性)的缩写,在jQuery DOM操作中会经常用到attr()

(1)attr()有4个表达式

  1. attr(传入属性名):获取属性的值
  2. attr(属性名, 属性值):设置属性的值
  3. attr(属性名,函数值):设置属性的函数值
  4. attr(attributes):给指定元素设置多个属性值,即:{属性名一: “属性值一” , 属性名二: “属性值二” , … … }

(2)removeAttr()删除方法
.removeAttr( attributeName ) : 为匹配的元素集合中的每个元素中移除一个属性(attribute)

优点:
attr、removeAttr都是jQuery为了属性操作封装的,直接在一个 jQuery 对象上调用该方法,很容易对属性进行操作,也不需要去特意的理解浏览器的属性名不同的问题

注意的问题:
dom中有个概念的区分:Attribute和Property翻译出来都是“属性”,《js高级程序设计》书中翻译为“特性”和“属性”。简单理解:

  1. Attribute就是dom节点自带的属性
    例如:html中常用的id、class、title、align等:
    <div id="immooc" title="慕课网"></div>
  2. Property是这个DOM元素作为对象,
    其附加的内容,例如,tagName, nodeName, nodeType,, defaultChecked, 和 defaultSelected 使用.prop()方法进行取值或赋值等

获取Attribute就需要用attr,获取Property就需要用prop

二、html()及.text()

读取、修改元素的html结构或者元素的文本内容是常见的DOM操作,jQuery针对这样的处理提供了2个便捷的方法.html()与.text()

(1).html()方法

获取集合中第一个匹配元素的HTML内容 或 设置每一个匹配元素的html内容,具体有3种用法:

  1. .html() 不传入值,就是获取集合中第一个匹配元素的HTML内容
  2. .html( htmlString ) 设置每一个匹配元素的html内容
  3. .html( function(index, oldhtml) ) 用来返回设置HTML内容的一个函数

注意事项:
.html()方法内部使用的是DOM的innerHTML属性来处理的,所以在设置与获取上需要注意的一个最重要的问题,这个操作是针对整个HTML内容(不仅仅只是文本内容)

(2).text()方法

得到匹配元素集合中每个元素的文本内容结合,包括他们的后代,或设置匹配元素集合中每个元素的文本内容为指定的文本内容。具体有3种用法:

  1. .text() 得到匹配元素集合中每个元素的合并文本,包括他们的后代
  2. .text( textString ) 用于设置匹配元素内容的文本
  3. .text( function(index, text) ) 用来返回设置文本内容的一个函数

注意事项:
.text()结果返回一个字符串,包含所有匹配元素的合并文本

(3).html与.text的异同:
  1. .html与.text的方法操作是一样,只是在具体针对处理对象不同
  2. .html处理的是元素内容,.text处理的是文本内容
  3. .html只能使用在HTML文档中,.text 在XML 和 HTML 文档中都能使用
  4. 如果处理的对象只有一个子文本节点,那么html处理的结果与text是一样的
  5. 火狐不支持innerText属性,用了类似的textContent属性,.text()方法综合了2个属性的支持,所以可以兼容所有浏览器
 <h3>.html()与.text()</h3>
    <div class="left first-div">
        <div class="div">
            <a>:first-child</a>
            <a>第二个元素</a>
            <a>:last-child</a>
        </div>  
        <div class="div">
            <a>:first-child</a>
            <a>第二个元素</a>
            <a>:last-child</a>
        </div>
    </div>
    
    <h4>显示通过html方法获取到的内容</h4>
    <p></p>

    <h4>显示通过text方法获取到的内容</h4>
    <p></p>
    <script type="text/javascript">
        //显示出html方法获取到的内容
        //.html()是整个html文档结构
        $('p:first').text( $(".first-div").html() ) 
    </script>
    <script type="text/javascript">
        //显示出text方法获取到的内容
        //.text()是文本内容的合集
        $('p:last').text( $(".first-div").text() ) 
    </script>

三、.val()

jQuery中有一个.val()方法主要是用于处理表单元素的值,比如 input, select 和 textarea。

(1).val()方法
  1. .val()无参数,获取匹配的元素集合中第一个元素的当前值
  2. .val( value ),设置匹配的元素集合中每个元素的值
  3. .val( function ) ,一个用来返回设置值的函数
(2) 注意事项:
  1. 通过.val()处理select元素, 当没有选择项被选中,它返回null
  2. .val()方法多用来设置表单的字段的值
  3. 如果select元素有multiple(多选)属性,并且至少一个选择项被选中, .val()方法返回一个数组,这个数组包含每个选中选择项的值
(3).html(),.text()和.val()的差异总结:
  1. .html(),.text(),.val()三种方法都是用来读取选定元素的内容;只不过.html()是用来读取元素的html内容(包括html标签).text()用来读取元素的纯文本内容,包括其后代元素.val()是用来读取表单元素的"value"值。其中.html()和.text()方法不能使用在表单元素上,而.val()只能使用在表单元素上;另外.html()方法使用在多个元素上时,只读取第一个元素;.val()方法和.html()相同,如果其应用在多个元素上时,只能读取第一个表单元素的"value"值,但是.text()和他们不一样,如果.text()应用在多个元素上时,将会读取所有选中元素的文本内容。
  2. .html(htmlString),.text(textString)和.val(value)三种方法都是用来替换选中元素的内容,如果三个方法同时运用在多个元素上时,那么将会替换所有选中元素的内容。
  3. .html(),.text(),.val()都可以使用回调函数的返回值来动态的改变多个元素的内容

四、增加样式.addClass()

通过动态改变类名(class),可以让其修改元素呈现出不同的效果。在HTML结构中,多个class以空格分隔,当一个节点(或称为一个标签)含有多个class时,DOM元素响应的className属性获取的不是class名称的数组,而是一个含有空格的字符串,这就使得多class操作变得很麻烦。同样的jQuery开发者也考虑到这种情况,增加了一个.addClass()方法,用于动态增加class类名

.addClass( className )方法

  1. .addClass( className ) : 为每个匹配元素所要增加的一个或多个样式名
  2. .addClass( function(index, currentClass) ) : 这个函数返回一个或更多用空格隔开的要增加的样式名

注意事项:
.addClass()方法不会替换一个样式类名。它只是简单的添加一个样式类名到元素上
简单的描述下:在p元素增加一个newClass的样式

<p class="orgClass">
$("p").addClass("newClass")

那么p元素的class实际上是 class="orgClass newClass"样式只会在原本的类上继续增加,通过空格分隔

五、删除样式.removeClass()

jQuery通过.addClass()方法可以很便捷的增加样式。如果需要样式之间的切换,同样jQuery提供了一个很方便的.removeClass(),它的作用是从匹配的元素中删除全部或者指定的class

.removeClass( )方法

  1. .removeClass( [className ] ):每个匹配元素移除的一个或多个用空格隔开的样式名
  2. .removeClass( function(index, class) ) : 一个函数,返回一个或多个将要被移除的样式名

注意事项
如果一个样式类名作为一个参数,只有这样式类会被从匹配的元素集合中删除 。 如果没有样式名作为参数,那么所有的样式类将被移除

六、切换样式.toggleClass()

在做某些效果的时候,可能会针对同一节点的某一个样式不断的切换,也就是addClass与removeClass的互斥切换,比如隔行换色效果

jQuery提供一个toggleClass方法用于简化这种互斥的逻辑,通过toggleClass方法动态添加删除Class,一次执行相当于addClass,再次执行相当于removeClass

.toggleClass( )方法:在匹配的元素集合中的每个元素上添加或删除一个或多个样式类,取决于这个样式类是否存在或值切换属性。即:如果存在(不存在)就删除(添加)一个类

  1. .toggleClass( className ):在匹配的元素集合中的每个元素上用来切换的一个或多个(用空格隔开)样式类名
  2. .toggleClass( className, switch ):一个布尔值,用于判断样式是否应该被添加或移除
  3. .toggleClass( [switch ] ):一个用来判断样式类添加还是移除的 布尔值
  4. .toggleClass( function(index, class, switch) [, switch ] ):用来返回在匹配的元素集合中的每个元素上用来切换的样式类名的一个函数。接收元素的索引位置和元素旧的样式类作为参数

注意事项:

  1. toggleClass是一个互斥的逻辑,也就是通过判断对应的元素上是否存在指定的Class名,如果有就删除,如果没有就增加
  2. toggleClass会保留原有的Class名后新增,通过空格隔开

七、样式操作.css()

通过JavaScript获取dom元素上的style属性,我们可以动态的给元素赋予样式属性。在jQuery中我们要动态的修改style属性我们只要使用css()方法就可以实现了

.css() 方法:获取元素样式属性的计算值或者设置元素的CSS属性

获取:
  1. .css( propertyName ) :获取匹配元素集合中的第一个元素的样式属性的计算值
  2. .css( propertyNames ):传递一组数组,返回一个对象结果
设置:
  1. .css(propertyName, value ):设置CSS
  2. .css( propertyName, function ):可以传入一个回调函数,返回取到对应的值进行处理
  3. .css( properties ):可以传一个对象,同时设置多个样式
注意事项:
  1. 浏览器属性获取方式不同,在获取某些值的时候都jQuery采用统一的处理,比如颜色采用RBG,尺寸采用px
  2. .css()方法支持驼峰写法与大小写混搭的写法,内部做了容错的处理
  3. 当一个数只被作为值(value)的时候, jQuery会将其转换为一个字符串,并添在字符串的结尾处添加px,例如 .css("width",50}) 与 .css("width","50px"})一样

八、.css()与.addClass()设置样式的区别

对于样式的设置,我们学了addClass与css方法,那么两者之间有什么区别?

(1)可维护性:

.addClass()的本质是通过定义个class类的样式规则,给元素添加一个或多个类。css方法是通过JavaScript大量代码进行改变元素的样式

通过.addClass()我们可以批量的给相同的元素设置统一规则,变动起来比较方便,可以统一修改删除。如果通过.css()方法就需要指定每一个元素是一一的修改,日后维护也要一一的修改,比较麻烦

(2)灵活性:

通过.css()方式可以很容易动态的去改变一个样式的属性,不需要在去繁琐的定义个class类的规则。一般来说在不确定开始布局规则,通过动态生成的HTML代码结构中,都是通过.css()方法处理的

(3)样式值:

.addClass()本质只是针对class的类的增加删除,不能获取到指定样式的属性的值,.css()可以获取到指定的样式值。

(4)样式的优先级:

css的样式是有优先级的,当外部样式、内部样式和内联样式同一样式规则同时应用于同一个元素的时候,优先级如下:
外部样式 < 内部样式 < 内联样式

  1. .addClass()方法是通过增加class名的方式,那么这个样式是在外部文件或者内部样式中先定义好的,等到需要的时候在附加到元素上
  2. 通过.css()方法处理的是内联样式,直接通过元素的style属性附加到元素上的

通过.css方法设置的样式属性优先级要高于.addClass方法

(5)总结:

.addClass与.css方法各有利弊,一般是静态的结构,都确定了布局的规则,可以用addClass的方法,增加统一的类规则
如果是动态的HTML结构,在不确定规则,或者经常变化的情况下,一般多考虑.css()方式

九、元素的数据存储.data()

html5 dataset是新的HTML5标准,允许你在普通的元素标签里嵌入类似data-*的属性,来实现一些简单数据的存取。它的数量不受限制,并且也能由JavaScript动态修改,也支持CSS选择器进行样式设置。这使得data属性特别灵活,也非常强大。有了这样的属性我们能够更加有序直观的进行数据预设或存储。那么在不支持HTML5标准的浏览器中,我们如何实现数据存取? jQuery就提供了一个.data()的方法来处理这个问题

使用jQuery初学者一般不是很关心data方式,这个方法是jquery内部预用的,可以用来做性能优化,比如sizzle选择中可以用来缓存部分结果集等等。当然这个也是非常重要的一个API了,常常用于我们存放临时的一些数据,因为它是直接跟DOM元素对象绑定在一起的

jQuery提供的存储接口

jQuery.data( element, key, value )   //静态接口,存数据
jQuery.data( element, key )  //静态接口,取数据   
.data( key, value ) //实例接口,存数据
.data( key ) //实例接口,存数据

2个方法在使用上存取都是同一个接口,传递元素,键值数据。在jQuery的官方文档中,建议用.data()方法来代替。

我们把DOM可以看作一个对象,那么我们往对象上是可以存在基本类型,引用类型的数据的,但是这里会引发一个问题,可能会存在循环引用的内存泄漏风险

通过jQuery提供的数据接口,就很好的处理了这个问题了,我们不需要关心它底层是如何实现,只需要按照对应的data方法使用就行了

同样的也提供2个对应的删除接口,使用上与data方法其实是一致的,只不过是一个是增加一个是删除罢了

jQuery.removeData( element [, name ] )
.removeData( [name ] )

二、DOM篇

第一章 DOM节点的创建

(1)DOM创建节点及节点属性

创建流程大体如下:
  1. 创建节点(常见的:元素、属性和文本)
  2. 添加节点的一些属性
  3. 加入到文档中
流程中涉及的一点方法:
  1. 创建元素:document.createElement
  2. 设置属性:setAttribute
  3. 添加文本:innerHTML
  4. 加入文档:appendChild
<body>
    <h2>动态创建元素节点</h2>
    <div class="left">
        <div class="aaron">点击body区域会动态创建元素节点</div>
    </div>
    <script type="text/javascript">
        var body = document.querySelector('body');

        document.addEventListener('click',function(){
            
            //创建2个div元素
            var rightdiv = document.createElement('div')
            var rightaaron = document.createElement("div");

            //给2个div设置不同的属性
            rightdiv.setAttribute('class', 'right')
            rightaaron.className = 'aaron'
            rightaaron.innerHTML = "动态创建DIV元素节点";

            //2个div合并成包含关系
            rightdiv.appendChild(rightaaron)
            
            //绘制到页面body
            body.appendChild(rightdiv)
        },false)
    </script>
</body>
问题:
  1. 每一个元素节点都必须单独创建
  2. 节点是属性需要单独设置,而且设置的接口不是很统一
  3. 添加到指定的元素位置不灵活
  4. 最后还有一个最重要的:浏览器兼容问题处理

(2)jQuery节点创建与属性的处理

通过JavaScript原生接口创建节点,在处理上是非常复杂与繁琐的。我们可以通过使用jQuery来简化了这个过程

1.创建元素节点:

常见方式就是直接把这个节点的结构给通过HTML标记字符串描述出来,通过$()函数处理,$("html结构")
$("<div></div>")

2.创建为本节点:

与创建元素节点类似,可以直接把文本内容一并描述
$("<div>我是文本节点</div>")

3.创建为属性节点:

与创建元素节点同样的方式
$("<div id='test' class='aaron'>我是文本节点</div>")

改进后:
<body>
    <h2>动态创建元素节点</h2>
    <button>点击通过jQuery动态创建元素节点</button>
    <script type="text/javascript">
    var $body = $('body');
    $body.on('click', function() {
        //通过jQuery生成div元素节点
        var div = $("<div class='right'><div class='aaron'>动态创建DIV元素节点</div></div>")
        $body.append(div)
    })
</body>

第二章 DOM节点的插入

(1)DOM内部插入append()与appendTo()

动态创建的元素是不够的,它只是临时存放在内存中,最终我们需要放到页面文档并呈现出来。那么问题来了,怎么放到文档上?
这里就涉及到一个位置关系,常见的就是把这个新创建的元素,当作页面某一个元素的子元素放到其内部。针对这样的处理,jQuery就定义2个操作的方法

  1. append:这个操作与对指定的元素执行原生的appendChild方法,将它们添加到文档中的情况类似。
  2. appendTo:实际上,使用这个方法是颠倒了常规的$(A).append(B)的操作,即不是把B追加到A中,而是把A追加到B中。
总结:

.append()和.appendTo()两种方法功能相同,主要的不同是语法——内容和目标的位置不同

  1. append()前面是被插入的对象,后面是要在对象内插入的元素内容
  2. appendTo()前面是要插入的元素内容,而后面是被插入的对象
<body>
    <h2>通过append与appendTo添加元素</h2>
    <button id="bt1">点击通过jQuery的append添加元素</button>
    <button id="bt2">点击通过jQuery的appendTo添加元素</button>
    <div class="content"></div>

    <script type="text/javascript">
        $("#bt1").on('click', function() {
            //.append(), 内容在方法的后面,
            //参数是将要插入的内容。
            $(".content").append('<div class="append">通过append方法添加的元素</div>')
        })

    </script>

    <script type="text/javascript">

        $("#bt2").on('click', function() {
            //.appendTo()刚好相反,内容在方法前面,
            //无论是一个选择器表达式 或创建作为标记上的标记
            //它都将被插入到目标容器的末尾。
            $('<div class="appendTo">通过appendTo方法添加的元素</div>').appendTo($(".content"))
        })
    </script>
</body>

(2)DOM外部插入after()与before()

节点与节点之前有各种关系,除了父子,祖辈关系,还可以是兄弟关系。之前我们在处理节点插入的时候,接触到了内部插入的几个方法,这节我们开始讲外部插入的处理,也就是兄弟之间的关系处理,这里jQuery引入了2个方法,可以用来在匹配的元素前后插入内容

选择器的描述:

  • before与after都是用来对相对选中元素外部增加相邻的兄弟节点
  • 2个方法都是都可以接收HTML字符串,DOM 元素,元素数组,或者jQuery对象,用来插入到集合中每个匹配元素的前面或者后面
  • 2个方法都支持多个参数传递after(div1,div2,....)
注意点:
  • after向元素的后边添加html代码,如果元素后面有元素了,那将后面的元素后移,然后将html代码插入
  • before向元素的前边添加html代码,如果元素前面有元素了,那将前面的元素前移,然后将html代码插
<body>
    <h2>通过before与after添加元素</h2>
    <button id="bt1">点击通过jQuery的before添加元素</button>
    <button id="bt2">点击通过jQuery的after添加元素</button>
    <div class="aaron">
        <p class="test1">测试before</p>
    </div>
    <div class="aaron">
        <p class="test2">测试after</p>
    </div>
    <script type="text/javascript">
    $("#bt1").on('click', function() {
        //在匹配test1元素集合中的每个元素前面插入p元素
        $(".test1").before('<p style="color:red">before,在匹配元素之前增加</p>', '<p style="color:red">多参数</p>')
    })
    </script>
    <script type="text/javascript">
    $("#bt2").on('click', function() {
        //在匹配test1元素集合中的每个元素后面插入p元素
        $(".test2").after('<p style="color:blue">after,在匹配元素之后增加</p>', '<p style="color:blue">多参数</p>')

    })
    </script>
</body>

(3)DOM内部插入prepend()与prependTo()

在元素内部进行操作的方法,除了在被选元素的结尾(仍然在内部)通过append与appendTo插入指定内容外,相应的还可以在被选元素之前插入,jQuery提供的方法是prepend与prependTo
选择器的描述:


通过右边代码可以看到prepend与prependTo的使用及区别:

  • .prepend()方法将指定元素插入到匹配元素里面作为它的第一个子元素 (如果要作为最后一个子元素插入用.append()).
  • .prepend()和.prependTo()实现同样的功能,主要的不同是语法,插入的内容和目标的位置不同
  • 对于.prepend() 而言,选择器表达式写在方法的前面,作为待插入内容的容器,将要被插入的内容作为方法的参数
  • 而.prependTo() 正好相反,将要被插入的内容写在方法的前面,可以是选择器表达式或动态创建的标记,待插入内容的容器作为参数。

这里总结下内部操作四个方法的区别:

  • append()向每个匹配的元素内部追加内容
  • prepend()向每个匹配的元素内部前置内容
  • appendTo()把所有匹配的元素追加到另一个指定元素的集合中
  • prependTo()把所有匹配的元素前置到另一个指定的元素集合中
<body>
    <h2>通过prepend与prependTo添加元素</h2>
    <button id="bt1">点击通过jQuery的prepend添加元素</button>
    <button id="bt2">点击通过jQuery的prependTo添加元素</button>
    <div class="aaron1">
        <p>测试prepend</p>
    </div>
    <div class="aaron2">
        <p>测试prependTo</p>
    </div>
    <script type="text/javascript">
    $("#bt1").on('click', function() {
        //找到class="aaron1"的div节点
        //然后通过prepend在内部的首位置添加一个新的p节点
        $('.aaron1')
            .prepend('<p>prepend增加的p元素</p>')
    })
    </script>
    <script type="text/javascript">
    $("#bt2").on('click', function() {
        //找到class="aaron2"的div节点
        //然后通过prependTo内部的首位置添加一个新的p节点
        $('<p>prependTo增加的p元素</p>')
            .prependTo($('.aaron2'))
    })
    </script>
</body>

(4)DOM外部插入insertAfter()与insertBefore()

与内部插入处理一样,jQuery由于内容目标的位置不同,增加了2个新的方法insertAfter与insertBefore

  • .before()和.insertBefore()实现同样的功能。主要的区别是语法——内容和目标的位置。 对于before()选择表达式在函数前面,内容作为参数,而.insertBefore()刚好相反,内容在方法前面,它将被放在参数里元素的前面
  • .after()和.insertAfter() 实现同样的功能。主要的不同是语法——特别是(插入)内容和目标的位置。 对于after()选择表达式在函数的前面,参数是将要插入的内容。对于 .insertAfter(), 刚好相反,内容在方法前面,它将被放在参数里元素的后面
    before、after与insertBefore。insertAfter的除了目标与位置的不同外,后面的不支持多参数处理
注意事项:
  • insertAfter将JQuery封装好的元素插入到指定元素的后面,如果元素后面有元素了,那将后面的元素后移,然后将JQuery对象插入;
  • insertBefore将JQuery封装好的元素插入到指定元素的前面,如果元素前面有元素了,那将前面的元素前移,然后将JQuery对象插入;
<body>
    <h2>通过insertBefore与insertAfter添加元素</h2>
    <button id="bt1">点击通过jQuery的insertBefore添加元素</button>
    <button id="bt2">点击通过jQuery的insertAfter添加元素</button>
    <div class="aaron">
        <p class="test1">测试insertBefore,不支持多参数</p>
    </div>
    <div class="aaron">
        <p class="test2">测试insertAfter,不支持多参数</p>
    </div>
    <script type="text/javascript">
    $("#bt1").on('click', function() {
        //在test1元素前后插入集合中每个匹配的元素
        //不支持多参数
        $('<p style="color:red">测试insertBefore方法增加</p>', '<p style="color:red">多参数</p>').insertBefore($(".test1"))
    })
    </script>
    <script type="text/javascript">
    $("#bt2").on('click', function() {
        //在test2元素前后插入集合中每个匹配的元素
        //不支持多参数
        $('<p style="color:red">测试insertAfter方法增加</p>', '<p style="color:red">多参数</p>').insertAfter($(".test2"))
    })
    </script>
</body>

第三章 DOM节点删除

(1)empty()的基本用法

empty 顾名思义,清空方法,但是与删除又有点不一样,因为它只移除了 指定元素中的所有子节点。这个方法不仅移除子元素(和其他后代元素),同样移除元素里的文本。因为元素里任何文本字符串都被看做是该元素的子节点。

请看下面的HTML:

<div class="hello"><p>慕课网</p></div>
//通过empty处理
$('.hello').empty()

如果我们通过empty方法移除里面div的所有元素,它会清空内部的html代码,本身的div元素没有被删除。

//结果:<p>慕课网</p>被移除
<div class="hello"></div>

(2)remove()的有参用法和无参用法

remove与empty一样,都是移除元素的方法,但是remove会将元素自身移除,同时也会移除元素内部的一切,包括绑定的事件及与该元素相关的jQuery数据。

例如一段节点,绑定点击事件

<div class="hello"><p>慕课网</p></div>
$('.hello').on("click",fn)

通过remove方法移除div及其内部所有元素,remove内部会自动操作事件销毁方法,所以使用起来非常简单

//通过remove处理
$('.hello').remove()
//结果:<div class="hello"><p>慕课网</p></div> 全部被移除
//节点不存在了,同时事件也会被销毁

为了防止"内存泄漏",前端开发者一定要注意,绑了多少事件,不用的时候一定要记得销毁

remove表达式参数:

remove比empty好用的地方就是可以传递一个选择器表达式用来过滤将被移除的匹配元素集合,可以选择性的删除指定的节点

<body>
    <h2>通过jQuery remove方法移除元素</h2>
    <div class="test1">
        <p>p元素1</p>
        <p>p元素2</p>
    </div>
    <div class="test2">
        <p>p元素3</p>
        <p>p元素4</p>
    </div>
    <button>通过点击jQuery的empty移除元素</button>
    <button>通过点击jQuery的empty移除指定元素</button>
    <script type="text/javascript">
    $("button:first").on('click', function() {
        //删除整个 class=test1的div节点
        $(".test1").remove()
    })

    $("button:last").on('click', function() {
        //找到所有p元素中,包含了3的元素
        //这个也是一个过滤器的处理
        $("p").remove(":contains('3')")
    })
    </script>
</body>

我们也可以通过类似于这样处理
$("p").filter(":contains('3')").remove()

(3)empty和remove区别

要用到移除指定元素的时候,jQuery提供了empty()与remove([expr])二个方法,两个都是删除元素,但是两者还是有区别

1. empty方法
  • 严格地讲,empty()方法并不是删除节点,而是清空节点,它能清空元素中的所有后代节点
  • empty不能删除自己本身这个节点
2. remove方法
  • 该节点与该节点所包含的所有后代节点将同时被删除
  • 提供传递一个筛选的表达式,删除指定合集中的元素

(4)保留数据的删除操作detach()

如果我们希望临时删除页面上的节点,但是又不希望节点上的数据与事件丢失,并且能在下一个时间段让这个删除的节点显示到页面,这时候就可以使用detach方法来处理

detach从字面上就很容易理解。让一个web元素托管。即从当前页面中移除该元素,但保留这个元素的内存模型对象。

jquery官方文档的解释:
  • 这个方法不会把匹配的元素从jQuery对象中删除,因而可以在将来再使用这些匹配的元素。与remove()不同的是,所有绑定的事件、附加的数据等都会保留下来。
  • $("div").detach()这一句会移除对象,仅仅是显示效果没有了。但是内存中还是存在的。当你append之后,又重新回到了文档流中。就又显示出来了。

当然这里要特别注意,detach方法是JQuery特有的,所以它只能处理通过JQuery的方法绑定的事件或者数据

<body>
    <p>P元素1,默认给绑定一个点击事件</p>
    <p>P元素2,默认给绑定一个点击事件</p>
    <button id="bt1">点击删除 p 元素</button>
    <button id="bt2">点击移动 p 元素</button>
    <script type="text/javascript">
    $('p').click(function(e) {
        alert(e.target.innerHTML)
    })
    var p;
    $("#bt1").click(function() {
        if (!$("p").length) return; //去重
        //通过detach方法删除元素
        //只是页面不可见,但是这个节点还是保存在内存中
        //数据与事件都不会丢失
        p = $("p").detach()
    });

    $("#bt2").click(function() {
        //把p元素在添加到页面中
        //事件还是存在
        $("body").append(p);
    });
    </script>
</body>

(5)detach()和remove()区别

1. remove:移除节点
  • 无参数,移除自身整个节点以及该节点的内部的所有节点,包括节点上事件与数据
  • 有参数,移除筛选出的节点以及该节点的内部的所有节点,包括节点上事件与数据
2. detach:移除节点
  • 移除的处理与remove一致
  • 与remove()不同的是,所有绑定的事件、附加的数据等都会保留下来
<body>
    <h3>给页面2个p元素节点绑定点击事件,点击后弹出自己本身的节点内容</h3>
    <p>元素p1,同时绑定点击事件</p>
    <p>元素p2,同时绑定点击事件</p>
    <h3>通过点击2个按钮后观察方法处理的区别</h3>
    <button>点击通过remove处理元素p1</button>
    <button>点击通过detach处理元素p2</button>
</body>
<script type="text/javascript">
    //给页面上2个p元素都绑定时间
    $('p').click(function(e) {
        alert(e.target.innerHTML)
    })

    $("button:first").click(function() {
        var p = $("p:first").remove();
        p.css('color','red').text('p1通过remove处理后,点击该元素,事件丢失')
        $("body").append(p);
    });

    $("button:last").click(function() {
        var p = $("p:first").detach();
        p.css('color','blue').text('p2通过detach处理后,点击该元素事件存在')
        $("body").append(p);
    });
</script>

来源1:慕课网_jQuery基础(一)—样式篇
来源2:慕课网_jQuery基础(二)—DOM篇

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 151,829评论 1 331
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 64,603评论 1 273
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 101,846评论 0 226
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 42,600评论 0 191
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 50,780评论 3 272
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 39,695评论 1 192
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,136评论 2 293
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 29,862评论 0 182
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 33,453评论 0 229
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 29,942评论 2 233
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,347评论 1 242
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 27,790评论 2 236
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,293评论 3 221
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 25,839评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,448评论 0 181
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 34,564评论 2 249
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 34,623评论 2 249

推荐阅读更多精彩内容