UDN-企业互联网技术人气社区

板块导航

浏览  : 242
回复  : 2

[原生js] 优雅的使用Js或CSS处理文本的截断与展示

[复制链接]
泡泡兔的头像 楼主
发表于 2017-1-4 15:08:46 | 显示全部楼层 |阅读模式
  之前遇见一个问题,就是处理文本截断,然后可以手动切换文本是全展示和手动展示,因为这个问题比较常见,而且其实现方式有多种,于是决定总结一下,与读者分享。

  前言 

  首先,我们看这样一个场景:
1.png

  其html 结构如下:
  1.     <p class="text-slice">
  2.         郑成月的经历就是一部中国社会历史!很有价值的!不管是社会研究还是真心纠错,都是非常好的案例。历史就是用各种个人经历写成的,那样就很有实在感。作家们没有素材?都在书写歌功颂德之文?想要把自己的作品流传后世,这就是最好的素材
  3.     </p>
  4.     <label class="expand-more">更多</label>
复制代码

  样式如下:
  1.     .text-slice {
  2.         display: -webkit-box;
  3.         -webkit-box-orient: vertical;
  4.         -webkit-line-clamp: 3;
  5.         overflow: hidden;
  6.         text-overflow: ellipsis;
  7.     }
复制代码

  如图,我们对文字默认展示内容有限制:限制默认最多显示三行,未超出三行时不需要展示更多按钮;超出内容被截断时,可以点击更多,展示全部内容,此时更多文字变成取消,再次点击的时候文字收起。

  实现上述功能,常见的是使用JavaScript,本文将介绍使用JavaScript和CSS共三种方式实现:

  • Js实现
  • CSS :target伪类 实现
  • CSS :checked伪类 + ~(临近兄弟节点选择符)实现

  Js实现

  先从最常见的Js实现,通常我们绑定点击事件实现切换文本截断与展示全部:

  点击查看效果
  1.     <script>
  2.         $(function() {
  3.             var $para = $('.content');
  4.             var $more = $('.expand-more');
  5.             $more.on('click', function() {
  6.                 $para.toggleClass('text-slice');
  7.                 if ($para.hasClass('text-slice')) {
  8.                     $more.html('更多');
  9.                 } else {
  10.                     $more.html('收起');
  11.                 }
  12.             });
  13.         });
  14.     </script>
复制代码

  如上,给按钮绑定点击事件,在事件回调中为文本切换实现截断样式的类名,并同时修改按钮文字,很简单。

  但是,到目前为止我们应该发现一个问题吧,假如文本内容少于三行或者刚好三行,我们怎么判断是否需要展示切换按钮呢?

  思考。。。。。。

  要判断文本是否发生截断,怎么处理呢?

  计算字数肯定不可行,因为涉及到不同手机,不同浏览器,不同字符,会有差异;

  计算高度,比较展示全部和添加截断时的高度值是否相等,相等时,说明不会截断;不相等则说明发生截断。

  判断文本是否截断

  我们不能直接使用该段落元素做判断,用户体验很不好,我们可以添加一个辅助段落元素:
  1.     <p class="fake-content text-slice">
  2.         郑成月的经历就是一部中国社会历史!很有价值的!不管是社会研究还是真心纠错,都是非常好的案例。历史就是用各种个人经历写成的,那样就很有实在感。作家们没有素材?都在书写歌功颂德之文?想要把自己的作品流传后世,这就是最好的素材
  3.     </p>
复制代码

  样式如下:
  1.     .fake-content {
  2.         position: absolute;
  3.         z-index: -1; /* 隐藏 */
  4.         opacity: 0; /* 透明 */
  5.         pointer-events: none; /*元素不可交互/点击*/
  6.     }
复制代码

  然后比较此元素在设置截断样式和不设置截断样式时高度,相等即不会发生截断,不相等即发生截断:
  1.     // 文本是否发生截断
  2.     function hasTextSliced($ele) {
  3.         var initHeight = $ele.height();
  4.         var height;
  5.         $ele.removeClass('text-slice'); // 删除截断样式
  6.         height = $ele.height();

  7.         if (initHeight < height) {
  8.             // 发生截断
  9.             return true;
  10.         }

  11.         return false;
  12.     }
复制代码

  如上,在删除截断样式后,若高度变大,则说明发生文本截断,否则不发生截断。

  CSS实现

  CSS可以有两种方式实现:

  • :target伪类 实现
  • :checked伪类 + ~(临近兄弟节点选择符)实现

  点击查看实例

  :target伪类

  我们知道HTML中,a链接可以设置锚点,点击后该锚点可以使用 :target 伪类选择获取,于是可以为其设置文字不截断样式:
  1.     #content:target {
  2.         overflow: auto;
  3.         display: block;
  4.     }
复制代码

  其html结构如下:
  1.     <p class="content text-slice" id="content">
  2.         ...        
  3.     </p>
  4.     <p class="fake-content text-slice">
  5.         ...
  6.     </p>
  7.     <a class="expand-more" href="#content">更多</a>
复制代码

  :checked伪类 + ~选择符

  此种方式原理是,选择框可以使用CSS伪类 :checked 获取,然后通过 ~ 选择符給元素设置样式不截断文本:
  1.     #expand-check:checked ~ .content {
  2.         overflow: auto;
  3.         display: block;
  4.     }
复制代码

  html结构如:
  1.     <input type="checkbox" id="expand-check" style="display: none;pointer-events: none;">
  2.     <p class="content text-slice">
  3.         ...
  4.     </p>
  5.     <p class="fake-content-2 text-slice">
  6.         ...
  7.     </p>
  8.     <label class="expand-more" for="expand-check">更多</label>
复制代码

  如上,通过在文本前面添加一个隐藏的· <input type="checkbox">元素 ,在更多按钮中使用label的for属性,通过设置 <label class="expand-more" for="expand-check"> 使其点击时可以改变前面添加的选择框元素的checked状态,从而实现切换效果。

  总结

  不同的方式都能实现效果,那什么情况适合使用哪一种呢,现进行比较:

  • 对比Js和CSS方式,Js实现可配置性,操作性强,而CSS实现有一定限制,无法在切换展示的同时进行其他Js处理;但是CSS实现更稳定,高效,代码,出错性小,js错误不影响此功能,在内容展示型页面适合使用。
  • 对比:target伪类和:checked伪类,前者代码量少,不需要添加额外元素,但是我们知道锚点点击时,页面是会滚动锚点元素到当前页面顶部的,这不适合长页面。
  • :checked伪类方式需要为每一个需要切换展示的段落都添加额外辅助元素,因此不适于在长列表中使用,如评论列表,新闻简介列表页。

  本篇中实例详细代码参考https://github.com/codingplayboy/web_demo/tree/master/smallcase/expand_more

相关帖子

发表于 2017-1-4 15:09:16 来自手机 | 显示全部楼层
总觉得哪里有点问题啊
使用道具 举报

回复

发表于 2017-1-4 15:09:17 | 显示全部楼层
OMG!介是啥东东
使用道具 举报

回复

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关于我们
联系我们
  • 电话:010-86393388
  • 邮件:udn@yonyou.com
  • 地址:北京市海淀区北清路68号
移动客户端下载
关注我们
  • 微信公众号:yonyouudn
  • 扫描右侧二维码关注我们
  • 专注企业互联网的技术社区
版权所有:用友网络科技股份有限公司82041 京ICP备05007539号-11 京公网网备安1101080209224 Powered by Discuz!
快速回复 返回列表 返回顶部