DOM

web API简介

简介:API是一些预定义好的函数。

JavaScript 组成

  • ECMAScript:
    
    • 定义了javascript的语法规范。
    • JavaScript的核心,描述了语言的基本语法和数据类型, ECMAScript是一套标准,定义了一种语言的标准,与具体实现无关。
  • BOM 浏览器对象模型

    • 一套操作浏览器功能的API。
    • 通过BOM可以操作浏览器窗口,比如弹出框、控制浏览器跳转、获取分辨率等等。
  • DOM 文档对象模型

    • 一套操作页面元素的API。
    • DOM可以把HTML看做一个文档树,通过DOM提供的API可以对树上的节点进行操作。

DOM

简介

  • 文档对象模型(Document Object Model),是w3c推荐的处理可扩展的标记语言的标准编程接口。它是一种与平台和语言无关的应用程序接口,可以动态的访问程序和脚本,更新其内容、结构和文档风格。HTML是将html元素转换成document对象,通过获取对象中的属性,来进行操作html的页面元素。文档可以进一步被处理,处理结果可以加入到当前的页面。Dom是一种基于树的API文档,它要求在处理过程中,将整个文档都存储在内存中。

通过id获取元素

  • 语法:调用 document 对象的 getElementById 方法。
  • 示例:document.getElementById("id名称")
  • 参数:字符串类型的 id 属性值。
  • 返回:对应 id 名的元素对象。
  • 注意:
    • 一般在接受返回值得时候,因为获取的是一个DOM对象,在给变量命名的时候,习惯性的以英文"o"开头。
    • 由于id具有唯一性,在js中通过id获取元素节点的时候,如果页面中有相同名称的id元素,则只会获取第一个对象。

通过标签名获取元素

  • 语法:调用 document 对象的 getElementsByTagName 方法。
  • 示例:document.getElementsByTagName("标签名")
  • 参数:标签名称。
  • 返回:同名的元素对象组成的伪数组。HTMLCollection。
  • 注意:
    • 操作的时候需要按照操作数组的方法进行操作。
    • getElementsByTagName 获取的元素是动态增加的。

元素对象内部获取标签元素。

  • 获取的元素对象内部,本身也可以调用根据标签获取元素的方法。例如 div 元素对象也可以调用 getElementsByTagName 方法。
  • 目的:缩小元素的选择范围,类似于CSS的后代选择器。

通过 name 属性获取元素

  • 语法:调用 document 对象的 getElementsByName 方法。
  • 示例:document.getElementsByName("name名称")
  • 参数:字符串类型的 name 属性值。
  • 返回:name 属性值相同的元素对象组成的数组。
  • 注意:
    • 不建议使用,因为在IE和Opera中有兼容问题,会多选中id名称相同的元素。
    • 方法选中的元素也是动态变化的。

通过类名获取元素

  • 方法:调用 decument 对象的 getElementsByClassName 方法。
  • 参数:字符串类型的 class 属性值。
  • 返回:class 属性值相同的元素对象组成的数组。
  • 浏览器兼容问题:不支持IE8及以下浏览器。

通过选择器获取元素

  • 方法1:调用 decument 对象的 querySelector()方法,通过css中的选择器,选取第一个符合条件的标签元素。
  • 方法2:调用 decument 对象的 querySelectorAll()方法,通过css选择器去选取所有符合条件的标签元素。
  • 示例1:decument.querySelector("#main")
  • 示例2:decument.querySelectorAll("#list li")
  • 参数:字符串类型的 css 中的选择器。
  • 返回:
    • querySelector() 返回指定元素。
    • querySelectorAll() 返回节点集合, NodeList
  • 注意:不会动态添加。
  • 浏览器兼容问题:不支持IE8以下的浏览器。

事件

简介

  • 事件:表示在什么时间做什么事
  • 执行机制:触发 响应机制
  • 绑定事件(注册事件)三要素:
    • 事件源:给谁绑定事件
    • 事件类型:绑定什么类型的事件
    • 事件函数:事件发生后执行什么内容,写在函数内部。

事件监听

  • JavaScript解析器会给有绑定事件的元素添加一个监听,解析器会一直监测这个元素,只有触发对应的绑定事件,就会立刻执行事件函数。

常用的鼠标事件类型

方法 说明
onclick 鼠标左键单击触发
ondblclick 鼠标左键双击触发
onmousedown 鼠标按键按下触发
onmouseup 鼠标按键放开时触发
onmousemove 鼠标在元素上移动触发
onmouseover 鼠标移到元素上触发
onmouseout 鼠标移除元素边界触发
onfocus 获取焦点事件
onblur 失去焦点
onscroll 滚动条滚动事件

常用事件监听方法

  • 方法1:绑定HTML元素属性,适用于比较简单的事件类型
  • 示例:
<input type="button" value="点击"    onclick="alert('surprised')">
  • 方法2:绑定DOM对象属性
  • 示例:
<input type="button" id="btn" value="点击有惊喜">
<script>
    // 获取元素
    let obtn = document.getElementById("btn")
        // 绑定事件
    obtn.onclick = function() {
        // 定义事件触发后要做的事情
        alert("惊喜多多")
    };
</script>

DOM 元素属性操作

非表单元素的属性

  • 例如:href、title、id、src等、
  • 调用方式:元素对象打点调用属性名,例如 obj.href
  • 注意:
    • 部分的属性名跟关键字和保留字冲突,会更换写法。

      • class -- className
      • for -- htmlFor
      • rowspan -- rowSpan
    • id元素是可读的,不可以修改。

  • 属性赋值:给元素属性赋值,等号右侧的赋值都是字符串格式。

函数中的 this

  • 在事件函数中有一个 this,指向事件源。
  • 在普通函数中,this 指向window 对象。
  • 在构造函数中,this 指向的是生成的实例对象。
  • 在对象的方法中,this 指向的是对象本身。

获取标签内部内容的属性

  • innerHTML属性:在获取标签内部内容时,如果包含标签,获取的内容会包含标签,获取的内容也会包括空白,换行等。
  • innerText属性:在获取标签内部内容时,如果包含标签,获取的内容会过滤标签,获取的内容会去掉换行和缩进等空白。

更改标签内容

  • innerHTML 设置属性值,有标签的字符串,会按照HTML语法中的标签加载。在设置有内部子标签结构的时候使用。
  • innerText 设置属性值,有标签的字符串,会按照普通的字符串加载。一般在设置纯字符串时候使用。

表单元素属性

  • value 用于大部分表单元素的内容获取(option除外)。
  • type 可以获取input标签的类型(输入框或复选框)。
  • disabled 禁用属性。
  • checked 复选框选中属性。
  • selected 下拉菜单选中属性。
  • 注意:在 DOM 中元素对象的属性值只有一个时,会被转换成布尔值显示,如 txt.disabled = true;

自定义属性操作

  • 元素可以进行自定义属性,直接在元素内部书写。
<div id="box" age=18></div>
  • 获取自定义属性值时候不可以直接使用打点调用的方法,如下代码返回undefined
var obox = document.getElementById("box")
obox.id // box
obox.age  // undefined
  • getAttribute(name) 获取标签行内属性
  • setAttribute(name, value) 设置标签行内属性
  • removeAttribute(name) 移除标签行内属性
  • 与element.属性的区别:上述三个方法用于获取任意的行内属性,包括自定义的属性。

style样式属性

  • 使用 style 属性方式设置的样式显示在标签行内。

  • element.style 属性的值,是所有行内样式组成的一个样式对象。

  • 样式对象可以继续打点语法调用或者更改 css 的行内样式属性,例如 widht、height 等属性。

  • 注意:

    • 类似 background-color 这种复合属性的单一属性写法,是由多个单词组成的,要修改为驼峰命名方式 书写为 backgroundColor。
    • 通过样式属性设置宽高、位置的属性类型是字符串,需要加上 px 等单位。
  • 应用场景:

    • 如果修改的样式为单一样式,可以选择直接使用style进行修改。
    • 如果修改的样式有很多条 css 样式,可以提前将修改后的样式设置到一个类选择器中,后续通过修改类名的方式,批量修改 css 样式。但是需要注意 css 的权重。

排他思想

  • 在一组标签中,如果给标签添加事件,但是仅仅只需要当前被选中的元素发生变化,当不被选中时,恢复默认样式,这需要用到排他思想。比如轮播图中当前元素下面小圆点显示高亮,其他都是默认颜色。
  • 主要步骤分为两步,第一是排除其他,第二是保留自己。排除其他通过for循环,让每个元素都设置成默认样式,然后再单独对需要发生变化的元素进行样式的添加或修改。
<script>
    var oinputArr = document.getElementsByTagName("input");
    for (var inputs of oinputArr) {
        inputs.onfocus = function() {
            // 排它思想
            // 排除所有
            for (var oinput of oinputArr) {
                oinput.style.backgroundColor = ""
                };
            // 选择自己
            this.style.backgroundColor = "red"};
        };
</script>
// tab栏切换
var ohd = document.getElementById("hd")
var ospans = ohd.getElementsByTagName("span")
var obd = document.getElementById("bd")
var odivs = obd.getElementsByTagName("div")

for (var i = 0; i < ospans.length; i++) {
    // 自定义 index 属性
    ospans[i].index = i;
    // 绑定鼠标经过事件
    ospans[i].onmousemove = function() {
        for (var k = 0; k < ospans.length; k++){
            ospans[k].className = "";
            odivs[k].className = "";
            };
        this.className = "current"
        odivs[this.index].className = "current";
    };
};

节点属性

  • 每一个元素就是一个节点,而每一个节点就是一个对象。也就是说,我们在操作元素时,其实就是把这个元素看成一个对象,然后使用这个对象的属性和方法来进行相关操作。

  • 表示元素的叫做元素节点,表示属性的叫做属性节点,表示文本的叫做文本节点。节点和元素是不一样的概念,节点是包含元素的。

  • 在JavaScript中可以使用 nodeType 属性来判断一个节点的类型。

  • 一个元素就是一个节点,这个节点称为元素节点。

  • 只有元素节点才有子节点,属性节点和文本节点没有子节点。

  • nodeType

节点类型 nodeType值
元素节点 1
属性节点 2
文本节点 3
  • nodeName 节点的名称(标签名称),只读。
  • nodeValue 节点值 返回或者设置当前的节点值。元素节点的节点值始终是null

父子节点常用属性

  • childNodes:只读属性,获取一个节点所有子节点的实时集合,集合是动态变化的。
语法:obj.childNodes
说明:obj表示通过getElementById等方法获取到的元素对象。
返回结果:NodeList[],数组中包含换行符与 标签元素。
  • children:只读属性,返回一个节点所有的子元素节点的集合,是一个动态更新的HTML元素集合。
语法:obj.children
说明:obj表示通过getElementById等方法获取到的元素对象。
返回结果:HTMLCollection[],数组中只包含标签元素。
  • firstChild:只读属性,返回该节点的第一个子节点,如果该节点没有子节点则返回null。
语法:obj.firstChild
说明:obj表示通过getElementById等方法获取到的元素对象。
返回结果:,NodeList数组中的第一个元素。
  • lastChild:只读属性,返回该节点的最后一个子节点,如果该节点没有子节点返回null。
语法:obj.lastChild
说明:obj表示通过getElementById等方法获取到的元素对象。
返回结果:,NodeList数组中的最后一个元素。
  • firstElementChild:获取所有元素类型的子节点的第一个元素。
语法:obj.firstElementChild
说明:obj表示通过getElementById等方法获取到的元素对象。
返回结果:HTMLCollection数组中的第一个元素。
  • lastElementChild:获取所有元素类型的子节点的最后一个元素。
语法:obj.lastElementChild
说明:obj表示通过getElementById等方法获取到的元素对象。
返回结果:HTMLCollection数组中的最后一个元素。
  • parentNode:返回一个当前节点的父节点,如果没有这样的节点,这个属性返回null
  • parentElement:返回当前节点的父元素节点,如果该元素没有父节点,或者父节点不是一个DOM元素,则返回null。
语法:obj.parentNode/obj.parentElement
说明:obj表示通过getElementById等方法获取到的元素对象。
返回结果:父级元素。

兄弟节点的常用属性

  • nextSibling:只读属性,返回与该节点同级的下一个节点,如果没有返回null。
  • previousSibling:只读属性,返回与该节点同级的上一个节点,如果没有返回null。
  • nextElementSibling:只读属性,返回与与该节点同一级的下一个元素节点,如果没有返回null。
  • previousElementSibling:只读属性,返回与该节点同一级的上一个元素节点,如果没有返回null。
  • 注意:nextElementSibling和previousElementSibling有兼容问题,IE9以后才支持。

动态创建元素

  • 在JavaScript中可以使用 createElement() 来创建一个元素节点,也可以使用 createTextNode() 来创建一个文本节点,也可以使用 createAttribute() 创建一个属性节点。然后可以将文本节点和元素节点组装成一个"有文本内容的元素"。

  • 语法:

// 动态创建元素节点
var el = document.createElement("元素名");
// 动态创建属性节点
val cls = document.createAttribute("属性名")
// 动态创建文本节点
var text = document.createTextNone("文本内容");
// 将文本节点插入到元素节点
text.appendChild(el);
// 将元素节点插入到body元素中。
document.body.appendChild(el);
  • 如果想在动态创建的节点中添加属性,可以通过 .属性值 的方法,为动态创建的元素节点添加属性。在添加class属性的时候,仍是需要使用 className ,而不是直接使用 class
// 动态创建一个 input 标签
var oinput = document.createElement("input");
oinput.id = "input";
oinput.type = "button";
oinput.value = "提交";
oinput.className = "btn";

// 将input标签插入到body元素中
document.body.appendChild(oinput);
  • 综上示例,如果想要动态创建一个元素,需要以下四步
    • 创建子元素节点 createElement()。
    • 创建文本节点 createTextNode()。
    • 把文本节点插入到元素节点 appendChild()。
    • 把元素节点插入到已有元素中 appendChild()。

插入元素

  • 在JavaScript中可以使用 appendChild()insertBefore() 两个方法,把一个新元素插入到父元素中。

  • 注意:appendChild()insertBefore() 这两种插入元素的方法都需要先获取父元素才可以操作

appendChild()
  • appendChild() 把一个新元素插入到父元素的内部 子元素 的末尾。

  • 语法:

    • A.appendChild(B);
  • 说明:

    • A表示父元素,B表示动态创建好的新元素。
  • 注意:将原有节点通过appendChild插入到父级元素中的时候,实际上进行了两步操作,第一步先将原始节点删除,第二步将元素添加到父元素的最后。

insertBefore()
  • insertBefore() 将一个新元素插入到父元素内部中某一个子元素之前。
  • 语法:
    • A.insertBefore(B, ref)
  • 说明:
    • A表示父元素,B表示动态创建好的新元素,ref表示指定子元素。表示在ref之前插入新元素B。如果ref为null,则会将新元素插入到子节点的末尾。

替换元素

  • JavaScript中,可以使用 replaceChild() 方法来替换当前节点的子节点。

  • 语法:

    • A.replaceChild(newChild, oldChild)
  • 说明:

    • 用指定的节点替换当前节点的一个子节点,并返回被替换掉的节点。

删除元素

  • JavaScript中,我们可以使用 removeChild() 方法来删除父元素下的某个子元素。

  • 语法:

    • A.removeChild(B)
  • 说明:

    • A表示父元素,B 表示父元素内部的某个子元素。
  • 注意:在删除元素之前必须要找到被删除的元素和被删除元素的父元素。

复制元素

  • 在JavaScript中,我们可以使用 cloneNode() 方法来实现复制元素。

  • 语法:

    • obj.cloneNode(bool)
  • 说明:

    • obj表示被复制的元素,参数bool是一个布尔值,取值如下
    • 1或true:表示复制元素本身以及复制该元素下的所有子元素。
    • 0或false:表示仅复制元素本身,不复制该元素下的子元素。
  • 注意:克隆时,标签上的属性和属性值也会被复制,写在标签行内的绑定事件也可以被复制,但是通过JavaScript动态绑定的事件不会被复制。

节点判断方法

  • hasChildNodes(),判断调用元素是否包含子节点。不区分节点类型。

  • 语法:

    • Node.hasChildNodes()
  • 说明:

    • 没有参数,返回一个Boolean布尔值。用来表示该元素是否包含子节点。
  • contains(child):返回一个boolean布尔值,表示传入的节点是否是调用元素的后代节点。

  • 语法:Node.contains(child) 表示传入的节点是否是调用元素的后代节点。

判断方法总结

  • node.firstChild !== null; // 表示有子节点
  • node.ChildNodes.length > 0; // 表示有子节点
  • node.hasChildNodes()

注册事件的其他方法

addEventListener()

  • elemennt.addEventListener() 方法

  • 参数:

    • 第一个参数:事件类型的字符串(直接书写"click",不需要加 on)。
    • 第二个参数:事件函数。
    • 第三个参数:true/false true表示事件捕获,false表示事件冒泡。
  • 同一个元素可以多次绑定事件监听,同一个事件类型可以注册多个事件函数。事件会根据一个书写的顺序进行排队。

  • 兼容性问题:不支持 IE9 以下的浏览器。

// 当点击btn按钮的时候,会先弹出1,然后再弹出2。
// 如果参数2的位置传入预先自定义好的函数,注意不要在函数名称后面添加小括号。

var btn = document.getElementById("btn");
btn.addEventListener("click", function () {
    alter(1);
    };
)
function clickEvent() {
    alter(2);
}

btn.addEventListener("click", clickEvent)

attachEvent()

  • element.attachEvent() 方法

  • 参数:

    • 第一个参数:事件类型的字符串,需要加 on。
    • 第二个参数:事件函数。
  • 同一个元素可以多次绑定事件监听,同一个事件类型可以注册多个事件函数。

  • 兼容性问题:只支持 IE10 及以下的浏览器。IE8 及以下在处理事件队列的时候,会出现数据顺序错乱。

自定义注册事件的兼容写法

  • 参数:

    • 事件源
    • 事件类型(不加on)
    • 事件函数
  • IE9 以上使用 addEventListener() 方法。

  • IE9 以下使用 attachEvent() 方法。

  • 判断浏览器时,不需要判断浏览器的版本,可以检测浏览器的能力,将某个方法作为 if 语句的判断条件,如果浏览器认识该方法返回 true,如果不认识返回 false。

<input type="button" id="btn">
<script>
    var obtn = document.getElementById("btn");
        function addEvent(ele, type, fn) {
            // ele: 事件源
            // type: 事件类型 不加 on
            // fn: 事件函数
            if (ele.addEventListener) {
                ele.addEventListener(tyle, fn);
            } else if (ele.attachEvent) {
                ele.attachEvent("on" + type,fn);
            };
        };
    // 调用函数
    addEvent(obtn, "click", function () {
        alter(1);
    })

事件解除绑定方法

DOM 0级事件解绑方法

btn.onclick = function () {
    alter(1)
};
btn.onclick = null;

removeEventListener()

  • element.removeEventListener() 方法

  • 参数:

    • 第一个参数:事件类型的字符串,不需要加 on
    • 第二个参数:事件函数引用名。
  • 注意:没有办法移除一个匿名函数,所以在注册事件时需要单独声明一个有函数名的事件函数,

  • 兼容问题:不支持 IE9 以下的浏览器。

detachEvent()

  • element.detachEvent() 方法

  • 参数:

    • 第一个参数:事件类型的字符串 需要加 on
    • 第二个参数:事件函数引用名。
  • 注意:没有办法移除一个匿名函数,所以在注册事件时需要单独声明一个有函数名的事件函数,

  • 兼容问题:只支持 IE10 及以下的浏览器。

自定义解绑事件的兼容写法

function removeEvent(ele, type, fn) {
    // ele: 事件源
    // type: 事件类型 不加 on
    // fn: 事件函数
    if (ele.removeEventListener) {
        ele.removeEventListener(type, fn);
    } else if (ele.detachEvent) {
        ele.detachEvent("on" + type, fn);
    };
}

事件流的三个阶段

  • 第一阶段:事件捕获。
  • 第二阶段:事件执行过程。
  • 第三阶段:事件冒泡。
  • addEventListener() 第三个参数为 false 时,事件冒泡
  • addEventListener() 第三个参数为 true 时,事件捕获
  • onclick 类型:只能进行事件冒泡过程,没有捕获阶段。
  • attachEvent() 方法:只能进行事件冒泡过程,没有捕获阶段

事件冒泡应用--事件委托

<div>
    <ul id="ul">
        <li>唐三藏</li>
        <li>孙悟空</li>
        <li>猪悟能</li>
        <li>沙悟净</li>
    </ul>
</div>
<script>
// 事件委托
var oul = document.getElementById("ul");
var olis = oul.children;

// 将子级的公共类型的事件,委托给父级添加,在父级内部找到真正触发事件的最底层的事件源。

oul.onclick = function(e) {
    // e 表示事件对象
    // 只要触发事件,函数内部就可以得到一个事件对象,对象中存储了关于事件的一系列数据
    // e.target 属性记录的就是真正触发事件的事件源。
    for (var oli of olis) {
        oli.style.backgroundColor = "";
    };
    console.log(e.target)
    e.target.style.backgroundColor = "pink";
}

事件对象

  • 只要触发事件,就会有一个对象。内部存储了与事件相关的数据。
  • e 在低版本浏览器中有兼容问题,低版本的浏览器使用的是window.event。
  • 事件对象的常用属性:
属性 描述
e.eventPhase 查看事件触发时所处的阶段。1:捕获阶段。2:执行阶段。3:冒泡阶段
e.target 用于获取触发事件的元素
e.secElement 用于获取触发事件的元素,低版本浏览器使用
e.currentTarget 用于获取绑定事件的事件源元素
e.type 获取事件类型
e.clientX/e.clientY 所有浏览器都支持,鼠标距离浏览器窗口左上角的距离
e.pageX/e.pageY IE8以前不支持,鼠标距离整个HTML页面左上顶点的距离

取消默认行为和阻止事件传播的方式

属性 说明
e.preventDefault() 取消默认行为
e.returnValue = false; 取消默认行文,低版本浏览器使用
e.stopPropagation() 阻止冒泡,标准方式
e.cancelBubble = true; 阻止冒泡,IE低版本,标准中以废弃

offset 偏移量属性

  • offsetParent 偏移参考父级,距离自己最近的有对象的父级,如果都没有定位,参考body或html
  • offsetLeft/offsetTop 偏移位置,如果父级没有定位的话,寻找的是当前元素左上角定点的位置到浏览器左、上部的位置,如果父级元素有定位,则寻找的是父级元素的边框以内到当前元素边框以外的左、上的位置
  • offsetWidth/offsetheight 偏移大小,获取的是自身的宽度和高度,包含边框和本身的padding值。

client 客户端系列属性

  • client 系列没有参考父级元素
  • clientLeft/clientTop 边框区域尺寸,不常用
  • clientWidth/clientHeight 边框内部大小,将元素本身当成了一个客户端。获取元素的大小,不包含边框。

scroll 滚动偏移系列属性

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

推荐阅读更多精彩内容