廖雪峰的JS教程5-瀏覽器(一)

瀏覽器(一)

(瀏覽器對象和操作DOM)

不同的瀏覽器對JavaScript支持的差異主要是承匣,有些API的接口不一樣,比如AJAX斗忌,F(xiàn)ile接口闯第。對于ES6標準市栗,不同的瀏覽器對各個特性支持也不一樣。

在編寫JavaScript的時候咳短,就要充分考慮到瀏覽器的差異填帽,盡量讓同一份JavaScript代碼能運行在不同的瀏覽器中。

瀏覽器對象

JavaScript可以獲取瀏覽器提供的很多對象诲泌,并進行操作盲赊。

window

window對象不但充當全局作用域铣鹏,而且表示瀏覽器窗口敷扫。

window對象有innerWidthinnerHeight屬性,可以獲取瀏覽器窗口的內(nèi)部寬度和高度诚卸。內(nèi)部寬高是指除去菜單欄葵第、工具欄、邊框等占位元素后合溺,用于顯示網(wǎng)頁的凈寬高卒密。

兼容性:IE<=8不支持。

'use strict';
//可以調(diào)整瀏覽器窗口大小試試:
console.log('window inner size: ' + window.innerWidth + 'x' + window.innerHeight);

對應的棠赛,還有一個outerWidthouterHeight屬性哮奇,可以獲取瀏覽器窗口的整個寬高

navigator

navigator對象表示瀏覽器的信息,最常用的屬性包括:

  • navigator.appName:瀏覽器名稱睛约;

  • navigator.appVersion:瀏覽器版本鼎俘;

  • navigator.language:瀏覽器設置的語言;

  • navigator.platform:操作系統(tǒng)類型辩涝;

  • navigator.userAgent:瀏覽器設定的User-Agent字符串贸伐。

'use strict';
console.log('appName = ' + navigator.appName);
console.log('appVersion = ' + navigator.appVersion);
console.log('language = ' + navigator.language);
console.log('platform = ' + navigator.platform);
console.log('userAgent = ' + navigator.userAgent);

請注意navigator的信息可以很容易地被用戶修改怔揩,所以JavaScript讀取的值不一定是正確的捉邢。很多初學者為了針對不同瀏覽器編寫不同的代碼,喜歡用if判斷瀏覽器版本商膊,例如:

var width:
if (getIEVersion(navigator.userAgent) < 9 {
    width = document.body.clientWidth;
    } else {
    width = window.innerWidth;
}

但這樣既可能判斷不準確伏伐,也很難維護代碼。正確的方法是充分利用JavaScript對不存在屬性返回undefined的特性晕拆,直接用短路運算符||計算:

var width = window.innerWidth || document.body.clientWidth;

screen

screen對象表示屏幕的信息秘案,常用的屬性有:

  • screen.width: 屏幕寬度,以像素為單位

  • screen.height: 屏幕高度,以像素為單位

  • screen.colorDepth: 返回顏色位數(shù)阱高,如8赚导、16、24

'use strict';
console.log('Screen size = ' + screen.width + 'x' + screen.height);

location

location對象表示當前頁面的URL信息赤惊。例如吼旧,一個完整的URL

可以用location.href獲取。要獲得URL各個部分的值未舟,可以這么寫:

location.protocol; //'http'
location.host; //'www.example.com'
location.port; //'8080'
location.pathname; // '/path/index.html'
location.search; // '?a=1&b=2'
location.hash; // 'TOP'

要加載一個新頁面圈暗,可以調(diào)用location.assign()。如果要重新加載當前頁面裕膀,調(diào)用location.reload()方法非常方便员串。

'use strict';
if (confirm('重新加載當前頁' + location.href + '?')) {
    location.reload();
} else {
    location.assign('/'); //設置一個新的URL地址
}

document

document對象表示當前頁面。由于HTML在瀏覽器中以DOM形式表示為樹形結構昼扛,document對象就是整個DOM樹的根節(jié)點寸齐。

documenttitle屬性是從HTML文檔中的<title>xxx</title>讀取的,但是可以動態(tài)改變:

'use strict';
document.title = '努力學習JavaScript抄谐!'渺鹦;

請觀察瀏覽器窗口標題的變化。

要查找DOM樹的某個節(jié)點蛹含,需要從document對象開始查找毅厚。最常用的查找是根據(jù)ID和Tag Name。

我們先準備HTML數(shù)據(jù):

<dl id="drink-menu" style="border:solid 1px #ccc; padding: 6px;">
    <dt>摩卡</dt>
    <dd>熱摩卡咖啡</dd>
    <dt>酸奶</dt>
    <dd>北京老酸奶</dd>
    <dt>果汁</dt>
    <dd>鮮榨蘋果汁</dd>
</dl>

document對象提供的getElementById()getElementsByTagName()可以按ID獲得一個DOM節(jié)點和按Tag名稱獲得一組DOM節(jié)點:

'use strict';
var menu = documnet.getElementById('drink-menu');
var drinks = document.getElementByTagNAme('dt');
var i, s, menu, drinks;

menu = documnet.getElementById('drink-menu');
menu.tagName; //'DL'
s = '提供的飲料有:';
for (i = 0; i < drinks.length; i++) {
    s = s + drinks[i].innerHTML + ',';
}
console,log(S);

document對象還有一個cookie屬性浦箱,可以獲取當前頁面的Cookie吸耿。

Cookie是由服務器發(fā)送的key-value標示符。因為HTTP協(xié)議是無狀態(tài)的酷窥,但是服務器要區(qū)分到底是哪個用戶發(fā)過來的請求咽安,就可以用Cookie來區(qū)分。當一個用戶成功登錄后竖幔,服務器發(fā)送一個Cookie給瀏覽器板乙,例如user=ABC123XYZ(加密的字符串)...,此后拳氢,瀏覽器訪問該網(wǎng)站時募逞,會在請求頭附上這個Cookie,服務器根據(jù)Cookie即可區(qū)分出用戶馋评。

Cookie還可以存儲網(wǎng)站的一些設置放接,例如,頁面顯示的語言等等留特。

JavaScript可以通過document.cookie讀取到當前頁面的Cookie:

document.cookie; //'v=123; remember = true;prefer = zh'

由于JavaScript能讀取到頁面的Cookie纠脾,而用戶的登錄信息通常也存在Cookie中玛瘸,這就造成了巨大的安全隱患,這是因為在HTML頁面中引入第三方的JavaScript代碼是允許的:

<!-- 當前頁面在wwwexample.com -->
<html>
    <head>
        <script src="http://www.foo.com/jquery.js"></script>
    </head>
    ...
</html>

如果引入的第三方的JavaScript中存在惡意代碼苟蹈,則www.foo.com網(wǎng)站將直接獲取到www.example.com網(wǎng)站的用戶登錄信息糊渊。

為了解決這個問題,服務器在設置Cookie時可以使用httpOnly慧脱,設定了httpOnly的Cookie將不能被JavaScript讀取渺绒。這個行為由瀏覽器實現(xiàn),主流瀏覽器均支持httpOnly選項菱鸥,IE從IE6 SP1開始支持宗兼。

為了確保安全,服務器端在設置Cookie時氮采,應該始終堅持使用httpOnly殷绍。

history

history對象保存了瀏覽器的歷史記錄,JavaScript可以調(diào)用history對象的back()forward ()鹊漠,相當于用戶點擊了瀏覽器的“后退”或“前進”按鈕主到。

這個對象屬于歷史遺留對象,對于現(xiàn)代Web頁面來說贸呢,由于大量使用AJAX和頁面交互镰烧,簡單粗暴地調(diào)用history.back()可能會讓用戶感到非常憤怒拢军。

新手開始設計Web頁面時喜歡在登錄頁登錄成功時調(diào)用history.back()楞陷,試圖回到登錄前的頁面。這是一種錯誤的方法茉唉。

任何情況固蛾,你都不應該使用history這個對象了。

操作DOM

由于HTML文檔被瀏覽器解析后就是一棵DOM樹度陆,要改變HTML的結構艾凯,就需要通過JavaScript來操作DOM。

始終記住DOM是一個樹形結構懂傀。操作一個DOM節(jié)點實際上就是這么幾個操作:

  • 更新:更新該DOM節(jié)點的內(nèi)容趾诗,相當于更新了該DOM節(jié)點表示的HTML的內(nèi)容;
  • 遍歷:遍歷該DOM節(jié)點下的子節(jié)點蹬蚁,以便進行進一步操作恃泪;
  • 添加:在該DOM節(jié)點下新增一個子節(jié)點,相當于動態(tài)增加了一個HTML節(jié)點犀斋;
  • 刪除:將該節(jié)點從HTML中刪除贝乎,相當于刪掉了該DOM節(jié)點的內(nèi)容以及它包含的所有子節(jié)點。

在操作一個DOM節(jié)點前叽粹,我們需要通過各種方式先拿到這個DOM節(jié)點览效。最常用的方法是document.getElementById()document.getElementsByTagName()却舀,以及CSS選擇器document.getElementsByClassName()俐填。

由于ID在HTML文檔中是唯一的稽揭,所以document.getElementById()可以直接定位唯一的一個DOM節(jié)點。document.getElementsByTagName()document.getElementsByClassName()總是返回一組DOM節(jié)點克握。要精確地選擇DOM但校,可以先定位父節(jié)點篱昔,再從父節(jié)點開始選擇,以縮小范圍始腾。

例如:

// 返回ID為'test'的節(jié)點:
var test = document.getElementById('test');
// 先定位ID為'test-table'的節(jié)點州刽,再返回其內(nèi)部所有tr節(jié)點:
var trs = document.getElementById('test-table').getElementByTagName('tr');
// 先定位ID為'test-div'的節(jié)點,再返回其內(nèi)部所有class包含red的節(jié)點:
var reds = document.getElementById('test-div').getElementsByClassName('red');

// 獲取節(jié)點test下的所有直屬子節(jié)點:
var cs = test.children;
//獲取節(jié)點test下第一個浪箭、最后一個子節(jié)點:
var first = test.firstElementChild;
var last = test.lastElementChild;

第二種方法是使用querySelector()querySelectorAll()穗椅,需要了解selector語法,然后使用條件來獲取節(jié)點奶栖,更加方便:

// 通過querySelector獲取ID為q1的節(jié)點:
var ql = document.querySelector('#ql');
// 通過querySelectorAll獲取q1節(jié)點內(nèi)的符合條件的所有節(jié)點:
var ps = ql.querySelectorAll('div.highlighted > p');

注意:低版本的IE<8不支持querySelectorquerySelectorAll匹表。IE8僅有限支持。

嚴格地講宣鄙,我們這里的DOM節(jié)點是指Element袍镀,但是DOM節(jié)點實際上是Node,在HTML中冻晤,Node包括Element苇羡、CommentCDATA_SECTION等很多種鼻弧,以及根節(jié)點Document類型设江,但是,絕大多數(shù)時候我們只關心Element攘轩,也就是實際控制頁面結構的Node叉存,其他類型的Node忽略即可。根節(jié)點Document已經(jīng)自動綁定為全局變量document度帮。

練習

如下的HTML結構:

JavaScript

Java

Python

Ruby

Swift

Scheme

Haskell

<!-- HTML結構 -->
<div id="test-div">
<div class="c-red">
    <p id="test-p">JavaScript</p>
    <p>Java</p>
  </div>
  <div class="c-red c-green">
    <p>Python</p>
    <p>Ruby</p>
    <p>Swift</p>
  </div>
  <div class="c-green">
    <p>Scheme</p>
    <p>Haskell</p>
  </div>
</div>

請選擇出指定條件的節(jié)點:

'use strict';
// 選擇<p>JavaScript</p>:
var js = document.getElementById('test-p');

// 選擇<p>Python</p>,<p>Ruby</p>,<p>Swift</p>:
var arr = document.getElementsByClassName("c-red")[1].getElementsByTagName("p");

// 選擇<p>Haskell</p>:
var haskell = document.getElementsByClassName('c-green')[1].lastElementChild;

// 測試:
if (!js || js.innerText !== 'JavaScript') {
    alert('選擇JavaScript失敗!');
} else if (!arr || arr.length !== 3 || !arr[0] || !arr[1] || !arr[2] || arr[0].innerText !== 'Python' || arr[1].innerText !== 'Ruby' || arr[2].innerText !== 'Swift') {
    console.log('選擇Python,Ruby,Swift失敗!');
} else if (!haskell || haskell.innerText !== 'Haskell') {
    console.log('選擇Haskell失敗!');
} else {
    console.log('測試通過!');
}

更新DOM

拿到一個DOM節(jié)點后歼捏,我們可以對它進行更新”颗瘢可以直接修改節(jié)點的文本瞳秽,方法有兩種:

一種是修改innerHTML屬性,這個方式非常強大冕屯,不但可以修改一個DOM節(jié)點的文本內(nèi)容寂诱,還可以直接通過HTML片段修改DOM節(jié)點內(nèi)部的子樹:

// 獲取<p id="p-id">...</p>
var p = document.getElementById('p-id');
// 設置文本為abc:
p.innerHTML = 'ABC'; // <p id="p-id">ABC</p>
// 設置HTML:
p.innerHTML = 'ABC <span style="color:red">RED</span> XYZ';
// <p>...</p>的內(nèi)部結構已修改

innerHTML時要注意,是否需要寫入HTML安聘。如果寫入的字符串是通過網(wǎng)絡拿到了痰洒,要注意對字符編碼來避免XSS攻擊瓢棒。

第二種是修改innerTexttextContent屬性,這樣可以自動對字符串進行HTML編碼丘喻,保證無法設置任何HTML標簽:

// 獲取<p id="p-id">...</p>
var p = document.getElementById('p-id');
// 設置文本:
p.innerText = '<script>alert("Hi")</script>';
// HTML被自動編碼脯宿,無法設置一個<script>節(jié)點:
// <p id="p-id">&lt;script&gt;alert("Hi")&lt;/script&gt;</p>

兩者的區(qū)別在于讀取屬性時,innerText不返回隱藏元素的文本泉粉,而textContent返回所有文本连霉。另外注意IE<9不支持textContent

修改CSS也是經(jīng)常需要的操作嗡靡。DOM節(jié)點的style屬性對應所有的CSS跺撼,可以直接獲取或設置。因為CSS允許font-size這樣的名稱讨彼,但它并非JavaScript有效的屬性名歉井,所以需要在JavaScript中改寫為駝峰式命名fontSize

// 獲取<p id="p-id">...</p>
var p = document.getElementById('p-id');
// 設置CSS:
p.style.color = '#ff0000';
p.style.fontSize = '20px';
p.style.paddingTop = '2em';

練習

有如下的HTML結構:

javascript

Java

<!-- HTML結構 -->
<div id="test-div">
  <p id="test-js">javascript</p>
  <p>Java</p>
</div>

請嘗試獲取指定節(jié)點并修改:

'use strict';

// 獲取<p>javascript</p>節(jié)點:
var js = document.getElementById('test-js');

// 修改文本為JavaScript:
js.innerText = 'JavaScript';

// 修改CSS為: color: #ff0000, font-weight: bold
js.style.color = '#ff0000';
js.style.fontWeight = 'bold';


// 測試:
if (js && js.parentNode && js.parentNode.id === 'test-div' && js.id === 'test-js') {
    if (js.innerText === 'JavaScript') {
        if (js.style && js.style.fontWeight === 'bold' && (js.style.color === 'red' || js.style.color === '#ff0000' || js.style.color === '#f00' || js.style.color === 'rgb(255, 0, 0)')) {
            console.log('測試通過!');
        } else {
            console.log('CSS樣式測試失敗!');
        }
    } else {
        console.log('文本測試失敗!');
    }
} else {
    console.log('節(jié)點測試失敗!');
}

插入DOM

當我們獲得了某個DOM節(jié)點哈误,想在這個DOM節(jié)點內(nèi)插入新的DOM哩至,應該如何做?

如果這個DOM節(jié)點是空的蜜自,例如菩貌,<div></div>,那么重荠,直接使用innerHTML = '<span>child</span>'就可以修改DOM節(jié)點的內(nèi)容箭阶,相當于“插入”了新的DOM節(jié)點。

如果這個DOM節(jié)點不是空的晚缩,那就不能這么做尾膊,因為innerHTML會直接替換掉原來的所有子節(jié)點媳危。

有兩個辦法可以插入新的節(jié)點荞彼。一個是使用appendChild,把一個子節(jié)點添加到父節(jié)點的最后一個子節(jié)點待笑。例如:

<!-- HTML結構 -->
<p id="js">JavaScript</p>
<div id="list">
    <p id="java">Java</p>
    <p id="python">Python</p>
    <p id="scheme">Scheme</p>
</div>

<p id="js">JavaScript</p>添加到<div id="list">的最后一項:

var
    js = document.getElementById('js'),
    list = document.getElementById('list');
list.appendChild(js);

現(xiàn)在鸣皂,HTML結構變成了這樣:

<!-- HTML結構 -->
<div id="list">
    <p id="java">Java</p>
    <p id="python">Python</p>
    <p id="scheme">Scheme</p>
    <p id="js">JavaScript</p>
</div>

因為我們插入的js節(jié)點已經(jīng)存在于當前的文檔樹,因此這個節(jié)點首先會從原先的位置刪除暮蹂,再插入到新的位置寞缝。

更多的時候我們會從零創(chuàng)建一個新的節(jié)點,然后插入到指定位置:

var
    list = document.getElementById('list'),
    haskell = document.createElement('p');  //新建p標簽
haskell.id = 'haskell';
haskell.innerText = 'Haskell';
list.appendChild(haskell);

這樣我們就動態(tài)添加了一個新的節(jié)點:

<!-- HTML結構 -->
<div id="list">
    <p id="java">Java</p>
    <p id="python">Python</p>
    <p id="scheme">Scheme</p>
    <p id="haskell">Haskell</p>
</div>

動態(tài)創(chuàng)建一個節(jié)點然后添加到DOM樹中仰泻,可以實現(xiàn)很多功能荆陆。舉個例子,下面的代碼動態(tài)創(chuàng)建了一個<style>節(jié)點集侯,然后把它添加到<head>節(jié)點的末尾被啼,這樣就動態(tài)地給文檔添加了新的CSS定義:

var d = document.createElement('style');
d.setAttribute('type', 'text/css');
d.innerHTML = 'p { color: red }';
document.getElementsByTagName('head')[0].appendChild(d);

可以在Chrome的控制臺執(zhí)行上述代碼帜消,觀察頁面樣式的變化。

insertBefore

如果我們要把子節(jié)點插入到指定的位置怎么辦浓体?可以使用parentElement.insertBefore(newElement, referenceElement);泡挺,子節(jié)點會插入到referenceElement之前。

還是以上面的HTML為例命浴,假定我們要把Haskell插入到Python之前:

<!-- HTML結構 -->
<div id="list">
    <p id="java">Java</p>
    <p id="python">Python</p>
    <p id="scheme">Scheme</p>
</div>

可以這么寫:

var 
    list = document.getElementById('list'),
    ref = document.getElementById('python'),
    haskell = document.createElement('p');
haskell.id = 'haskell';
haskell.innerText = 'Haskell';
list.insertBefore(haskell, ref);

新的HTML結構如下:

<!-- HTML結構 -->
<div id="list">
    <p id="java">Java</p>
    <p id="haskell">Haskell</p>
    <p id="python">Python</p>
    <p id="scheme">Scheme</p>
</div>

可見娄猫,使用insertBefore重點是要拿到一個“參考子節(jié)點”的引用。很多時候生闲,需要循環(huán)一個父節(jié)點的所有子節(jié)點媳溺,可以通過迭代children屬性實現(xiàn):

var
    i, c,
    list = document.getElementById('list');
for (i = 0; i < list.children.length; i++) {
    c = list.children[i]; //拿到第i個子節(jié)點
}

練習

對于一個已有的HTML結構:

  1. Scheme
  2. JavaScript
  3. Python
  4. Ruby
  5. Haskell
<!-- HTML結構 -->
<ol id="test-list">
    <li class="lang">Scheme</li>
    <li class="lang">JavaScript</li>
    <li class="lang">Python</li>
    <li class="lang">Ruby</li>
    <li class="lang">Haskell</li>
</ol>

按字符串順序重新排序DOM節(jié)點:

'use strict';
//sort list
//第一種解法:利用insertBefore方法進行插入   較小的插入到較大的前面

var new_list = document.getElementById('test-list');
var new_list_child = document.getElementsByClassName('lang');
for(var i=0;i<new_list_child.length;i++){
  for(var j = i+1;j<new_list_child.length;j++){
    if(new_list_child[i].innerText > new_list_child[j].innerText){
      new_list.insertBefore(new_list_child[j],new_list_child[i])
}
}
}

//第二種解法:通過 Array.protptype.slice.call().sort()  轉換數(shù)組 進行排序  forEach循環(huán)遍歷進行重新添加節(jié)點

var new_list = document.getElementById('test-list');

var new_list_child = new_list.children;

new_list_child = Array.prototype.slice.call(new_list_child).sort(function(a,b){

  return a.innerHTML > b.innerHTML?1:-1;  

});

new_list_child.forEach(function(el){

  new_list.appendChild(el);

});

//注:代碼更新之后發(fā)現(xiàn) 存在只適用于同樣大小寫的情況,也就是說大寫之間進行排序碍讯,小寫之間進行排序褂删,如果混在一起的話,例如:AfBcdE  結果為ABEcdf  這個問題后面我會注意改過來重新追加

// 測試:
;(function () {
    var
        arr, i,
        t = document.getElementById('test-list');
    if (t && t.children && t.children.length === 5) {
        arr = [];
        for (i=0; i<t.children.length; i++) {
            arr.push(t.children[i].innerText);
        }
        if (arr.toString() === ['Haskell', 'JavaScript', 'Python', 'Ruby', 'Scheme'].toString()) {
            console.log('測試通過!');
        }
        else {
            console.log('測試失敗: ' + arr.toString());
        }
    }
    else {
        console.log('測試失敗!');
    }
})();

刪除DOM

刪除一個DOM節(jié)點就比插入要容易得多冲茸。

要刪除一個節(jié)點屯阀,首先要獲得該節(jié)點本身以及它的父節(jié)點,然后轴术,調(diào)用父節(jié)點的removeChild把自己刪掉:

//拿到待刪除節(jié)點:
var self = document.getElementById('to-be-removed');
//拿到父節(jié)點:
var parent = self.parentElement;
// 刪除:
var removed = parent.removeChild(self);
removed === self; //true

注意到刪除后的節(jié)點雖然不在文檔樹中了难衰,但其實它還在內(nèi)存中,可以隨時再次被添加到別的位置逗栽。

當你遍歷一個父節(jié)點的子節(jié)點并進行刪除操作時盖袭,要注意,children屬性是一個只讀屬性彼宠,并且它在子節(jié)點變化時會實時更新鳄虱。

例如,對于如下HTML結構:

<div id="parent">
    <p>First</p>
    <p>Second</p>
</div>

當我們用如下代碼刪除子節(jié)點時:

var parent = document.getElementById('parent');
parent.removeChild(parent.children[0]);
parent.removeChild(parent.children[1]); // <-- 瀏覽器報錯

瀏覽器報錯:parent.children[1]不是一個有效的節(jié)點凭峡。原因就在于拙已,當<p>First</p>節(jié)點被刪除后,parent.children的節(jié)點數(shù)量已經(jīng)從2變?yōu)榱?摧冀,索引[1]已經(jīng)不存在了倍踪。

因此,刪除多個節(jié)點時索昂,要注意children屬性時刻都在變化建车。

練習

  • JavaScript
  • Swift
  • HTML
  • ANSI C
  • CSS
  • DirectX
<!-- HTML結構 -->
<ul id="test-list">
    <li>JavaScript</li>
    <li>Swift</li>
    <li>HTML</li>
    <li>ANSI C</li>
    <li>CSS</li>
    <li>DirectX</li>
</ul>

把與Web開發(fā)技術不相關的節(jié)點刪掉:

'use strict';
//答案1
var web = ["JavaScript", "HTML", "CSS"];
var ul = document.getElementById("test-list");
for (var li of ul.children) {
    if (web.indexOf(li.innerText) === -1) {
        ul.removeChild(li);
    }
};

//答案2
var parent = document.getElementById('test-list');
var children = [].slice.call(parent.children); //Array.prototype.slice.call()
children.forEach((element) => {
    for (var s of ['Swift', 'ANSI C', 'DirectX']) {
        if (element.innerText == s) {
            parent.removeChild(element);
        }
    }
});

// 測試:
;(function () {
    var
        arr, i,
        t = document.getElementById('test-list');
    if (t && t.children && t.children.length === 3) {
        arr = [];
        for (i = 0; i < t.children.length; i ++) {
            arr.push(t.children[i].innerText);
        }
        if (arr.toString() === ['JavaScript', 'HTML', 'CSS'].toString()) {
            console.log('測試通過!');
        }
        else {
            console.log('測試失敗: ' + arr.toString());
        }
    }
    else {
        console.log('測試失敗!');
    }
})();
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市椒惨,隨后出現(xiàn)的幾起案子缤至,更是在濱河造成了極大的恐慌,老刑警劉巖康谆,帶你破解...
    沈念sama閱讀 217,185評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件领斥,死亡現(xiàn)場離奇詭異错洁,居然都是意外死亡,警方通過查閱死者的電腦和手機戒突,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,652評論 3 393
  • 文/潘曉璐 我一進店門屯碴,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人膊存,你說我怎么就攤上這事导而。” “怎么了隔崎?”我有些...
    開封第一講書人閱讀 163,524評論 0 353
  • 文/不壞的土叔 我叫張陵今艺,是天一觀的道長。 經(jīng)常有香客問我爵卒,道長虚缎,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,339評論 1 293
  • 正文 為了忘掉前任钓株,我火速辦了婚禮实牡,結果婚禮上,老公的妹妹穿的比我還像新娘轴合。我一直安慰自己创坞,他們只是感情好,可當我...
    茶點故事閱讀 67,387評論 6 391
  • 文/花漫 我一把揭開白布受葛。 她就那樣靜靜地躺著题涨,像睡著了一般。 火紅的嫁衣襯著肌膚如雪总滩。 梳的紋絲不亂的頭發(fā)上纲堵,一...
    開封第一講書人閱讀 51,287評論 1 301
  • 那天,我揣著相機與錄音闰渔,去河邊找鬼席函。 笑死,一個胖子當著我的面吹牛澜建,可吹牛的內(nèi)容都是我干的向挖。 我是一名探鬼主播,決...
    沈念sama閱讀 40,130評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼炕舵,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了跟畅?” 一聲冷哼從身側響起咽筋,我...
    開封第一講書人閱讀 38,985評論 0 275
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎徊件,沒想到半個月后奸攻,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體蒜危,經(jīng)...
    沈念sama閱讀 45,420評論 1 313
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,617評論 3 334
  • 正文 我和宋清朗相戀三年睹耐,在試婚紗的時候發(fā)現(xiàn)自己被綠了辐赞。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,779評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡硝训,死狀恐怖响委,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情窖梁,我是刑警寧澤赘风,帶...
    沈念sama閱讀 35,477評論 5 345
  • 正文 年R本政府宣布,位于F島的核電站纵刘,受9級特大地震影響邀窃,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜假哎,卻給世界環(huán)境...
    茶點故事閱讀 41,088評論 3 328
  • 文/蒙蒙 一瞬捕、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧舵抹,春花似錦山析、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,716評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至赊淑,卻和暖如春爵政,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背陶缺。 一陣腳步聲響...
    開封第一講書人閱讀 32,857評論 1 269
  • 我被黑心中介騙來泰國打工钾挟, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人饱岸。 一個月前我還...
    沈念sama閱讀 47,876評論 2 370
  • 正文 我出身青樓掺出,卻偏偏與公主長得像,于是被迫代替她去往敵國和親苫费。 傳聞我的和親對象是個殘疾皇子汤锨,可洞房花燭夜當晚...
    茶點故事閱讀 44,700評論 2 354

推薦閱讀更多精彩內(nèi)容