JS-DOM

有的没的

DOM就是把html视为一个层次结构(树形结构)的文档

文档(Document):一个页面就是一个文档,html或者xml文件,html主要用来展示数据,xml侧重于存储数据

html文件看做是一个文档,由于万物皆对象,所以把这个文档看成是一个对象,文档中的所有标签都可以看成是一个对象。

元素(Element):Html文档中的所有标签

页面中的每个标签都是一个元素,每个元素都可以看成是一个对象,标签可以嵌套,标签中有标签,元素中有元素。html页面中都有一个跟标签,html,它也称为根元素。

节点(Node):文档中的所有内容都可以称之为节点:标签、属性、文本。

根元素(root):文档中的第一个元素,html文档就是<html>,只有一个

文本节点

属性节点

dom可以做什么

1. 找对象(元素)

2. 设置元素属性

3. 设置元素样式

4. 动态创建和删除元素

5. 事件—触发响应

    --事件源(事件的触发者)

    --事件名称

    --事件响应程序

     一个栗子:

         点击操作:事件

        按钮:事件源

        点击:事件名称

         被点击了:触发了

        弹框了:响应

    html标签中的id属性中存储的值是唯一的,id属性就像是人的身份证号码一样,不能重复,他是页面中的唯一标识;

    var btObj = document.getElementById(‘id属性的值’);返回的是一个元素对象,他有很多的属性,可以通过’.属性’来获取属性;

    btObj.onclick = f2;(f2后面不要加括号)

innerText、textContent和innerHTML

设置标签中的文本内容,应该使用textContent属性,谷歌、火狐支持,IE8不支持;innerText属性,谷歌、火狐、IE8都支持,它是IE8的标准

获取标签中的文本内容,textContent属性,谷歌、火狐支持,IE8不支持(输出undefined);inertText属性,谷歌、火狐、IE8都支持

如果这个属性在浏览器中不支持,那么这个属性的类型是undefined

//设置任意标签中间的任意文本内容

  function  setTextContent (element , text){

  if(typeof(element.textContent) === undefined){

  element.innerText = text;

 }else {

  element.textContent = text;

 }

 }

  //获取任意标签中间的文本内容

  function  getTextContent (element){

  if(typeof(element.textContent) === undefined){

  return  element.innerText;

 }else {

  return  element.textContent;

 }

 }

    innerHTML也可以设置文本内容,并且任何浏览器都是支持的;而且它还可以设置html标签。同样,获取标签的时候,innerHTML也能获取到标签。

总结:

    想要设置标签内容,就用innerHTML,如果想要设置文本内容,innerText或者textContent或者innerHTML,推荐使用innerHTML,没有兼容性问题。

    获取的时候,innerText可以获取标签中的文本内容,但是如果标签中还有标签,那么最里面的标签文本也能获取到;innerHTML在获取标签中的文本时,能获取到标签中的文本,如果标签中还有标签,那么获取到的就是标签中的标签。

自定义属性
<ul  id="score">

  <li  score='10分'>你的成绩</li>

  <li  score='20分'>他的成绩</li>

 <li  score='30分'>她的成绩</li>

  <li  score='40分'>它的成绩</li>

  <li  score='50分'>谁的成绩</li>

</ul>
var  list = document.getElementsByTagName('li');

  for(var  i = 0;i<list.length;i++){

  list[i].onclick = function(){

  alert(this.getAttribute('score'));

  //score属性时设置在<li>标签上的,而this指的是DOM对象,直接this.score是获取不到这个属性值的,

  //要通过getAttribute方法获取标签的某个属性

  //同样,要设置标签的属性,要使用list[i].setAttribute()方法,其中有两个参数,一个属性名,一个属性值

 }

 }

    一般在设置自定义属性的时候,不通过上面的方式对标签添加属性,如果标签很多的话会造成代码重复,一般是通过循环遍历,使用list[i].setAttribute()方式添加标签元素。

    移除自定义属性时,使用的方法是element.removeAttribute(‘属性名’);属性和值都没有了,这种方式也可以移除元素自带的属性。

节点

     节点有三个属性:nodeType、nodeName、nodeValue

nodeType:节点的类型,1:标签,2:属性,3:文本

nodeName:节点的名字,标签节点:大写的标签名字;属性节点:小写的属性名字;文本节点:#text

nodeValue:节点的值:标签节点:null;属性节点:属性值;文本节点:文本内容

12行代码
<div  id="dv">

     <ul id="uu">第一个子节点

  <li>第一个子元素</li>

  <li>前一个兄弟元素</li>前一个兄弟节点

  <li  id="some">吼吼</li>后一个兄弟节点

  <li>后一个兄弟元素</li>

  <li>最后一个子元素</li>最后一个子节点

  </ul>

  </div>
var  ulObj = document.getElementById('uu');

  //ul的父元素

  console.log(ulObj.parentElement);

  //ul的父节点

  console.log(ulObj.parentNode);

  //ul的子元素

  console.log(ulObj.children);

  //ul的子节点

  console.log(ulObj.childNodes);

  console.log('----------------------------------------------');

  //ul的第一个子元素

  console.log(ulObj.firstElementChild);

  //ul的第一个子节点

  console.log(ulObj.firstChild);

  //ul的最后一个子元素

  console.log(ulObj.lastElementChild);

  //ul的最后一个子节点

  console.log(ulObj.lastChild);

  var  someObj = document.getElementById('some');

  //某个元素的前一个兄弟元素

  console.log(someObj.previousElementSibling)

  //某个元素的前一个兄弟节点

  console.log(someObj.previousSibling);

  //某个元素的后一个兄弟元素

  console.log(someObj.nextElementSibling);

  //某个元素的后一个兄弟节点

  console.log(someObj.nextSibling);

    分割线后面的代码在IE8中会有写问题,所有的获取元素的不再支持,输出undefined,在获取节点时,以获取第一个节点(firstChild)为例,如果第一个节点中有文本,则这个方法返回的还是第一个节点,如果第一个节点中没有文本,则这个方法返回的是第一个元素。但在IE11中又重新支持。恩,IE这样玩也是……

    所以就有了下面的兼容性代码:

function  getFirstElementChild(element){

  if(element.firstElementChild){

 return element.firstElementChild;

 }else{

  var  node = element.firstChild;

  //一直判断node是否存在,并且是否是标签(标签的nodeType==1),如果是则返回,如果不是,则获取node的后一个兄弟节点

  while(node && node.nodeType!= 1){

  node = node.nextSibling;

 }

  return  node;

 }

 }
获取元素的方法

根据id属性的值获取元素,返回来的是一个元素对象

getElementById(‘id属性的值’)

根据标签名字获取元素,返回来的是一个伪数组,里面保存了多个DOM对象

getElementsByTagName(‘标签名字’)

//下面的几个,有的浏览器不支持

根据name属性的值获取元素,返回来的是一个伪数组,里面保存了多个DOM对象

getElementsByName(‘name属性的值’)

根据类样式的名字来获取元素,返回来的是一个伪数组,里面保存了多个DOM对象

getElementsByClassName(‘类样式的名字’)

根据选择器获取元素,返回来的是一个元素对象

querySelector(‘选择器的名字’)

根据选择器获取元素,返回来的是一个伪数组,里面保存了多个DOM对象

querySelectorAll(‘选择器的名字’)

创建元素的三种方式
document.write

document.write(‘标签代码及内容’)

这种方式创建元素有缺陷:如果在页面加载完毕后再通过这种方式创建元素的话,整个页面就会被覆盖掉。

对象.innerHTML

对象.innerHTML(‘标签代码及内容’)

在谁里面添加标签,就用谁做对象

<input  type="button"  value="动态创建列表"  id="createList">

<div  id="list"></div>

  var  arrName = ['陈信宏', '温尚翊', '石锦航', '蔡升晏', '刘谚明'];

  var  divObj = document.getElementById('list');

  document.getElementById('createList').onclick = function () {

  var  str = '<ul>';

  for (var  i = 0; i < arrName.length; i++) {

 str += '<li>';

  str += arrName[i];

  str += '</li>';

 }

  str += '</ul>';

  divObj.innerHTML = str;

  var  list = divObj.getElementsByTagName('li');

  for (var  j = 0; j < list.length; j++) {

 list[j].style.cursor = 'pointer';

  list[j].onmouseover = function () {

  this.style.backgroundColor = 'green';

 }

  list[j].onmouseout = function () {

  this.style.backgroundColor = '';

 }

 }

 }
createElement
var  appendChd = document.getElementById('append');

  document.getElementById('addChild').onclick = function(){

  var  pObj = document.createElement('p');

  setTextContent(pObj,'我是一个p标签');

  appendChd.appendChild(pObj);

 }

一个栗子:动态创建表格

  var  arrTable = [

 {name:'百度',href:'https://www.baidu.com/'},

 {name:'谷歌',href:'https://www.google.cn/'},

 {name:'百度',href:'https://www.baidu.com/'},

 {name:'谷歌',href:'https://www.google.cn/'},

 {name:'百度',href:'https://www.baidu.com/'},

 {name:'谷歌',href:'https://www.google.cn/'}

 ]

  document.getElementById('createTable').onclick = function(){

  var  tableObj = document.createElement('table');

  var  tabDivObj = document.getElementById('table');

  tabDivObj.appendChild(tableObj);

  tableObj.border = '1';

  tableObj.cellPadding = '0';

  tableObj.cellSpacing = '0';

  for(var  i = 0;i<arrTable.length;i++){

  var  col = document.createElement('tr');

  tableObj.appendChild(col);

  var  row1 = document.createElement('td');

  row1.innerText = arrTable[i].name;

  row1.style.padding = '10px';

  var  row2 = document.createElement('td');

  row2.innerHTML = "<a href='"+arrTable[i].href+"'>"+arrTable[i].name+"</a>";

  row2.style.padding = '10px';

  tableObj.appendChild(row1);

  tableObj.appendChild(row2);

 }

 }

何时使用匿名函数,何时使用命名函数?

    如果是循环的方式添加事件,推荐使用命名函数;如果不是循环的方式添加事件,推荐使用匿名函数。

元素的相关方法

appendChild(元素) 追加元素,旧元素后移,新元素在第一个位置

insertBefore(新元素,旧元素) 插入元素

replaceChild(新元素,旧元素) 替换旧元素

removeChild(旧元素) 删除旧元素

为元素绑定事件

为同一个元素绑定多个相同的事件

1. 对象.on事件名 = 函数(命名函数、匿名函数)

element.onclick = function(){}

2.addEventListener(); 谷歌、火狐是支持的,IE8****不支持

三个参数

第一个参数:事件的类型------事件的名字没有on

第二个参数:事件的处理函数------命名函数、匿名函数

第三个参数:布尔类型,false表示事件是冒泡阶段(从里向外),true表示事件是捕获阶段(从外向里)

3.attachEvent(); 只有IE8****支持

两个参数

第一个参数:事件类型------事件的名字,有on

第二个参数:事件的处理函数------命名函数、匿名函数

兼容性代码

//为任意元素绑定任意事件

function  addEventListener(element,type,fn){

  //判断一个对象有没有一个方法,直接对象.方法名,不要加括号

  //加括号的意思就是执行方法,得到的是方法的返回值

  if(element.addEventListener){

  element.addEventListener(type,fn,false);

 }else  if(element.attachEvent){

  element.attachEvent('on'+type,fn);

 }else {

  element['on'+type] = fn;

 }

}

addEventListener和attachEvent对比

相同点:

都可以为元素绑定事件

不同点:

1. 方法名不一样

2. 参数个数不一样addEventListener参数有三个,attachEvent参数有两个

3. addEventListener中事件的名字没有on,attachEvent中事件的名字有on

4. addEventListener谷歌、火狐、IE11支持,IE8不支持,attachEvent谷歌、火狐、IE11不支持,IE8支持

5. addEventListener方法中的this是当前绑定对象,attachEvent方法中的this是window

为元素解绑事件

注:用什么样的方式绑定事件,就要用什么样的方式解绑事件

1. 对象.on事件名字 = null;

2. remoceEventListener()

三个参数:

第一个参数:事件的类型------事件的名字没有on

第二个参数:事件的处理函数------命名函数

第三个参数:布尔类型,false表示事件是冒泡阶段(从里向外),true表示事件是捕获阶段(从外向里)

这种方式解绑事件,需要在绑定事件的时候使用命名函数,最后解绑的时候使用同样的函数名

function  f1(){};

document.getElementById('btn').addEventListener('click',f1,false);

document.getElementById('btn').removeEventListener('click',f1,false);

3. detachEvent()

两个参数:

第一个参数:事件类型------事件的名字,有on

第二个参数:事件的处理函数------命名函数

同样,在绑定事件的时候需要使用命名函数,在解绑的时候使用同样的函数名

兼容代码

//为任意元素解绑任意事件

function  removeEventListener(element,type,fnName){

  //判断一个对象有没有一个方法,直接对象.方法名,不要加括号

  //加括号的意思就是执行方法,得到的是方法的返回值

  if(element.removeEventListener){

  element.removeEventListener(type,fnName,false);

 }else  if(element.detachEvent){

  element.detachEvent('on'+type,fnName);

 }else {

  element['on'+type] = null;

 }

}
阻止浏览器的默认事件

两种方式:

1. return false:

2. e.preventDefault() 这种方式IE8不支持

事件冒泡

多个元素嵌套,有层次关系,这些元素都注册了相同的事件,如果里面的元素的事件触发了,外面元素的相同事件(相同事件的意思是,相同类型的事件)也会被触发。

阻止事件冒泡

在想要阻止的事件处理函数中,最后调用这么一句话

  document.getElementById('btn').onclick = function(){

  window.event.cancelBubble = true;

 }

谷歌、IE8****都支持,火狐不支持

或者是使用事件处理对象

  document.getElementById('btn').onclick = function(e){

  e.stopPropagation();

 }

谷歌、火狐支持,IE8****不支持

可以看到,IE8中的window.event和谷歌火狐中的e对象时相同的,在IE8中,没有e这个事件处理参数,所以不能调用其对应方法。

事件流
冒泡事件流

事件的传播是从下往上传,即从DOM树的叶子到根。

image.png
捕获事件流

事件的传播是从上往下,即从跟到叶子

image.png
var  divObjs = [my$('div1'),my$('div2'),my$('div3')];

  divObjs.forEach(function(element){

  element.addEventListener('click',function(e){

  console.log(this.id);

  console.log(e.eventPhase);

 },true);

 })
/**

 * 1.冒泡事件

 * 2.目标事件

 * 3.捕获事件

 *

 * 标识这是什么事件的属性在事件参数对象中存在,也就是上面的e,e.eventPhase

 * 哪个对象触发的点击事件,那么这个对象就是目标对象,它触发的事件就是目标事件,对应的e.eventPhase属性值为2

 * 通过冒泡触发的事件,对应的对象的e.eventPhase属性值就为1

 * 通过捕获触发的事件,对应的对象的e.eventPhase属性值就为3

 */

总结:

事件的出发过程中可能会出现事件冒泡,为了阻止事件冒泡:

window.event.cancelBubble = true;谷歌、IE8支持,火狐不支持,

window.event是一个对象,是IE中的标准;

e.stopPropagation();谷歌、火狐支持,IE8不支持,

window.event和e都是事件参数对象,一个是IE的标准,一个是火狐的标准,事件参数e在IE8的浏览器中是不存在的,此时用window.event来代替。

事件的阶段有三个,通过e.eventPhase这个属性可以知道当前的事件是什么阶段的,如果这个属性的值是1,表示为捕获阶段,2表示目标阶段,3表示冒泡阶段;一般默认为冒泡阶段,很少用捕获阶段。

一个栗子,事件的类型在e.type属性中

//为同一个元素绑定不同的事件,指向相同的事件处理函数

  my$('div1').onclick = f1;

  my$('div1').onmouseover = f1;

  my$('div1').onmouseout = f1;

  function  f1 (e){

  console.log(e.type)

 }
offset系列

在style标签中设置的样式属性时获取不到的,但在标签的style属性中设置的样式属性时可以获取到的。以后获取元素的高和宽用offset系列。

元素.offsetWidth; 元素的宽(有边框的,和元素中的内容是没有关系的)

元素.offsetHeight; 元素的高(有边框的,和元素中的内容是没有关系的)

元素.offsetLeft; 元素距离左边的距离

元素.offsetTop; 元素距离上边的距离

解释一下后面两个

没有脱离文档流时

offsetLeft:父级元素的****margin + 父级元素的padding + 父级元素的border + 自己的margin

脱离文档流时

offsetLeft:大小和父级元素的margin、padding、border已经没有关系了,只和自己的****left****和margin****有关,但相对的位置是相对父元素的位置(也就是说,这个时候,找到子元素的父元素是关键)

scroll系列

scrollWidth:元素中内容的实际宽度(没有边框),当没有内容或者内容没有超出元素时,还是元素的宽度

scrollHeight:元素中内容的实际高度(没有边框),当没有内容或者内容没有超出元素时,还是元素的高度

scrollTop:元素中的内容向上卷曲过去的距离

scrollLeft:元素中的内容向左卷曲过去的距离

兼容性代码:

//获取滚动条的滚动距离(上、左)

function  getScroll (){

  return {

  top:window.pageYOffset||document.documentElement.scrollTop||document.body.scrollTop||0,

  left:window.pageYOffset||document.documentElement.scrollLeft||document.body.clientLeft||0

 };

}

固定导航栏案例

//这个地方有个注意点,就是设置marginTop的时候,一定要记得加‘px’

  window.onscroll = function () {

  console.log(getScroll().top);

  if(getScroll().top > my$('d1').offsetHeight){

  my$('d2').className = 'div2 fixed';

  my$('d3').style.marginTop = my$('d2').offsetHeight+'px';

 }else{

  my$('d2').className = 'div2';

  my$('d3').style.marginTop = 0 +'px';

 }

 }
client系列

可视区域:能看到的元素的大小

clientWidth:可视区域的宽,没有边框,有padding

clientHeight:可视区域的高,没有边框,有padding

clientLeft:左边框的宽度

clientTop:上边框的宽度

因为padding也是内容的一部分,所以padding并不算在这个值里面

clientX,offsetX,layerX,pageX,screenX,X

https://www.cnblogs.com/xulei1992/p/5659923.html

先来个定义

screenX/Y:鼠标位置相对于屏幕的坐标

pageX/Y:鼠标位置相对于文档边缘的距离,当滚动条滚动时,对应的值会增加,可以理解为相对于文档的top和left,而不是相对于可是区域的top、left(IE8不支持)

clientX/Y:鼠标位置相对于文档边缘的距离,当公东条滚动时,对应的值不会增加

offsetX/Y:鼠标位置相对于当前元素(块或行内块)的距离,google浏览器的边缘包含border,IE浏览器的边缘不包含边框

啥意思呢?看图说话

google浏览器中,当鼠标放在border上时,offset的值是正的


image.png

在IE浏览器中,当鼠标放在border上时,offset的值是负的


image.png

X/Y:与clientX/Y相同,火狐浏览器不支持

layerX/Y:与pageX/Y相同(不包括IE浏览器),IE11浏览器中和clientX/Y相同(IE8不支持)

测试代码自存

<!DOCTYPE html>

<html>

<head>

  <title></title>

  <script  type="text/javascript"  src="http://code.jquery.com/jquery-1.9.1.min.js"></script>

  <style>

  body {

  margin: 0;

  padding: 0;

 }

  .div {

  text-align: center;

  font-size: 24px;

  height: 300px;

  width: 1300px;

  line-height: 300px;

  color: yellow;

 }

  #d1 {

  background-color: #FF3B2F;

 }

  #d2 {

  background-color: #4CDA64;

 }

  #d3 {

  background-color: #007AFF;

  border: 50px  solid  #004400;

  width: 500px;

  display: inline-block;

 }

  #d3-2{

  background-color: #FF2C55;

  width: 500px;

  border: 10px  solid  #019EE4;

  display: inline-block;

 }

  #d4 {

  position: fixed;

  background-color: #FFCC00;

  height: 340px;

  width: 120px;

  top: 0;

  bottom: 0;

  left: 50px;

  margin: auto  0;

  font-family: "arial";

  font-size: 16px;

 }

  </style>

  <script  type="text/javascript">

  $(function () {

  document.onmousemove = function (e) {

  if (e == null) {

  e = window.event;

 }

  var  html = "<span style='color:#000'>screenX:" + e.screenX + "</span><br/>";

  html += "<span style='color:#000'>screenY:" + e.screenY + "</span><br/><br/>";

  html += "<span style='color:#f00'>clientX:" + e.clientX + "</span><br/>";

  html += "<span style='color:#f00'>clientY:" + e.clientY + "</span><br/><br/>";

  html += "<span style='color:#f00'>x:" + e.x + "</span><br/>";

 html += "<span style='color:#f00'>y:" + e.y + "</span><br/><br/>";

  html += "<span style='color:#00f'>layerX:" + e.layerX + "</span><br/>";

  html += "<span style='color:#00f'>layerY:" + e.layerY + "</span><br/><br/>";

  html += "<span style='color:#00f'>pageX:" + e.pageX + "</span><br/>";

  html += "<span style='color:#00f'>pageY:" + e.pageY + "</span><br/><br/>";

  html += "<span style='color:#070'>offsetX:" + e.offsetX + "</span><br/>";

  html += "<span style='color:#070'>offsetY:" + e.offsetY + "</span><br/>";

  $("#d4").html(html);

 };

 });

  </script>

</head>

<body>

  <div  id="d1"  class="div">div1 height:300px width:1300px</div>

  <div  id="d2"  class="div">div2 height:300px width:1300px</div>

  <div  id="d3"  class="div">div3 height:300px width:500px</div>

  <div  id="d3-2"  class="div">div3-2 height:300px width:500px <span  style="width:50px;height:50px;background:#000;display: inline-block;border: 5px solid #fff;line-height: 45px;">dddd</span></div>

  <div  id="d4"></div>

</body>

</html>
通过document获取元素

获取body,得到的是一个标签

document.body

获取title,得到的是title文本

document.title

获取html

document.documentElement

获取元素的所有样式属性
window.getComputedStyle(my$('d1'),null)

这样就能获取到d1元素的所有样式,返回值是一个样式对象,通过.属性即可获得属性值(IE8不支持)

my$('d1').currentStyle

IE8支持

兼容性代码

//获取元素的所有样式属性

function  getStyle (element,attr){

  return  window.getComputedStyle? window.getComputedStyle(element,null)[attr]:element.currentStyle[attr];

}
元素隐藏的不同方式

不占位:

display:none;

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

推荐阅读更多精彩内容