Layui框架】layer.photos()遇到动态加载图片的时候出现问题

  • [1. 问题]
    • [1.1 问题描述]
    • [1.2 代码]
  • [2. 第一个问题的解决]
    • [2.1 一开始的解决:]
    • [2.2 最没有错误的解决办法]
      - [2.2.1 解决办法的思路:]
      - [2.2.2 实现]
  • [3. 第二个问题的解决思路过程]
    • [3.1 初始详细描述]
    • [3.2 找错步骤一:看源码]
    • [3.3 步骤二:从浏览器控制台定位错误出现的地方]
    • [3.4 步骤三:根据正常的流程走一遍]
    • [3.5 步骤四:新开一个页面,对比,继续寻找错误:]
    • [3.6 步驟五 打开谷歌浏览器的调试工具,在js设置断点]
    • [3.7 总结一下到目前的进度]
      - [3.7.1 我的进度]
      - [3.7.2 问题本质]
    • [3.8 这个问题的终极解决步骤]
  • [4. 总结]

1. 问题

1.1. 问题描述

当layer.photo()作用的区域内的图片是动态加载产生的的时候,出现两个问题。

  • 一次性加载一个图片之后,方法不生效;第二次加载图片,方法方才生效;且常出现最后一张图片点击之后一直转圈,加载不出来的情况。
  • 点击图片显示图片总共多少张,即i/n中n显示异常。继上一个问题,点击放大查看第一张图片图片,显示1/1张,再点击第二张图片,显示2/2;在加载正常的情况下,若直接点击最后一张图片,则显示2/2张。

1.2. 代码

  • HTML代码
<div class="layui-upload">
    <button type="button" class="layui-btn layui-btn-primary" id="uploadpics">选择图片</button>
    <blockquote id="blockquote_pics" class="layui-elem-quote layui-quote-nm" style="display: none; margin-top: 10px;">
        预览图:
        <div class="layui-upload-list" id="pics" lay-filter="pics"></div>
    </blockquote>
</div>
  • 图片上传的js代码
upload.render({
    elem: '#uploadpics',
    url: '/upload/',
    multiple: true,
    size: 1000 //限制文件大小,单位 KB
        ,
    number: 9,
    before: function(obj) {
        $('#blockquote_pics').show();
        //预读本地文件示例,不支持ie8
        obj.preview(function(index, file, result) {
            $('#pics').append('<img src="' + result + '" alt="' + file.name + '" class="layui-upload-img">')
        });
}
});
  • 这里定义了一个方法,写在fun.js里。就是封装了的layer.photos()
function layerphotos() {
        console.log("layer.photos() start.");
        layer.photos({
            photos: '#pics',
            anim: 5 //0-6的选择,指定弹出图片动画类型,默认随机(请注意,3.0之前的版本用shift参数)
        });
    }; 

2. 第一个问题的解决

2.1. 一开始的解决:

把图片预览显示的代码放在动态生成代码的一起,紧跟着动态生成图片的代码。

obj.preview(function(index, file, result) {
    $('#pics').append('<img src="' + result + '" alt="' + file.name + '" class="layui-upload-img">')
    layerphotos();
}

这个问题,一开始的想法是:在页面加载完成之后执行layerphotos();方法,但根据控制台调试输出的结果发现,页面加载完成的时候方法起作用的div里没有图片,后续加载图片也不会起作用的。

这个值得注意,用控制台输出console.log()的方法判断js代码的执行顺序。

但是,这个问题解决了的原因,还是没有想明白。

目前这个解决方案的不合理之处在于:我如果在图片都加载完成之后,即在preview()函数执行完之后使用photos函数,理论上来说其效果一致,实则不然。考虑这个方法可能是非同步执行。

2.2. 最没有错误的解决办法

2.2.0.1. 解决办法的思路:

layerphotos();方法调用放在图片都加载到页面完成之后,而不是在每一张图片加载之后。

放在每一张图片加载之后并不合理,我们需要在图片全部加载之后才调用layerphotos();去渲染这个div。要使得图片全部加载完成之后再调用这个方法,我们可以在photos()的三个回调函数中解决。

  • before回调函数里,获取这次加载的图片数量,在循环执行完毕(加载完毕)之后执行layerphotos();方法。
  • error回调函数里,判断一共有多少张照片,确保加载完毕执行layerphotos();方法。
  • done回调函数里,执行layerphotos();方法。

这里,三个回调函数,以及before回调函数里执行循环的函数function(index, file, result),其都是非同步执行的。但我们需要达到的效果是,在循环完全执行完毕之后再去执行layerphotos();方法。

2.2.0.2. 实现

  • 修改upload模块源码upload.js,暴露出before回调中获取文件数量的接口
    因为我要在before中动态加载上传的图片,所以要在before回调中获取文件数量。然后在我使用浏览器调试工具仔细分析发现,layui2.3.0版本中,upload模块暴露出来的接口只有四个函数:


    upload模块before回调暴露出的接口

    图片里的fileLength_()是我在源码中找到暴露接口的位置加进去的:

    g = {
        preview: function(e) {
            o.preview(e)
        },
        upload: function(e, i) {
            var t = {};
            t[e] = i, o.upload(t)
        },
        pushFile: function() {
            return o.files = o.files || {}, layui.each(o.chooseFiles, function(e, i) {
                o.files[e] = i
            }), o.files
        },
        resetFile: function(e, i, t) {
            var n = new File([i], t);
            o.files = o.files || {}, o.files[e] = n
        }
        //--------------------------add------------------------
        ,
        fileLength_: function() {
            return o.fileLength
        }
    },
  • 获取此次加载的图片数量fileLength
  • 获取目前一共加载了的图片的数量pics_num_amount
  • 在before的循环中计数,或者error中计数,得到已经加载完毕的图片数量 pics_current
  • pics_current === pics_num的时候,调用layerphotos();方法。因为此时,所有图片在div中的加载渲染都已经确保完成。
before: function(obj) {
        var fileLength = obj.fileLength_();     //获取本次上传的图片数量
        pics_num_amount = pics_num_load + fileLength;   //目前一共加载了的图片的数量
        console.log("pics_num_amount = " + pics_num_amount + ", fileLength = " + fileLength);
        $('#blockquote_pics').show();           //显示这div
        
        //预读本地文件示例,不支持ie8
        obj.preview(function(index, file, result) {
            $('#pics').append('<img id="img_o_' + index + '" src="' + result + '" alt="' + file.name + '" class="layui-upload-img">')
            pics_cur ++;                        //加载中  实时更新的已经加载了的图片总数
            console.log("pics_num_amount = " + pics_num_amount + " pics_cur = " + pics_cur);
            if(pics_cur == pics_num_amount) {       //都加载完毕了
                layerphotos('pics');                    //调用layer.photos() 此时调用能保证div中的图片加载完全了
            }
        });
        pics_num_load += fileLength;
    },

3. 第二个问题的解决思路过程

3.1. 初始详细描述

  1. 初始状态:div为空


    初始div不可见
  2. 上传一张图片


    上传一张图片

    点击图片正常显示
  3. 再上传两张图片


    现在是三张

    点击第一张仍然显示1/1

    点击第二张显示2/3正常

    再上传一张点击第二张仍然是2/3,不正确。点击第四张后恢复正确。


    再上传第五张,直接点第五张图片,显示加载中
  • 出现控制台报错:
Uncaught TypeError: Cannot read property 'src' of undefined
    at Object.r.photos (layer.js:2)
    at HTMLImageElement.<anonymous> (layer.js:2)
    at HTMLDivElement.dispatch (jquery-3.2.1.min.js:3)
    at HTMLDivElement.q.handle (jquery-3.2.1.min.js:3)

就这样,卡在了这个地方。

3.2. 找错步骤一:看源码

layer.js中有photos()方法

3.3. 步骤二:从浏览器控制台定位错误出现的地方

s.loadi = r.load(1, {
        shade: !("shade"in t) && .9,
        scrollbar: !1
    }),
    o(u[d].src, function(n) {
        r.close(s.loadi),
        s.index = r.open(i.extend({
            type: 1,
            id: "layui-layer-photos",
            area: function() {
                var a = [n.width, n.height]
                    , o = [i(e).width() - 100, i(e).height() - 100];
                if (!t.full && (a[0] > o[0] || a[1] > o[1])) {
                    var r = [a[0] / o[0], a[1] / o[1]];
                    r[0] > r[1] ? (a[0] = a[0] / r[0],
                    a[1] = a[1] / r[0]) : r[0] < r[1] && (a[0] = a[0] / r[1],
                    a[1] = a[1] / r[1])
                }
                return [a[0] + "px", a[1] + "px"]
            }(),
            ...
},

看目前的状况,似乎是这样的:

当页面动态加载出图片,此时

photos() 这个方法似乎是异步方法,不是同步方法。其传入的参数t,也就是图片数据,可以用这行代码打印出:

        console.log(t.photos.data);

不对不对,不是异步方法。

这个方法是在点击图片这个事件被触发的时候调用的方法 。!

if(n || p.on("click", t.img, function() {
    var e = i(this),
        n = e.attr("layer-index");
    r.photos(i.extend(t, {    //就是在这里调用的
        photos: {
            start: n,
            data: u,
            tab: t.tab
        },
        full: t.full
    }), !0), h()
}), !n) return

3.4. 步骤三:根据正常的流程走一遍

我写了四处注释,加载一个在页面加载完毕就能把所有图片都加载好的页面,其效果是这样的:

首先,会进入这个方法。但并不是通过我调用方法的入口进入方法的。(就是说我写的console.log("layer.photos() start.");这一句代码并没有执行;我写在layui.use(layer)中的console.log(" * * * * * * layui.use('layer') * * *");

001 -- photos 方法调用--r.photos = function(t, n, a)   &  t.photos.data:
undefined
002 ---图片数据u=f.data: u.length = 0 startIndex:d = 0 ---s.imgIndex = 1

紧接着,由于加载出来了四组图片(4个div),会调用四次layer.photos()方法
此时加载了layer模块:

* * * * * *  layui.use('layer') * * *

然后,四个div的执行结果大同小异,以第一个div为例:

photos 方法启动 & id = #friendpics0
layer.js:531  001 -- photos 方法调用--r.photos = function(t, n, a)   &  t.photos.data:
layer.js:532 undefined
layer.js:548 002 ---图片数据u=f.data: u.length = 0 startIndex:d = 0 ---s.imgIndex = 1
layer.js:557 003 -- 方法h()调用  & e = 0
layer.js:557 003 -- 方法h()调用  & e = 1
layer.js:557 003 -- 方法h()调用  & e = 2
VM10684:122 photos 方法执行完毕 & id = #friendpics0

可以看出,注册这个事件的主要逻辑应该在h()这个方法内部

h = function() {
                        
        u = [], p.find(t.img).each(function(e) {
            console.log("003 -- 方法h()调用  & e = " + e);
            var t = i(this);
            t.attr("layer-index", e), u.push({
                alt: t.attr("alt"),
                pid: t.attr("layer-pid"),
                src: t.attr("layer-src") || t.attr("src"),
                thumb: t.attr("src")
            })
        })
    };

这个方法内部,通过循环遍历这个div内的所有img,其中e是index。
然后点击第一张图:

图片显示、序号都正常

控制台消息:
这是点击第一张图片后的控制台消息

点击另两张图片的效果也是一样的。首先004调用了点击事件所注册的函数,在这个函数内部,调用了photos()方法。

至此,一次完整的,正确的操作完毕。问题就出在动态加载。

3.5. 步骤四:新开一个页面,对比,继续寻找错误:

依旧,一步步记录。值得注意的是,这也页面,我只有一个div,只是不断更新其内的内容。

  1. 打开页面,也是会不经过我的调用就执行这个方法:
 001 -- photos 方法调用--r.photos = function(t, n, a)   &  t.photos.data:
layer.js:532 undefined
layer.js:548 002 ---图片数据u=f.data: u.length = 0 startIndex:d = 0 ---s.imgIndex = 1

1.1. 动态加载出一张图片,控制台输出:

VM372:4 element.render()
VM372:5 layer.photos() start.
layer.js:531  001 -- photos 方法调用--r.photos = function(t, n, a)   &  t.photos.data:
layer.js:532 undefined
layer.js:548 002 ---图片数据u=f.data: u.length = 0 startIndex:d = 0 ---s.imgIndex = 1
layer.js:557 003 -- 方法h()调用  & e = 0
VM372:14 layer.photos() end.

首先更新渲染(不知道有没有用),然后通过我的调用启动了方法。因为只有一张图片,e = 0说明此时,这个用来遍历div的循环正常执行。

1.2. 然后点击这张图片,显示正常,此时控制台输出是:

layer.js:571 004 -- p.on(click, t.img, function() {}  &  e = [object Object]  n = e.attr(layer-index) = 0
layer.js:531  001 -- photos 方法调用--r.photos = function(t, n, a)   &  t.photos.data:
layer.js:532 [{…}]
layer.js:548 002 ---图片数据u=f.data: u.length = 1 startIndex:d = 0 ---s.imgIndex = 1
layer.js:608 005 -- 这里是几个函数定义之后 -- u = : 
layer.js:609 [{…}]
layer.js:610 --u.length = 1 d = 0src: data:image/jpeg;base64,.../这里的记录是一段乱码,超长,疑点1/...
layer.js:557 003 -- 方法h()调用  & e = 0
控制台输出
  1. 然后加载第二张图片。同样的,加载时候首先输出:


    加载第二张图片之后的输出

    可以看出,遍历正常。

2.1. 然后点击第一张图片,控制台输出:

第一张图片点击之后的控制台输出

004点击了index为0的图片,也就是第一张图片
001方法调用,显示photos.data的数据有两条,正常
002 ---图片数据u=f.data: u.length = 2 startIndex:d = 0 ---s.imgIndex = 1长度为2说明有两张图片,显示正常;当前图片的编号index为1,这也正常。
003循环正常
但点击显示不正常,显示的是 1/1 .
这个点击事件有一个疑点,就是它会执行两次,控制台上会有两条一模一样的输出,我这里只截取了一个输出。

2.2. 然后点击第二张图片,控制台输出:

第二张图片点击之后的控制台输出

004点击index为1的图片,也就是第二张图片
001方法调用,显示photos.data的数据有两条,正常
002 ---图片数据u=f.data: u.length = 2 startIndex:d = 1 ---s.imgIndex = 2当前图片编号2,正常。
003循环正常
点击图片显示正常2/2

2.3. 然后再点击第一张图片,1/2显示正常,控制台输出:


再点击第一张图片之后的显示

比较可疑的点:为什么会调用两次。

  1. 进行了一些小操作
    3.1 刷新页面
    3.2 上传一张图片,再上传一张图片。这个期间不点击图片。控制台输出就是:


    先后上传两张图片时候的控制台输出

    和预想的一致:
    首先加载了photos()函数,什么操作都没完成。
    然后加载出第一张图片之后,调用了这个方法。循环遍历发现img只有一个。
    然后加载出第二张图片,调用了这个方法,循环遍历发现img有两个。
    一切正常。
    3.3 点击第一张图片,控制台输出两组记录:
    第一组记录:


    注意中间部分获取到的photos.data只有一条记录

    第二组记录:
    注意中间部分获取到的photos.data两条记录

    此时,点开的图片显示1/1,是不正常的。但因为我看到了第二组记录其实更新正常了,所以在想,此时重新点开第一张图片,显示应该是正常的1/2。果真如此。

也就是说,我在点击第一张图片的时候,其会执行两遍photos函数,因为有两个img,而当且仅当都执行完的时候,显示才是正确的。

同样的,再新增一张图片,控制台有三组输出,前两组输出中展示的photos都是两张,最后一组输出展示的是三张。

现在的问题变成:为什么我点击第一张图片,click事件注册的函数为什么会多次执行?在一个正常的操作了,控制台输出很简洁:


正常操作

现在明白了报错src undefined的问题。因为只有在我们点击了已经存在着的照片的时候,新加进去的照片才会被被被发现?被photos.data这个数组所容纳。所以如果你直接点击新加进去的图片,自然是undefined。

哈哈哈我现在的状态是,知道什么时候肯定会出什么错。

  • 比如我一次性加载三张图片,先点击第一张图片,此时后台调用三次click事件绑定的方法(click事件作用的元素是同一个元素),而在第一次完成后图片就正常显示了,此时显示的序号是1/1。然后再点击后边任意的图片,由于之前三次click已经完成了,现在无论怎么点击,显示的都是正常的。
  • 如果我一次性加载三张图片,直接点击第三张图片,此时后台直接调用第三张图片的点击事件,这时候必然报错,因为没被发现。这个时候被发现的图片是第一张图片,所以第三张图片的信息是undefined。

3.6. 步驟五 打开谷歌浏览器的调试工具,在js设置断点

  1. 同时上传两张图片。此时,上传图片的before(){}方法内部,遍历div中的所有图片,在每一个图片时候调用一次photos()方法。解决这个问题的办法是将这个函数的调用语句放在done和error回调函数中,控制在图片都加载完成之后调用。
  2. 之前说,点击一张图片之后,后台会调用若干次click事件注册的方法。现在发现,这个次数和photos()函数的执行次数有关系。我现在先后两次分别上传了5张图片,之后第三次上传图片,点击第一张图片,后台执行三次click事件绑定的函数:第一次显示photos.data只有10张,第二次显示10张,这都是第三次上传的图片还没有被发现的时候的数据,第三次执行,就显示11张,就正常了。

3.7. 总结一下到目前的进度

3.7.0.3. 我的进度

  1. 我做了什么? --把相对本质的问题暴露出来了,其他问题都得到了解决。
    比如页面加载就调用方法。
  2. 现在的问题
  • 展现上:上传一张图片,再上传一张图片,点击第一张图片查看,序号是1/1,此时第二张图片尚未被发现,重新打开第一张图片,序号是1/2。
  • 后台执行上:上传一张图片,再上传一张图片,点击第一张图片查看,此时会调用两次点击事件绑定的方法。第一次调用的时候显示只有一张图片,此时图片显示出来;第二次调用的时候显示有两张图片,此时图片因为已经显示出来了,所以正确的没法显示。

3.7.0.4. 问题本质

分析到现在,问题很明确了。在我多次加载图片之后,点击第一张图片,此时后台会依次“发现”所有被加载的图片,然而第一次过程之后就展示了图片,所以导致序号显示不正确,以及加载完毕就点击后加载的图片会显示不出来。

解决思路是,控制图片显示的时机。

3.8. 这个问题的终极解决步骤

  • 原本的做法 ( layer.js )
    点击图片,依次“发现”被加载的图片。
  • 现在的做法,点击图片,判断所有被加载的图片是不是都被“发现”了,如果是,再执行图片显示的操作。

我把我在源码上做的改动和一些注释,以及控制台输出语句处理一下,注意注释里加了------的和星号*的是我修改了的地方,粘贴到这里:(为了不影响其他操作,本着防止牵一发而动全身的基本理念,我把修改后的方法命名为photos_dynamic() (layer.js))

var pic_amount = 0;                     //------ 变量定义  图片计数器
var pic_acount_valid = false;           //------ 变量定义  图片计数器有效检验
r.photos_dynamic= function(t, n, a) {
    ...
    if(t = t || {}, t.photos) {          //t就是传入的photos数据
        if(delete t.success, l) {} else {
            var p = i(t.photos),
            h = function() {                //h函数的定义 遍历所有图片 设置属性 因为要遍历所有图片,所以在这里计数
                pic_acount_valid = false;           //* 计数器无效
                u = [], p.find(t.img).each(function(e) {    //循环
                    pic_amount = e+1;               //* 计数器计数
                    ...};
            pic_acount_valid = true;     //* ------ 当h()遍历完所有的图片,也就是图片计数器数值有效,置为true
            ...
            if(n || p.on("click", t.img, function() {        //图片被点击时候调用的函数 
                ...                                         //这里调用了photos函数 用来“发现所有的图片” 也就是说点击图片之后执行语句会在这个方法内部再次调用photos_dynamic()
                r.photos_dynamic(i.extend(t, { ... },}),!0), h()}), !n) return
    }
    ... //一些函数的定义 前一张后一张等
    if(pic_acount_valid === true, u.length === pic_amount) {        //------ 判断计数器有效,且当前被发现的数据u的差哪个都和计数器计数数量一致 说明所有图片都已经被发现
        console.log("006 --成功 -- 自己加的判断:pic_acount_valid === " + pic_acount_valid + " " + "u.length = " + u.length + " " + "pic_amount = " + pic_amount);
        o(u[d].src, function(n) {
            r.close(s.loadi), s.index = r.open(i.extend({ ... }(),               //设置区域大小等  用layer.open()打开弹出窗
            }, t))                  //设置open()的一些属性
        },
            ...     //设置关闭弹窗的一下属性 
    }
    else {
        console.log("006 --失败 -- 自己加的判断:pic_acount_valid === " + pic_acount_valid + " " + "u.length = " + u.length + " " + "pic_amount = " + pic_amount);
    }}}, ... //其余的一些函数定义等
}()

就是在这里判断一下计数器和图片数量是不是一致的,只有是一致的的时候才执行open()方法。

4. 总结

截至目前,问题都得到了解决。我在确保不影响模块本身的功能,以及layer.photos()方法本身的功能的基础上,修改了一下源码。对源码的修改主要有两处:

  • upload.js模块 暴露出获取文件数量的接口;
  • layer.js模块,新增了layer在处理页面动态加载出的数据的时候的合理处理。

这次遇到的这个问题,对于我的项目来说并不是关键的东西,但我认为这是比较基本的应该实现的效果,所以我查了源码,用了浏览器调试,甚至修改了框架代码。

尽管如此,我并不认为我这是最好的解决。

  • 我不知道为什么框架没有暴露出获取文件数量的接口,也许是出于自身考虑。我们的确可以在循环中设置计数器,这样虽然能获取到文件数量,但由于这个回调函数是非同步执行,我如果将这个数据运用到其他回调中,必然会出现问题。
  • 如果是在一个div中动态加载出来的图片,框架原本的做法,会多次调用图片的点击事件。
    • 合理操作中,当页面加载图片完毕,点击某一张图片,触发这个图片的点击事件,此时点击事件内就应该已经捕获到这个div最新的所有图片。
    • 但实际中,点击图片,会多次触发这个图片的点击事件(见文中的截图),并且,图片加载操作有几次,此时就触发了几次点击事件。并且前几次触发点击事件时候事件所捕获的div内的内容是上一次更新的内容,直到最后一次点击事件被触发。这是为什么呢?

layui框架给了我很多帮助成长,期待更新!ayui框架给了我很多帮助成长,期待更新!

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