用原生 js && jquery 完成知乎收起答案功用

《用原生 js && jquery 完成知乎收起答案功用》《用原生 js && jquery 完成知乎收起答案功用》

  • Update 2016.12.7
  • 已封装为插件

    • 原生 js 插件$ npm install foldcontent-zhihu@">=3.0.12" --save Usage
    • jquery 插件 $ npm install foldcontent-zhihu-jquery@">=1.0.1" --save Usage
  • Update 2016.11.23
  • 此前demo 定义两个按钮,一个牢固定位,一个相对定位,因而转动至底部时会涌现两个按钮同时涌现的题目,用户体验不是很好,因而变动成只要一个按钮,推断转动至底部时增加 classname 变动款式。且精简了代码ヾ(≧∇≦*)ゝ
  • scroll 事宜机能优化题目。

    • 鼠标转动时 scroll 事宜触发的间隔大约为 10~20 ms,相对于其他的鼠标、键盘事宜,它被触发的频次很高,间隔很近。因而假如 scroll 事宜触及大批的位置盘算、元素重绘等事情,且这些事情没法在下个 scroll 事宜触发前完成,就会致使浏览器掉帧
    • 因而须要削减绑定给 scroll 中详细想要实行的营业逻辑的实行次数
    • 并将对象初始化、稳定的高度值等缓存在 scroll 事宜外部
    • 存在 bug : 当以很快的速率转动时,有能够实行不到 scroll 绑定的事宜(ó﹏ò),有没得更好的优化计划?
  • 示例代码及 github 均已更新 ٩(ˊᗜˋ*)و
  • Update 2016.11.22
  • 优化代码构造,存在定名不范例、jquery 要领和原生 js 要领混用、代码未封装、设想冗余等题目。。。review 代码被批了。。。
    《用原生 js && jquery 完成知乎收起答案功用》

没有需求的话……就本身提一个 ୧(๑•̀⌄•́๑)૭

  • 起初是要做一个公司内部的 mongoDB 日记查询网站,前端用 bootstrap,后端用 nodejs 做了一个简朴的页面,不得不说页面照样很粗陋的,由于一条日记的内容许多,假如直接显现的话内容太甚冗杂,每每转动频频才看完一条日记,而且常常查询的就是牢固的几个 key,直接展现不利于敏捷debug。
  • 题目肯定了,要完成的就是显现日记时只显现常常查询的几个键值对,点击睁开时显现悉数日记,点击收起时变回原状。
  • 需求很简朴,而且和知乎的显现悉数&&收起功用异常相似,然则 Google 了一下没有找到相似的 demo,因而决议本身完成一个!

Here we go

  • 看了知乎的网页代码。道理是点击显现悉数时,假如这条答案超越浏览器视窗,则收起按钮变成牢固定位,js 盘算出 right 值,bottom牢固为12px;当这条答案底部转动至浏览器视窗内,收起按钮变回相对定位。ps 发明知乎是不是是改版了,之前答案底部涌如今浏览器视窗内后这个位置是有收起按钮的?,按钮从牢固定位变成相对定位并变动款式,就像旁边的作者保存权益如许的作风~(图一直传不上来。。临时摒弃了)
  • 如今的做法是直接隐蔽掉牢固定位的收起按钮。

《用原生 js && jquery 完成知乎收起答案功用》

  • 实在我的完成要领和知乎的不甚雷同,由于他的 js 代码我至心……没看懂!谁能告诉我这类状况应当怎样调试(ノ°ο°)ノ

《用原生 js && jquery 完成知乎收起答案功用》

  • 所以想了另一种思绪,在答案右下角定义一个按钮 A,推断答案顶部和底部的相对位置 x 和 y ,个中 y = x + 答案的高度(js 猎取)。当答案涌如今浏览器视窗内,即 x = $(window).height() 时,给 A 增加牢固定位,动态定义 right 值;当答案行将滚出浏览器视窗,即 y = $(window).height() 时,A 变成相对定位,right 值一直为 20px。当 A 的文本内容为收起时,点击 A 文本内容变成睁开,去掉牢固定位。
  • 此处省去连接数据库等无关事情,仅用两段风趣的笔墨作为 demo ~
  • 起首,笔墨内容分为 all-content 和 part-content 两部分,分别为摺叠前和摺叠后要展现的内容,由于还未搞懂知乎摺叠答案后显现哪一部分内容的算法,所以简朴粗犷地分了摺叠前和摺叠后的内容。。此处有一个 TODO ?
<ul class="wrap">
    <li>
        <div class="content all-content" style="display: none;">
            <h2>Sheldon 坐位理论</h2>
            <p>In the winter that seat is close enough to the radiator to remain warm 
            and yet not so close as to cause perspiration. 
            In the summer it's directly in the path of a cross breeze 
            created by opening windows there, and there. 
            It faces the television at an angle that is neither direct, 
            thus discouraging conversation, 
            nor so far wide to create a parallax distortion. I could go on,
            but ... I think I've made my point.</p>
            <p>冬季的时刻,这个处所离电暖器很近、最温煦,然则又不会近到让你觉得热、流汗;
                炎天的时刻,这里又能够吹由那两扇窗户吹进来的冉冉轻风;
                坐这的角度能够让我同时看电视又同时和别人谈天而不受影响,
                恰好不会太远也不会发生视觉上的错觉。</p>
            <p>That is my spot. In an ever-changing world it is a simple point of consistency.
                If my life were expressed as a function in a four-dimensional Cartesian coordinate system,
                that spot, at the moment I first sat on it, would be 0000.</p>
            <p>那是我的专座。在这个不停变化的天下里,这是稳定的一点。
                假定我的性命用一个建立在四维直角坐标系里的方程来示意的话,
                这个坐位从我坐上那一刻最先就成为了(0,0,0,0)。</p>
        </div>

        <div class="content part-content">
            In the winter that seat is close enough to the radiator to remain warm 
            and yet not so close as to cause perspiration. 
            In the summer
            <b> ...</b>
        </div>

        <div class="sign unfold">睁开</div>
    </li>
</ul>
var doc = $(document);
var win = $(window);
// 屡次运用, 缓存起来
doc.on('click', '.unfold', function () {
    var unfold = $(this);
    if (unfold.text() !== '收起') {
        unfold.text('收起').siblings('.part-content').hide().siblings('.all-content').show();
        var panel = unfold.parent();
        var panelScroll = panel.offset().top + panel.height();
        var scrollHeight = doc.scrollTop() + win.height();
        var right = win.width() / 2 - 350 + 20 > 20 ? win.width() / 2 - 350 + 20 : 20;
        // 点击睁开按钮时即推断是不是涌现收起按钮
        if (scrollHeight - panelScroll < 50) {
            unfold.addClass('fold-fix').css('right', right);
        }
        // 绑定在 scroll 事宜上
        var cb = {
            onscroll: function() {
                var panelScroll = panel.offset().top + panel.height();
                var scrollHeight = doc.scrollTop() + win.height();
                var right = win.width() / 2 - 350 + 20 > 0 ? win.width() / 2 - 350 + 20 : 20;
                if (scrollHeight - panelScroll < 50 &&
                    panel.offset().top - scrollHeight < -90 && unfold.text() !== '睁开') {
                    unfold.addClass('fold-fix').css('right', right);
                } else {
                    changeStyle(unfold);
                }
                win.off("scroll", cb.onscroll);
                setTimeout(function() {
                    win.on("scroll", cb.onscroll);
                }, 50);
            }
        };
        win.on("scroll", cb.onscroll);
    } else {
        var fold = $(this);
        changeStyle(fold);
        fold.text('睁开').siblings('.part-content').show()
            .siblings('.all-content').hide();
    }
});

function changeStyle(i) {
    i.removeClass('fold-fix').css('right', '20px');
}
  • 此处触及一个知识点:网页元素的相对位置 && 相对位置

    • 网页元素的相对位置,指该元素的左上角相对于整张网页左上角的坐标。jquery 中 offset() 要领返回元素相对于文档的偏移。该要领返回的对象包括两个整型属性:top 和 left。x.offset().top 即为 x 元素的相对高度;
    • 网页元素的相对位置,指该元素左上角相对于浏览器窗口左上角的坐标。相对位置减去页面的转动条转动的间隔就是相对位置。x.offset().top - $(document).scrollTop() 即为 x 元素的相对高度。
    • 本例须要浏览器视窗方才转动至答案a的相对定位按钮涌现的结果,因而此节点为答案底部的相对高度减去浏览器视窗高度恰好即是负的按钮 A 的高度。即 a.offset().top + a.height() – $(document).scrollTop() – $(window).height() = – 按钮高度
    • 阮一峰先生的用Javascript猎取页面元素的位置这篇文章解说得非常清楚,假如要深切相识这个知识点发起看一下这篇文章,说不定就有恍然大悟的觉得哦 ٩(ˊᗜˋ*)و
  • 怎样动态设置牢固定位的摺叠按钮 的 right 值呢?

    • 答案的牢固宽度是 700px,因而浏览器视窗宽度减去 700px 再除以 2 便一直是答案的 right 值,由于按钮为相对定位时 right: 20px; 因而 right: $(window).width()/2 – 350 + 20 就保证了牢固定位和相对定位时按钮都在一条垂直线上,过渡连接很天然。
    • 当浏览器窗口不停缩小时,上面盘算出的牢固定位时按钮的 right 值能够为负,这明显不符合需求,因而要设置当盘算出的 right 值为负时设置 right 值为 20px。

catch the code

  • 源代码已上传至 my github (ㆆᴗㆆ) ?
    原文作者:一颗板栗
    原文地址: https://segmentfault.com/a/1190000007503399
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞