JavaScript高级编程笔记(3)

BOM(浏览器对象模型)

由于window对象同时扮演ECMAScript中的global对象的角色,因此所有在全局作用域中声明的变量、函数都会变成window对象的属性和方法。

窗口大小:

  • outerWidthouterHeight 返回浏览器窗口本身的尺寸
  • innerWidthinnerHeight 返回该容器中页面视图区的大小
  • document.documentElement.clientWidthdocument.documentElement.clientHeight 保存页面视口的信息。(标准模式)
  • document.body.clientWidthdocument.body.clientHeight 保存页面视口的信息。(混杂模式)
  • document.compatMode 判断页面当前模式(CSS1Compat为普通模式)
  • window.resizeTo()window.resizeBy()方法可以调整浏览器窗口的大小.其中resizeTo()接受浏览器窗口新宽度和新高度,而resizeBy()接受新窗口与原窗口的宽度和高度之差.
  • window.open() 打开窗口,第一个参数为url,第二个参数为窗口名称.在不打开新窗口的情况下会忽略第三个参数.该方法会返回一个指向新窗口的引用.

间歇调用和超时调用:

  • 超时调用: setTimeout(fun,time)clearTimeout(object) .
  • 间歇调用:setInterval(func,time)clearInterval(object) .

location 对象

属性 描述
hash 设置或返回从井号 (#) 开始的 URL(锚)。如果地址里没有“#”,则返回空字符串。
host 设置或返回主机名和当前 URL 的端口号。
hostname 设置或返回当前 URL 的主机名。
href 设置或返回完整的 URL。在浏览器的地址栏上怎么显示它就怎么返回。
pathname 设置或返回当前 URL 的路径部分。
port 设置或返回当前 URL 的端口号,设置或返回当前 URL 的端口号。
protocol 设置或返回当前 URL 的协议,取值为 ‘http:’,’https:’,’file:’ 等等。
search 设置或返回从问号 (?) 开始的 URL(查询部分)。

navigator 对象

属性 描述
appCodeName 返回浏览器的代码名。
appMinorVersion 返回浏览器的次级版本。
appName 返回浏览器的名称。
appVersion 返回浏览器的平台和版本信息。
browserLanguage 返回当前浏览器的语言。
cookieEnabled 返回指明浏览器中是否启用 cookie 的布尔值。
cpuClass 返回浏览器系统的 CPU 等级。
onLine 返回指明系统是否处于脱机模式的布尔值。
platform 返回运行浏览器的操作系统平台。
systemLanguage 返回 OS 使用的默认语言。
userAgent 返回由客户机发送服务器的 user-agent 头部的值。
userLanguage 返回 OS 的自然语言设置。
  • window.navigator.plugins[]可以遍历检测浏览器的插件.
注册处理程序:
  • registerContentHandler()registerProtocolHandler()方法可以让一个站点指明它可以处理特定类型的信息.他们接受三个协议:要处理的协议、处理该协议页面的URL和应用程序的名称。

Screen 对象

在编程中作用不大,基本上只用来表明客户端的能力。

History 对象

history对象保存着用户上网的内容.
history.go()方法可以在用户历史记录中任意跳转,接受一个参数表示向后或向前跳转的一个整数值。
负数向后,正数向前,传递字符串直接跳转.


客户端检测

能力检测

能力检测目标不是识别特定浏览器,而是识别浏览器的能力。

能力检测的基本模式是:

if (object.propertyInQuestion){
  // 使用 object.propertyInQuestion
}

重要概念:一个特性存在,不一定意味着另一个特性也存在。
可靠的检测:

  • 不要用!object.sort来检测一个对象是否支持排序,而是用 typeof object.sort == "function"; 来进行检测.
  • 不要用特性来检测确定浏览器.
  • 部分浏览器有bug 可以使用怪癖检测.

用户代理检测

关于浏览器的检测可以在搜索引擎中获取相关信息。

DOM

Dom(文档对象模型)是针对HTML和XML文档的一个API(应用程序编程接口).DOM描绘了一个层次化的节点数,允许开发人员添加、移除和修改页面的某一部分。DOM脱胎于Netscape以及微软公司创始的DHTML(动态HTML)。

节点关系图.jpg

Document类型

referrer - 来源页面URL
domain - 域:
  • 可以将网页中的内嵌框架页面domain的值设置为和主页相同的域来进行互相访问对方的JvaScript对象。
  • 如果域名一开始是松散的那么就不能将它再设置为紧绷的.(设置为"wrox.com"之后再也不能将它设置回"p2p.wrox.com")
getElementByTagName(elementname)getElementByName(name)getElementById(id) 获取元素操作
  • getElementById(id) 只返回文档中第一次出现的元素ID。而getElementByTagName接受元素参数返回包含多个参数的NodeList(HTMLCollection)
  • HTMLCollection.namedItem() 方法从集合(HTMLCollection)中取回带有指定名称的节点或元素。
DOM一致性检测

document.implementation属性为浏览器对DOM的实现提供响应信息和功能的对象。

  • DOM1级只为该属性规定了一个方法:hasFeature().这个方法接受两个参数:要检测的DOM功能和版本号,浏览器支持则返回true。
DOM节点:
节点类型.png
节点类型 - 所返回的值.png
DOM扩展
1、选择符API

"querySelector 属于 W3C 中的 Selectors API 规范 。而 getElementsBy 系列则属于 W3C 的 DOM 规范"

  • getXXXByXXX获取的是动态集合,querySelector获取的是静态集合.
  • querySelector(CSS选择符)返回与模式匹配的第一个元素,没找到返回null.
  • querySelectorAll(CSS选择符) 返回NodeList对象.
  • matchesSelector(CSS选择符),如果调用元素与该选择符匹配,返回true,否则返回false。(即判断CSS选择符匹配的是调用元素).
    如果使用的话最好使用包装函数.
浏览器版本 函数
原生 matchesSelector()
IE9+ msMatchesSelector()
FireFox 3.6+ mozMatchesSelector()
Chrome、Safari 5+ webkitMatchesSelector()
2、元素遍历(支持规范:IE 9+ 、Firefox 3.5+、Safari 4+、Chrome 和 Opera 10+)
  • childElementCount :返回子元素(不包括文本节点和注释)的个数。
  • firstElementChild:指向第一个子元素;firstChild的元素版。
  • lastElementChild:指向最后一个子元素;lastChild的元素版。
  • previousElementSibling:指向前一个同辈元素;previousSibling的元素版。
  • nextElementSibling:指向后一个同辈元素;nextSibling的元素版。
var i,
     len,
     child = element.firstElementChild;
while(child != element.lastElementChild){
     processChild(child); 
     child = child.nextElementSibling;
}

HTML5

  • getElementsByClassName() 方法
    接受一个或者多个类名字符串(空格分隔),返回带有指定类的所有元素的NodeList.
  • classList 属性
    元素classList属性是新集合类型DOMTokenList实例。定义以下方法
方法名 解释
add(value) 将给定的字符串值添加到列表中,如果值已经存在,就不添加了。
contains(value) 表示列表中是否存在给定的值,如果存在则返回true,否则返回false
remove(value) 从列表中删除给定的字符串。
toggle(value) 如果列表中已经存在给定的值,删除它;如果列表中没有给定的值,添加它。
1、焦点管理
  • focus()
  • hasFocus()
2、 HTMLDocument的变化
  • readyState 属性
    • loading, 正在加载文档.
    • complete, 已经加载完文档.
  • compatMode 兼容模式
    • CSS1Compat,标准模式.
    • BackCompat,混杂模式.
  • head 属性
    要引用文档<head>元素,可以解和使用这个属性和另一个后被方法
  var head = document.head || document.getElementsByTagName("head")[0];
  • charset 字符集属性
    • document.charset 表示文档实际使用的字符集
    • document.defaultCharset 表示根据默认浏览器以及操作系统的设置,当前文档默认的字符集应该是什么。
3、 自定义数据属性

HTML5规定可以为元素添加非标准的属性,但要添加前缀data-,目的是为元素提供与渲染无关的信息,或者提供语义信息。这些属性可以任意添加、随便命名。只要以data-开头即可。

添加了自定义属性之后,可以通过元素dataset属性来访问自定义属性的值。

4、 插入标记 (未掌握)
  • innerHTML 属性

    在读模式下,innerHTML属性返回与调用元素的所有子节点(元素、注释和文本节点)对应的HTML标记。
    在写模式下,innerHTML会根据指定的值创建新的DOM树,然后用这个DOM树完全替换调用元素原先的所有子节点。

在写模式下,innerHTML的值会被解析为DOM子树,替换调用元素原来的所有子节点。
如果设置的值仅仅是文本而没有HTML标签,那么结果就是设置纯文本。
注意:大多数浏览器不会执行插入在innerHTML的<script>元素

  • outerHTML 属性

    在读模式下,outerHTML属性返回调用它的元素以及所有子节点的HTML标签。
    在写模式下,outerHTML会根据指定的HTML字符串创建新的DOM子树,然后用这个DOM子树完全替换调用元素。

  • insertAdjacentHTML() 方法

    它接收两个参数:插入位置和要插入的HTML文本。

  1. 第一个参数必须是下列值之一:
    • beforebegin() 在当前元素之前插入一个紧邻的同辈元素;
    • afterbegin() 在当前元素之下插入一个新的子元素或在第一个子元素之前再插入新的子元素;
    • beforeend() 在当前元素之下插入一个新的子元素或在最后一个子元素之后再插入新的子元素;
    • afterend() 在当前元素之后插入一个紧邻的同辈元素;
  2. 第二个参数是一个HTML字符串。

使用上面方法的时候需要注意 先将字符串单独构造,避免频繁操作,否则会影响性能。

5、滚动页面规范

scrollIntoView()为HTML5最终选择的滚动页面标准方法。如果不传参数或者传true作为参数,窗口滚动之后会让调用元素的顶部与视口顶部尽可能平齐。

document.element.scrollIntoView()

专有扩展

1、children属性
2、contains()方法

祖先节点调用contains(childNode)方法判断某个节点是否为另一个节点的后代.
调用 compareDocumentPosition(Node)方法确定节点之间的关系,返回该关系的掩码值

掩码 节点关系
1 无关(给定的节点不在当前文档中)
2 居前(给定的节点在DOM树中位于参考节点之前)
4 居后(给定的节点在DOM树中位于参考节点之前)
8 包含(给定的节点是参考节点的祖先)
16 被包含(给定的节点是参考节点的后代)

DOM2、DOM3

DOM1级主要定义的是HTML和XML文档的底层结构。DOM2和DOM3则在这个结构的基础上引入了更多的交互能力,也支持了更高级的XML特性。DOM2、DOM3分为许多模块:

  • DOM2级核心
  • DOM2级视图
  • DOM2级事件
  • DOM2级样式
  • DOM2级遍历和范围
  • DOM2级HTML

DOM变化

1、xml命名空间:xmlns
<html xmlns="http://www.w3.org/1999/xhtml">
  • DOM Level 2:
    Node类型包含以下特性:

    • localName: 不带命名空间前缀的节点名称.
    • namespaceURI: 命名空间URI或者(未指定时)null.
    • prefix: 命名空间前缀或者(未指定时)null.
  • DOM Level 3:
    Node类型包含以下特性:

    • isDefaultNamespace(namespaceURI): 在指定的namespaceURI是当前节点的默认命名空间的情况下返回true.
    • lookupNamespaceURI(prefix): 返回给定prefix的命名空间.
    • lookupPrefix(namespaceURI): 返回给定namespaceURI前缀..
  • Document 类型的变化
    后缀NS ,第一个参数为命名空间.

    • createElementNS(namespaceURI, tagName) 使用给定的tagName创建一个属于命名空间namespaceURI的新元素.
    • createAttributeNS(namespaceURI, attributeName) 使用给定的attributeName创建一个属于命名空间namespaceURI的新特性.
    • getElementsByTagNameNS(namespaceURI, tagName) 返回属于命名空间的namespaceURI的tagName元素的NodeList.
  • Element 类型的变化
    后缀NS ,第一个参数为命名空间.

    • getAttributeNS(namespaceURI, localName)
    • getAttributeNodeNS(namespaceURI, localName)
    • getElementsByTagNameNS(namespaceURI, tagName)
    • hasAttributeNS(namespaceURI, localName)
    • removeAttriubteNS(namespaceURI, localName)
    • setAttributeNS(namespaceURI, qualifiedName, value)
    • setAttributeNodeNS(attNode)
  • NamedNodeMap 类型的变化

函数 作用
getNamedItemNS(namespaceURI, localName) 取得属于命名空间namespaceURI且名为localName的项
removeNamedItemNS(namespaceURI, localName) 移除属于命名空间namespaceURI且名为localName的项
settNamedItemNS(node) 添加node

(很少使用)

2、DocumentType类型(DOM Level 2)

DocumentType类型新增三个属性publicIdsystemIdinternalSubset,前两个属性表示文档类型声明的两个信息段,最后一个属性用于访问包含在文档类型声明的额外定义。

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" 
        "http://www.w3.org/TR/html4/strict.dtd"
        [<!ELEMENT name (#PCDATA)>] >

在这个文档类型声明而言,publicId是"-//W3C//DTD HTML 4.01//EN" ,systemID是"http://www.w3.org/TR/html4/strict.dtd",internalSubset是 [<!ELEMENT name (#PCDATA)>] (很少用到)

alert(document.doctype.publicId)
3、
3) 滚动大小(scroll dimennsion)

滚动大小指的是包含滚动内容的元素的大小.下面是4个与滚动大小相关的属性

  • scrollHeight: 在没有滚动条的情况下,元素内容的总高度。
  • scrollWidth: 在没有滚动条的情况下,元素内容的总宽度。
  • scrollLeft:被隐藏在内容区域左侧的像素数.通过设置这个属性可以改变元素的滚动位置。
  • scrollTop:被隐藏在内容区域上方的像素数.通过设置这个属性可以改变元素的滚动位置。

对于不包含滚动条的页面而言,scrollWidth 和 scrollHeight 与 clientWidth 和 clientHeight 之间的关系并不十分清晰。在这情况下不同浏览器之间发现不一致性问题

  • Firefox 中这两组属性始终都是相等的,但大小代表的是文档内容区域的实际尺寸,而非视口尺寸。
  • Opera、Safari、Chrome 中的这两组属性是又差别的。其中 scrollWidthscrollHeight 等于视口大小 ,而 clientWidthclientHeight 等于文档内容区域的大小。
  • IE (在标准模式)中的这两组属性不相等。其中scrollWidthscrollHeight 等于文档内容区域的大小,而 clientWidthclientHeight等于视口大小.

确定文档的总高度是(包括基于视口的最小高度时),必须取得scrollWidth/clientWidth 和 scrollHeight/clientHeight 中的最大值,才能保证在跨浏览器的环境下得到精确的结果。

var docHeight = Math.max(document.documentElement.scrollHeight,
                                            document.documentElemennt.clientHeight);
var docWidth = Math.max(document.documentElement.scrollWidth,
                                          document.documentElement.clientWidth);

注意:对于运行在混杂模式下的IE,则需要用document.body代替document.documentElement

4) 确定元素大小

浏览器给每个元素提供了getBoundingClientRect()方法。这个方法返回一个矩形对象,包括4个属性:lefttoprightbottom
IE8 更早版本认为文档的左上角坐标是(2,2),而其他浏览器包括IE9则将传统的(0,0)作为起点坐标.
跨浏览器函数:


5) 遍历

“DOM2级遍历和范围” 模块 定义了两个用于辅助完成顺序遍历DOM结构的类型:NodeIteratorTreeWalker.这两个类型能够基于给定的起点对DOM结构执行深度优先(depth-first)的遍历操作。
IE不支持DOM遍历

使用下列代码可以检测浏览器对DOM2级遍历能力的支持情况

var supportsTraversals = document.implementation.hasFeature("Traversal","2.0");
var supportsNodeIterator = (typeof document.createNodeIterator == "function");
var supportsTreeWalker = (typeof document.createTreeWalker == "function");
  • NodeIterator 类型

使用document.createNodeIterator()方法 创建它的新实例。它接受下列四个参数:

  • root:想要作为搜索起点的树中的节点。
  • whatToShow: 表示要访问哪些节点的数字代码。
  • filter:是一个NodeFilter对象,或者一个表示应该接受还是拒绝某种特定节点的函数。
  • entityReferenceExpansion: 布尔值,表示是否要扩展实体引用。

whatToShow参数是一个位掩码,通过一或多个过滤器来确定要访问哪些节点。这个参数的值以常量形式在NodeFilter类型中定义,如下所示。
https://developer.mozilla.org/en-US/docs/Web/API/NodeIterator/whatToShow

filter参数指定自定义NodeFilter对象或者指定一个功能类似节点过滤器的函数。每个NodeFilter对象只有一个方法。即accept-Node();如果应该访问给定的节点,该方法返回NodeFilter.FILTER_ACCEPT,如果不应该访问给定的节点,该方法返回NodeFilter.FILTER_SKIP
下列代码展示了如何创建一个只显示<p>元素的节点迭代器.

var filter = {
      acceptNode: function(node){
            return node.tagName.toLowCase() == "p" ?
                      NodeFilter.FILTER_ACCEPT :
                      NodeFilter.FILTER_SKIP;
      }
};

var iterator = document.createNodeIterator(root, NodeFilter.SHOW_ELEMENT, filter, false);

下列代码创建一个能够范文所有类型节点的简单NodeIterator.(不指定过滤器,第三个参数传入null)

var iterator = document.createNodeIterator(document, NodeFilter.SHOW_ALL, null, false);

NodeIterator类型的两个主要方法是nextNode()previousNode().这两个方法根据情况遍历到了最后一个节点或者根节点的时候调用会返回null.

  • TreeWalker 类型
    TreeWalker是一个更能高级的版本。除了包括nextNode()previousNode()在内的相同的功能之外,这个类型还提供了下列用于在不同方向上遍历DOM结构的方法。
    • parentNode(): 遍历到当前节点的父节点
    • firstChild(): 遍历到当前节点的第一个子节点
    • lastChild(): 遍历到当前节点的最后一个子节点
    • nextSibling(): 遍历到当前节点的下一个同辈节点
    • previousSibling(): 遍历到当前节点的上一个同辈节点

创建TreeWalker对象要使用document.createTreeWalker()方法。接受的四个参数和document.createNodeIterator()方法相同:作为遍历起点的根节点、要显示的节点类型、过滤器和一个表示是否扩展实体引用的布尔值。
在这里,filter可以返回的值有所不同。除了NodeIterator那两个返回值以外,还可以使用NodeFilter.FILTER_REJECT

属性:

  • currentNode(): 表示任何遍历方法在上一次遍历中返回的节点。通过设置这个属性也可以修改遍历继续进行的起点。
var node = walker.nextNode();
alert(node === walker.currentNode); //true
walker.currentNode = document.body;    //修改起点
6) 范围

通过范围可以选择文档中的一个区域,而不必考虑节点的界限。IE以专有的方式实现了自己的范围特性。

DOM2级在Document类型中定义了createRange()方法。可以使用hasFeature()或者直接检测该方法来判断浏览器是否支持范围。
每个范围由一个range类型的实例表示。下列属性提供了当前范围在文档的位置信息

  • startContainer: 包含范围起点的节点(即选区中第一个节点的父节点)
  • startOffset: 范围在 startContainer 中起点的偏移量。如果startContainer是文本节点、注释节点或者CDATA节点,那么startOffset就是范围起点之前跳过的字符数量。否则,startOffset就是范围中第一个子节点的索引。
  • endContainer:包含范围终点的节点(即选区中最后一个节点的父节点)
  • endOffset:范围在 endConainer 中终点的偏移量(与startOffset遵循相同的取值规则)
  • commonAncestorContainer:startContainerendContainer 共同的祖先节点在文档树中位置最深的那个.

要使用范围来选择文档中的一部分,最简的方式就是使用selectNode()selectNodeContents().这两个方法都接受一个参数,即一个DOM节点,然后使用该节点中的信息来填充范围。
selectNode()方法选择整个节点,包括其子节点。
selectNodeContents()方法则只选择节点的子节点。
以下面html代码为例

<p id="p1"><b>hello</b>world</p>
var range1 = document.createRange();
var range2 = document.createRange();
var p1  =  document.getElementById("p1");
range1.selectNode(p1);  //<p id="p1"><b>hello</b>world</p>
range2.selectNodeContents(p1);  //<b>hello</b>world

为了更精细控制将哪些节点包含在范围中,还可以使用下面方法.

函数 功能
setStartBefore(refNode) 将范围的起点设置在refNode之前,因此refNode也就是范围选取中的第一个子节点。同时将startContainer属性设置为refNode.parentNode,将startOffset属性设置为refNode在其父节点的childNodes集合中的索引.
setStartAfter(refNode) 将范围的起点设置在refNode之后,因此refNode也就是不在范围之内了。其下一个同辈节点才是范围选区中的第一个子节点.
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.

创建范围后,可以使用各种方法对范围的内容进行操作了。

  • deleteContents() 删除范围所包含的内容.
  • extractContents() 删除范围所包含的内容.返回值就是范围的文档片段.
  • cloneContents() 创建范围对象的一个副本,然后在文档的其他地方插入这个副本.(返回的文档片段包含范围中节点的副本,而不是实际的节点)
  • insertNode() 在范围选取的开始处插入一个节点.
  • surroundContents() 环绕范围插入内容,接受一个参数(环绕范围内容的节点)
  • collapse() 折叠范围。接受一个参数(布尔值),表示要折叠到范围的哪一端。true表示折叠到范围的起点,false表示折叠到范围的终点.确定范围已经折叠完毕,可以检查collapsed属性.
    折叠范围.jpg

有多个范围的情况下,可以使用compareBoundaryPoints()方法来确定这些范围是否有公共的边界(起点或终点)。这些方法接受两个参数:表示比较方式的常量值和要比较的范围。常量值如下:

  • range.START_TO_START(0):比较第一个范围和第二个范围的起点。
  • range.START_TO_END(1):比较第一个范围的起点和第二个范围的终点。
  • range.END_TO_END(2):比较第一个范围和第二个范围的终点。
  • range.END_TO_START(3):比较的哥范围的终点和第二个范围的起点。
    返回值如下:
    第一个范围的点位于第二个范围中的点之前,返回-1;如果两个点相等,返回0;如果第一个范围中的点位于第二个范围中的点之后,返回1;
range1.compareBoundaryPoints(Range.START_TO_START, range2));
  • cloneRange() 复制范围,创建调用它的范围的一个副本.
  • 使用完范围,最好调用detach()方法,以便从创建范围的文档中分离出该范围。调用detach()之后,就可以放心解除对范围的引用。(range = null)

IE8及早期版本不支持DOM范围,但支持一种类型的概念。即文本范围(text range)

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

推荐阅读更多精彩内容