# JavaScript 事件這回事兒

NARUTOne

引言:js的事件機(jī)制在web開發(fā)中的出鏡率是很高,但是要想給事件機(jī)制拍出高顏值的效果歼冰,還是很難的靡狞。本篇將會(huì)介紹javascript事件機(jī)制這回事兒。

參考:最詳細(xì)的JavaScript和事件解讀

你若觸發(fā)隔嫡,我就處理——淺談JavaScript的事件響應(yīng)

MDN

事件有哪些

//獲取window事件
var log = document.getElementById('log'),
i = '', 
out = [];
for (i in window) {
  if ( /^on/.test(i)) { out[out.length] = i; }
}
log.innerHTML = out.join(', ');

可以發(fā)現(xiàn)甸怕,事件家族成員還是很龐大的。

標(biāo)準(zhǔn)事件屬性列表

事件綁定監(jiān)聽

html內(nèi)聯(lián)綁定

<a href='javascript:;' onclick="alert('你點(diǎn)擊了這個(gè)a');">點(diǎn)擊</a>

顯而易見腮恩,使用這種方法梢杭,JavaScript 代碼與 HTML 代碼耦合在了一起,不便于維護(hù)和開發(fā)秸滴。所以除非在必須使用的情況(例如統(tǒng)計(jì)鏈接點(diǎn)擊數(shù)據(jù))下武契,盡量避免使用這種方法。

DOM屬性綁定

element.onclick = function(event){
    alert('你點(diǎn)擊了這個(gè)按鈕');
};

直接賦值給對(duì)應(yīng)屬性荡含,如果你在后面代碼中再次為 element 綁定一個(gè)回調(diào)函數(shù)吝羞,會(huì)覆蓋掉之前回調(diào)函數(shù)的內(nèi)容。

事件監(jiān)聽

element.addEventListener(<event-name>, <callback>, <use-capture>);

表示在 element 這個(gè)對(duì)象上面添加一個(gè)事件監(jiān)聽器内颗。

1钧排、當(dāng)監(jiān)聽到有 <event-name> 事件發(fā)生的時(shí)候。

2均澳、調(diào)用 <callback> 這個(gè)回調(diào)函數(shù)恨溜。

3、至于 <use-capture> 這個(gè)參數(shù)找前,表示該事件監(jiān)聽是在“捕獲”階段中監(jiān)聽(設(shè)置為 true)還是在“冒泡”階段中監(jiān)聽(設(shè)置為 false)糟袁。大部分設(shè)置在冒泡階段。

var btn = document.getElementsByTagName('button');
btn[0].addEventListener('click', function() {
    alert('你點(diǎn)擊了這個(gè)按鈕');
}, false);

移除監(jiān)聽

element.removeEventListener(<event-name>, <callback>, <use-capture>);

需要注意的是躺盛,綁定事件時(shí)的回調(diào)函數(shù)不能是匿名函數(shù)项戴,必須是一個(gè)聲明的函數(shù),因?yàn)榻獬录壎〞r(shí)需要傳遞這個(gè)回調(diào)函數(shù)的引用槽惫,才可以斷開綁定周叮。

var fun = function() {
    // function logic
};

element.addEventListener('click', fun, false);
element.removeEventListener('click', fun, false);

add: addEventListener是用來注冊(cè)事件的辩撑,通常第二個(gè)參數(shù)我們傳入的是一個(gè)回調(diào)函數(shù);但是也可以傳一個(gè)object,只需要這個(gè)object具有handleEvent屬性即可仿耽。

事件觸發(fā)過程

事件綁定后合冀,那事件發(fā)生時(shí)是如何確認(rèn)發(fā)生對(duì)象和觸發(fā)的呢,過程詳看w3c UI Events

捕獲階段(Capture Phase)

當(dāng)我們?cè)?DOM 樹的某個(gè)節(jié)點(diǎn)發(fā)生了一些操作(例如單擊项贺、鼠標(biāo)移動(dòng)上去)君躺,就會(huì)有一個(gè)事件發(fā)射過去。這個(gè)事件從 Window 發(fā)出开缎,不斷經(jīng)過下級(jí)節(jié)點(diǎn)直到目標(biāo)節(jié)點(diǎn)棕叫。在到達(dá)目標(biāo)節(jié)點(diǎn)之前的過程,就是捕獲階段(Capture Phase)奕删。

所有經(jīng)過的節(jié)點(diǎn)俺泣,都會(huì)觸發(fā)這個(gè)事件。捕獲階段的任務(wù)就是建立這個(gè)事件傳遞路線急侥,以便后面冒泡階段順著這條路線返回 Window砌滞。

監(jiān)聽某個(gè)在捕獲階段觸發(fā)的事件,需要在事件監(jiān)聽函數(shù)傳遞第三個(gè)參數(shù) true坏怪。

element.addEventListener(<event-name>, <callback>, true);

目標(biāo)階段(Target Phase)

當(dāng)事件跑啊跑贝润,跑到了事件觸發(fā)目標(biāo)節(jié)點(diǎn)那里,最終在目標(biāo)節(jié)點(diǎn)上觸發(fā)這個(gè)事件铝宵,就是目標(biāo)階段打掘。

需要注意的時(shí),事件觸發(fā)的目標(biāo)總是最底層的節(jié)點(diǎn)鹏秋。比如你點(diǎn)擊一段文字尊蚁,你以為你的事件目標(biāo)節(jié)點(diǎn)在 div 上,但實(shí)際上觸發(fā)在 <p>侣夷、<span> 等子節(jié)點(diǎn)上横朋。

document.addEventListener('click', function(e){
    alert(e.target.tagName);
}, false);

冒泡階段(Bubbling Phase)

當(dāng)事件達(dá)到目標(biāo)節(jié)點(diǎn)之后,就會(huì)沿著原路返回百拓,由于這個(gè)過程類似水泡從底部浮到頂部琴锭,所以稱作冒泡階段。

在實(shí)際使用中衙传,你并不需要把事件監(jiān)聽函數(shù)準(zhǔn)確綁定到最底層的節(jié)點(diǎn)也可以正常工作决帖。比如在上例,你想為這個(gè)div 綁定單擊時(shí)的回調(diào)函數(shù)蓖捶,你無須為這個(gè) div 下面的所有子節(jié)點(diǎn)全部綁定單擊事件地回,只需要為 div 這一個(gè)節(jié)點(diǎn)綁定即可。因?yàn)榘l(fā)生它子節(jié)點(diǎn)的單擊事件,都會(huì)冒泡上去刻像,發(fā)生在 div 上面畅买。

事件機(jī)制FQA

為什么不用第三個(gè)參數(shù) true(捕獲)

在使用 addEventListener 函數(shù)來監(jiān)聽事件時(shí),第三個(gè)參數(shù)設(shè)置為 false绎速,這樣監(jiān)聽事件時(shí)只會(huì)監(jiān)聽冒泡階段發(fā)生的事件皮获。

這是因?yàn)?IE 瀏覽器不支持在捕獲階段監(jiān)聽事件焙蚓,為了統(tǒng)一而設(shè)置的纹冤,畢竟 IE 瀏覽器的份額是不可忽略的。

利用事件代理監(jiān)聽提升性能 (Event Delegate)

因?yàn)槭录忻芭輽C(jī)制购公,所有子節(jié)點(diǎn)的事件都會(huì)順著父級(jí)節(jié)點(diǎn)跑回去萌京,所以我們可以通過監(jiān)聽父級(jí)節(jié)點(diǎn)來實(shí)現(xiàn)監(jiān)聽子節(jié)點(diǎn)的功能,這就是事件代理宏浩。

使用事件代理主要有兩個(gè)優(yōu)勢(shì):

  • 減少事件綁定知残,提升性能。之前你需要綁定一堆子節(jié)點(diǎn)比庄,而現(xiàn)在你只需要綁定一個(gè)父節(jié)點(diǎn)即可求妹。減少了綁定事件監(jiān)聽函數(shù)的數(shù)量。
  • 動(dòng)態(tài)變化的 DOM 結(jié)構(gòu)佳窑,仍然可以監(jiān)聽制恍。當(dāng)一個(gè) DOM 動(dòng)態(tài)創(chuàng)建之后,不會(huì)帶有任何事件監(jiān)聽神凑,除非你重新執(zhí)行事件監(jiān)聽函數(shù)净神,而使用事件監(jiān)聽無須擔(dān)憂這個(gè)問題。
<ul id="resources">
  <li><a >MDN</a></li>
  <li><a >HTML5 Doctor</a></li>
  <li><a >HTML5 Rocks</a></li>
  <li><a >Expressive Web</a></li>
  <li><a >CreativeJS</a></li>
</ul>
var resources = document.querySelector('#resources'),
    log = document.querySelector('#log');
 
resources.addEventListener('mouseover', showtarget, false);
 
function showtarget(ev) {
  var target = ev.target;
  if (target.tagName === 'A') {
    log.innerHTML = 'A link, with the href:' + target.href;
  }
  if (target.tagName === 'LI') {
    log.innerHTML = 'A list item';
  }
  if (target.tagName === 'UL') {
    log.innerHTML = 'The list itself';
  }
}

使用原生的方式實(shí)現(xiàn)事件代理溉委,需要注意過濾非目標(biāo)節(jié)點(diǎn)

element.addEventListener('click', function(event) {
    // 判斷是否是 a 節(jié)點(diǎn)
    if ( event.target.tagName == 'A' ) {
        // a 的一些交互操作
    }
}, false);

停止事件冒泡(stopPropagation)

比較復(fù)雜的應(yīng)用鹃唯,由于事件監(jiān)聽比較復(fù)雜,可能會(huì)希望只監(jiān)聽發(fā)生在具體節(jié)點(diǎn)的事件瓣喊。這個(gè)時(shí)候就需要停止事件冒泡坡慌。停止事件冒泡需要使用事件對(duì)象的 stopPropagation 方法

element.addEventListener('click', function(event) {
    event.stopPropagation();
}, false);

事件對(duì)象
當(dāng)一個(gè)事件被觸發(fā)的時(shí)候,會(huì)創(chuàng)建一個(gè)事件對(duì)象(Event Object)藻三,這個(gè)對(duì)象里面包含了一些有用的屬性或者方法洪橘。事件對(duì)象會(huì)作為第一個(gè)參數(shù),傳遞給我們的毀掉函數(shù)趴酣。我們可以使用下面代碼梨树,在瀏覽器中打印出這個(gè)事件對(duì)象:標(biāo)準(zhǔn)事件屬性列表

<button>打印 Event Object</button>

<script>
    var btn = document.getElementsByTagName('button');
    btn[0].addEventListener('click', function(event) {
        console.log(event);
    }, false);
</script>

默認(rèn)事件禁止preventDefault

這個(gè)方法可以禁止一切默認(rèn)的行為,例如點(diǎn)擊 a 標(biāo)簽時(shí)岖寞,會(huì)打開一個(gè)新頁面抡四,如果為 a 標(biāo)簽監(jiān)聽事件 click同時(shí)調(diào)用該方法,則不會(huì)打開新頁面。

<a href="www.baidu.com" id='jump'>是否跳轉(zhuǎn)呢指巡?</a>

document.getElementById('jump').addEventListener('click', function(e) {
    alert('會(huì)跳轉(zhuǎn)到www.baidu.com淑履??藻雪?');
    e.preventDefault();
}, false)

IE下的事件差異兼容

IE 下綁定事件

在 IE 下面綁定一個(gè)事件監(jiān)聽秘噪,在 IE9- 無法使用標(biāo)準(zhǔn)的 addEventListener 函數(shù),而是使用自家的attachEvent勉耀,具體用法:

element.attachEvent(<event-name>, <callback>);

其中 <event-name> 參數(shù)需要注意指煎,它需要為事件名稱添加 on 前綴,比如有個(gè)事件叫 click便斥,標(biāo)準(zhǔn)事件監(jiān)聽函數(shù)監(jiān)聽 click至壤,IE 這里需要監(jiān)聽 onclick。

另一個(gè)枢纠,它沒有第三個(gè)參數(shù)像街,也就是說它只支持監(jiān)聽在冒泡階段觸發(fā)的事件,所以為了統(tǒng)一晋渺,在使用標(biāo)準(zhǔn)事件監(jiān)聽函數(shù)的時(shí)候镰绎,第三參數(shù)傳遞 false。

當(dāng)然木西,這個(gè)方法在 IE9 已經(jīng)被拋棄畴栖,在 IE11 已經(jīng)被移除了,IE 也在慢慢變好户魏。O(∩_∩)O~

** IE中的Event **

IE 中往回調(diào)函數(shù)中傳遞的事件對(duì)象與標(biāo)準(zhǔn)也有一些差異驶臊,你需要使用 window.event 來獲取事件對(duì)象。所以你通常會(huì)寫出下面代碼來獲取事件對(duì)象:

event = event || window.event

此外還有一些事件屬性有差別叼丑,比如比較常用的 event.target 屬性关翎,IE 中沒有,而是使用 event.srcElement來代替鸠信。如果你的回調(diào)函數(shù)需要處理觸發(fā)事件的節(jié)點(diǎn)纵寝,那么需要寫:

node = event.srcElement || event.target;

用 JavaScript 模擬觸發(fā)內(nèi)置事件

內(nèi)置的事件也可以被 JavaScript 模擬觸發(fā),dispatchEvent()

function simulateClick() {
  var event = new MouseEvent('click', {
    'view': window,
    'bubbles': true,
    'cancelable': true
  });
  var cb = document.getElementById('checkbox'); 
  var canceled = !cb.dispatchEvent(event);
  if (canceled) {
    // A handler called preventDefault.
    alert("canceled");
  } else {
    // None of the handlers called preventDefault.
    alert("not canceled");
  }
}

自定義事件

內(nèi)置的事件會(huì)由瀏覽器根據(jù)某些操作進(jìn)行觸發(fā)星立,自定義的事件就需要人工觸發(fā)爽茴。dispatchEvent 函數(shù)就是用來觸發(fā)某個(gè)事件

自定義事件的函數(shù)有 Event、CustomEvent 和 dispatchEvent

使用 Event 構(gòu)造函數(shù)

var event = new Event('build');

// Listen for the event.
elem.addEventListener('build', function (e) { ... }, false);

// Dispatch the event.
elem.dispatchEvent(event);

CustomEvent創(chuàng)建
CustomEvent 可以創(chuàng)建一個(gè)更高度自定義事件绰垂,還可以附帶一些數(shù)據(jù)室奏。

var myEvent = new CustomEvent(eventname, options);

var options = {
    detail: {
        ...
    },
    bubbles: true,
    cancelable: false
}

element.dispatchEvent(customEvent);

detail 可以存放一些初始化的信息,可以在觸發(fā)的時(shí)候調(diào)用劲装。其他屬性就是定義該事件是否具有冒泡等等功能胧沫。

在 element 上面觸發(fā) customEvent 這個(gè)事件昌简。結(jié)合起來用就是:

// add an appropriate event listener
obj.addEventListener("cat", function(e) { process(e.detail) });

// create and dispatch the event
var event = new CustomEvent("cat", {"detail":{"hazcheeseburger":true}});
obj.dispatchEvent(event);

使用自定義事件需要注意兼容性問題,而使用 jQuery 就簡(jiǎn)單多了:

// 綁定自定義事件
$(element).on('myCustomEvent', function(){});

// 觸發(fā)事件
$(element).trigger('myCustomEvent');

此外绒怨,你還可以在觸發(fā)自定義事件時(shí)傳遞更多參數(shù)信息:

$( "p" ).on( "myCustomEvent", function( event, myName ) {
  $( this ).text( myName + ", hi there!" );
});
$( "button" ).click(function () {
  $( "p" ).trigger( "myCustomEvent", [ "John" ] );
});

事件解耦

我們可以將一個(gè)整個(gè)的功能纯赎,分割成獨(dú)立的小功能,每個(gè)小功能綁定一個(gè)事件南蹂,由一個(gè)“控制器”負(fù)責(zé)根據(jù)條件觸發(fā)某個(gè)事件犬金。這樣,在外面觸發(fā)這個(gè)事件六剥,也可以調(diào)用對(duì)應(yīng)功能晚顷,使其更加靈活。

這里推薦 cowboy 開發(fā)的 Tiny Pub Sub仗考,通過 jQuery 實(shí)現(xiàn)

(function($) {

  var o = $({});

  $.subscribe = function() {
    o.on.apply(o, arguments);
  };

  $.unsubscribe = function() {
    o.off.apply(o, arguments);
  };

  $.publish = function() {
    o.trigger.apply(o, arguments);
  };

}(jQuery));

媒體事件

videoaudio這倆很潮的玩意也有一大堆事件供我們使用音同。比如有趣的time事件词爬,它可以告訴我們這首歌或電影的已播放時(shí)長(zhǎng)秃嗜。

其他設(shè)備事件

我們知道,瀏覽器提供了與鼠標(biāo)鍵盤的交互顿膨,但這還遠(yuǎn)遠(yuǎn)不夠滿足我們更多的硬件交互需求锅锨。比如檢測(cè)手機(jī)或平板電腦傾斜度的Device orientation和 touch events。the Gamepad API讓我們可以在瀏覽器中做游戲控制恋沃;postMessage讓我們可以在瀏覽器各窗口之間進(jìn)行跨域消息傳遞必搞;pageVisibility讓我們可以得知瀏覽器中當(dāng)前標(biāo)簽頁可見狀態(tài)。甚至當(dāng)window的history對(duì)象有操作時(shí)也能監(jiān)聽的到囊咏。查看window對(duì)象的事件列表恕洲,有的可能已經(jīng)被實(shí)現(xiàn)了,還有更多的在謀劃中……

嘛梅割,不管瀏覽器是否會(huì)支持霜第,最終都是要支持的嘛,這些是剛需户辞。我們只要默默等待就可以了泌类,騷年,向著夕陽奔跑吧底燎!=v=

總結(jié)

綁定刃榨、捕獲、冒泡双仍、委托及瀏覽器兼容枢希。

1、綁定三種方式:

①onEle = fun模式 :

②addEventListener('ele', fun, bool)模式:

③attachEvent('onEle', fun, bool)模式:

2朱沃、默認(rèn)事件行為阻止(一般):

①on模式:

ele.onclick = function() {
    ……                         //你的代碼
    return false;              //通過返回false值阻止默認(rèn)事件行為
};

②addEventListener()模式:

element.addEventListener("click", function(e){
    var event = e || window.event;
    ……
    event.preventDefault( );      //阻止默認(rèn)事件
},false);

③attachEvent()模式 IE

element.attachEvent("onclick", function(e){
    var event = e || window.event;
    ……
    event.returnValue = false;       //阻止默認(rèn)事件
},false);

3苞轿、兼容綁定、解綁

// 事件綁定
function addEvent(element, eType, handle, bol) {
    if(element.addEventListener){           //如果支持addEventListener
        element.addEventListener(eType, handle, bol);
    }else if(element.attachEvent){          //如果支持attachEvent
        element.attachEvent("on"+eType, handle);
    }else{                                  //否則使用兼容的onclick綁定
        element["on"+eType] = handle;
    }
}

// 事件解綁
function removeEvent(element, eType, handle, bol) {
    if(element.addEventListener){
        element.removeEventListener(eType, handle, bol);
    }else if(element.attachEvent){
        element.detachEvent("on"+eType, handle);
    }else{
        element["on"+eType] = null;
    }
}

4、冒泡

// 阻止事件的進(jìn)一步傳播呕屎,包括(冒泡让簿,捕獲),無參數(shù)
 event.stopPropagation( );                
 
event.cancelBubble = true;  // true 為阻止冒泡秀睛,IE

5尔当、事件委托:利用事件冒泡的特性,將里層的事件委托給外層事件蹂安,根據(jù)event對(duì)象的屬性進(jìn)行事件委托椭迎,改善性能。
使用事件委托能夠避免對(duì)特定的每個(gè)節(jié)點(diǎn)添加事件監(jiān)聽器田盈;事件監(jiān)聽器是被添加到它們的父元素上畜号。事件監(jiān)聽器會(huì)分析從子元素冒泡上來的事件,找到是哪個(gè)子元素的事件允瞧。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末简软,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子述暂,更是在濱河造成了極大的恐慌痹升,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,590評(píng)論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件畦韭,死亡現(xiàn)場(chǎng)離奇詭異疼蛾,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)艺配,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,157評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門察郁,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人转唉,你說我怎么就攤上這事皮钠。” “怎么了酝掩?”我有些...
    開封第一講書人閱讀 169,301評(píng)論 0 362
  • 文/不壞的土叔 我叫張陵鳞芙,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我期虾,道長(zhǎng)原朝,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 60,078評(píng)論 1 300
  • 正文 為了忘掉前任镶苞,我火速辦了婚禮喳坠,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘茂蚓。我一直安慰自己壕鹉,他們只是感情好剃幌,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,082評(píng)論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著晾浴,像睡著了一般负乡。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上脊凰,一...
    開封第一講書人閱讀 52,682評(píng)論 1 312
  • 那天抖棘,我揣著相機(jī)與錄音,去河邊找鬼狸涌。 笑死切省,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的帕胆。 我是一名探鬼主播朝捆,決...
    沈念sama閱讀 41,155評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼懒豹!你這毒婦竟也來了芙盘?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 40,098評(píng)論 0 277
  • 序言:老撾萬榮一對(duì)情侶失蹤歼捐,失蹤者是張志新(化名)和其女友劉穎何陆,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體豹储,經(jīng)...
    沈念sama閱讀 46,638評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,701評(píng)論 3 342
  • 正文 我和宋清朗相戀三年淘这,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了剥扣。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,852評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡铝穷,死狀恐怖钠怯,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情曙聂,我是刑警寧澤晦炊,帶...
    沈念sama閱讀 36,520評(píng)論 5 351
  • 正文 年R本政府宣布,位于F島的核電站宁脊,受9級(jí)特大地震影響断国,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜榆苞,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,181評(píng)論 3 335
  • 文/蒙蒙 一稳衬、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧坐漏,春花似錦薄疚、人聲如沸碧信。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,674評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽砰碴。三九已至,卻和暖如春板丽,著一層夾襖步出監(jiān)牢的瞬間衣式,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,788評(píng)論 1 274
  • 我被黑心中介騙來泰國(guó)打工檐什, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留碴卧,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 49,279評(píng)論 3 379
  • 正文 我出身青樓乃正,卻偏偏與公主長(zhǎng)得像住册,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子瓮具,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,851評(píng)論 2 361

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