网页闯关游戏(riddle webgame)--仿微信聊天的前端页面设计和难点

摘要:
break-all允许在单词内换行。keep-all只能在半角空格或连字符处换行。

前言:
之前编写了一个网页闯关游戏(类似Riddle Game), 除了希望大家能够体验一下我的游戏外. 也愿意分享编写这个网页游戏过程中, 学到的一些知识.
本文讲描述, 如何在网页端实现一个仿微信的聊天窗口界面, 以及其中涉及到的一些技术点. 作者前端是初学者, 请大拿们轻拍.

效果展示:
先打下广告: 网页闯关游戏入口(请狠狠地点击我, ^_^) .
仿微信窗口的设计源于第四关--倾听女神的故事.

网页闯关游戏(riddle webgame)--仿微信聊天的前端页面设计和难点第1张

这种聊天对话的布局模式, 比PC端QQ的那种聊天方式更贴近移动端, 我个人感觉.

需求设定:
让我们先过一遍, 实现该聊天窗口需要支持的一些功能点.
聊天消息结构和布局
聊天消息包括: 人物(头像)和消息内容. 朋友消息位居左侧, 自己消息则位于右侧, 方便区分.
文本区域的自适应
消息内容可以自适应大小, 总是以最合理的区域大小包裹.
网页闯关游戏(riddle webgame)--仿微信聊天的前端页面设计和难点第2张
滚动支持
因聊天记录太多, 大小超过聊天窗口的预设尺寸.
底部自动对齐
有新消息后, 窗口内容自动对齐到可视窗口的底部.
Enter键捕获
消息的输入支持, 以及捕获响应Enter键.
这几个功能点中, 感觉最难的是文本区域自适应处理, 走了不少弯路, ^_^.

实现方案:
聊天消息结构和布局
基本的html代码结构可以如下所示:

<div>
    <img src="https://tool.4xseo.com/article/31430.html" alt="头像"/> <div>消息内容</div>
</div>

注: 头像为一个img标签, 文本消息内容则为一个div, 包裹两者的是另一个大的div, 代表完整的一个消息.
对于布局的左偏移和右偏移, 则借助float:left|right, 来进行控制, 这个还是基础的.
文本区域的自适应
为了让聊天的文本内容显得美观, 最好方式就是自适应的文本区域(有个max-width, 区域最小化).
最初的时候, 我尝试了textarea标签, 因为其属性有row和col, 对应字符个数单位, 可以用于设定行数和列数.
可惜的是, 我被现实打败了, 因为textarea对中文字符和英文字符的计算标准不同, 中文字符按2个算, 英文字符按1个算. 因为用户输入的不确定, 导致很难用文本串的长度来设定textarea的行列值.
于是回到起点, 只能走计算文本像素点px长度的方式来设定大小(等价于限定max-width).
计算文本的长度, 参考于"JQuery 计算文本的总宽度 Width".

function GetCurrentStrWidth(text, font) {
    var currentObj = $('<pre>').hide().appendTo(document.body);
    $(currentObj).html(text).css('font', font);
    var width = currentObj.width();
    currentObj.remove();
    return width;
}

注: 巧妙的通过添加/删除<pre>标签, 返回<pre>的真实长度, 既文本长度.
对于小于预设的max-width, 则文本区域div缺省即可. 对于大于预设的max-width值, 则文本区域div设定为width=max-width.

var maxWidth = 320;
var currentFont = "normal 13px Helvetica, Arial, sans-serif";
msgDiv.style.font = currentFont;
var currentWidth = GetCurrentStrWidth(message, currentFont);
// *) 设定文本区域的宽度
if (currentWidth <= maxWidth) {
  msgDiv.style.width = "" + currentWidth + "px";
} else {
  msgDiv.style.width = "" + maxWidth + "px";
}

当然这边还有一个需要的注意的地方, 就是自动换行.

word-break: normal|break-all|keep-all;
值 描述
normal 使用浏览器默认的换行规则。
break-all 允许在单词内换行。
keep-all 只能在半角空格或连字符处换行。

为了防止太长的英文单词(非常规词)的影响, 最后选用了word-break: break-all.
滚动支持
滚动支持, 相对简单, 只需要聊天对话框在y轴方向设定如下css属性即可:

overflow-y : scroll;

底部自动对齐
这个也是老生常谈的事了, 每次聊天窗口的内容有更新, 执行如下js代码即可.

div.scrollTop = div.scrollHeight;

注:既scrollTop和scrollHeight属性值保持一致即可.
Enter键响应捕获
对enter键响应的支持, 添加如下监听事件函数即可.

document.addEventListener("keydown", function (evt) {
  if (evt.keyCode == 13) {
    // TODO
  }
});

后记:
  原本以为实现一个聊天窗口的示例很容易, 却在真正的实践过程中磕磕碰碰, 步履蹒跚. 前端这一块, 真心水很深. 事后回忆起来,觉得收获很大, 当然对于文本的自适应, 采用了一个较复杂的办法. 后来想想是不是加个max-width属性就能轻松搞定了?

公众号&游戏站点:
个人微信公众号:木目的H5游戏世界
网页闯关游戏(riddle webgame)--仿微信聊天的前端页面设计和难点第3张
个人游戏作品集站点(尚在建设中...):www.mmxfgame.com, 也可直接ip访问:http://120.26.221.54/.

免责声明:文章转载自《网页闯关游戏(riddle webgame)--仿微信聊天的前端页面设计和难点》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇PostGIS 快速入门(转)JNDI简介和简单示例下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

echarts 标签字体 自适应方法

一:echarts 自适应方案 在做一个大屏项目开发,主要是vue+echarts来做。 这次在做的时候,蓝湖是 1920 x 1080 的像素。输出的屏幕是 4k 。其实数据上就是 宽 ,高 的两倍差距。 还原 ui 的时候约定用 1920 x 1080 的像素标准直接来写。我提前将布局用 vw vh 写好了(其实写的大概差不多,也没有用比例转。。) 主...

vue3+ts的PC端自适应布局

1 安装npm install amfe-flexible postcss-px2rem -S2 在main.ts中引入import 'amfe-flexible/index.js'3 在已有的vue.config.js(没有就在根路径下新建一个) css: { loaderOptions: { postcss: {...

如何解决PC端和移动端自适应问题?

   做网页时,我们通常需要考虑到不同电脑屏幕尺寸,以及不同手机屏幕大小等问题,解决样式发生改变的情况,那么如何解决呢?现在主要是采用自适应来解决高度,宽度的,以及图片自适应问题,下面就PC端和移动端来总结一下,通常进行自适应高度和宽度,图片时,一般与页面的布局存在关系。 1、最小尺寸分辨率1024*768(传统17寸显示器),则可以采用940px、960...

用CSS使图片自适应显示宽度

做网站的时候经常遇到,新闻展示等,用户上传的图片太大了 自己又不去调解,导致展示的时候图片太大撑开了,使页面显示的很难。这里利用CSS属性,使图片超过展示的宽度后,给图片设置显示最大的宽度。 假如用width属性强行设定显示尺寸似乎太不智能。幸好Firefox/Opera/IE7都提供了max-width属性支持。 假定希望图片显示宽度不超过500像素,C...

干货|自适应大邻域搜索(ALNS)算法求解带时间窗的车辆路径规划问题(附java代码)

转眼距离开学又过去一个多月了,不知道大家在家里学习的怎么样?这段时间小编在家里也没闲着,时隔多日,再次为大家带来干货内容。 邻域搜索类启发式算法有很多种,比如禁忌搜索啦,模拟退火啦,变邻域搜索啦等等。这次带来的自适应大邻域搜索代码,相对上述几种会更复杂,编写相对全面。 小编在编写代码时,主要采用git-hub上一位作者de.markusziller的代码,...

echarts使用技巧(一)echarts的图表自适应resize问题、单选、缩放等

  这些东西要是有精力和时间可以通读echarts文档,里面都有配置详细介绍。该博客只是把自己使用echarts遇到的问题记录下,并不全,加深印象,抛砖引玉而已,完整学习的请移步官方文档 1、legend设置单选 legend: { data:['db block gets', 'consistent gets'], selectedM...