当前位置: 首页 > Web前端 > HTML

如何实现完美的两端对齐-head-to-tail功能——hyphenjs

时间:2023-04-02 22:10:53 HTML

因为之前的代码太乱了。最近在重写,忘记开分店了。有兴趣查看之前代码的朋友可以重置到commitc8034eb之前的代码。重写完成后我会重写一篇文章,抱歉。前言话不多说,先上图吧。后面的红框是浏览器默认的文字排版,右边会有锯齿(至于难不难见仁见智,哈哈)。前者是使用自己开发的hyphenjs后的文字排版,整齐得像块豆腐!对于处女座来说,就舒服多了。去看这个神奇的hyphenjs应用场景不会无缘无故造轮子。日常工作需求中,设计师丢给你一个PSD,发现里面的文字是两端对齐的,然后在实际开发中发现,text-align:justify;这种操作根本行不通,会把单词和空格之间的距离拉的非常难看。之所以用PSD好看是因为设计师对字号或者换行做了微调。当然,大家都知道在实际开发中根本不起作用。作为一个颇有追求的前端开发者,在社区中找不到满意的工具库后,果断开始自己动手,创造快乐。技术分析简单来说,在hyphenjs的开发中(hyphenjs只考虑西方语言,即英语、印尼语等),遇到三个难点:换行的时机,换行适合哪个字符?在每行的末尾添加一个连接器是否合适?如何做到每行长短一致,排版精致又妖艳?第一点是要实现两端对齐,所以每行的长度必须接近文本框的宽度才能达到目的。问题来了,盒子的宽度很容易得到:(getComputedStyle(target))['width'],那么如何控制线长呢?请看下面的代码:varspan=document.createElement('span'),width=0;span.style.fontSize=18;span.innerText='R';target.appendChild(跨度);width=(span.getBoundingClientRect())['width'];通过这个方法的思路,也得到了每个字符的真实宽度。有几个方面需要注意。fontSize需要从文本框中获取。这里我们只假设一个字体大小。同时,只有当span被插入到文本框(或DOM树)中时,才能真正生效,获取其所有真实的属性(也会继承parent的相关样式,如font-family和我们关心的其他属性)。因此,最终我们可以得到文本框中出现过的所有字符的宽度,并用hashMap记录下它们的charCode和宽度,方便复用。如何计算每行的累计宽度?请看下面的函数://计算n和m个字符之间的累积宽度functiongetAccWidth(textData,charArray,from,to){returncharArray.slice(from,to).reduce(function(acc,cur){if(!cur)returnacc+0;returnacc+textData[PREFIX+cur.charCodeAt()].width;},0);}上面计算出来的hashMap终于派上用场了,逐一访问文本中的每一个charCode,通过hashMap(即函数的形参textData)获取字符的宽度,累加计算n到m的总宽度,与框的宽度比较,若框的宽度为当前字符和当前下一个字符之间的累积宽度,应该是一个合适的换行时机。比如比如第一行,那么from是0,如果to到了第21个字符,呃,刚好比盒子的宽度大,那么20~21正好是断行的时机.那么第一个问题就解决了!接下来~换行虽然粗暴,但来个精致又骚的换行怎么样?是否适合换行添加连接器?我特意去谷歌搜索了几份英文报纸观察,发现了几个特点:如果单词被减半,那么它必须被添加!但最多从第二个字符开始~\"\':;,.?()[]{}<>~!@#$%^&*-+=/\\|1234567890等特殊字符不需要补充一下,为什么?看着不舒服~逗号、句号等标点符号不会留在每行的开头然而,鹅问题来了,当我撒娇的时候,把成品发给公司的高层看,高层淡淡的说道,“还是没对齐……我心里受到了重创。”的确,由于前面三个条件的原因,换行部分出现了一些小的漂移。",所以确实没有完美对齐。那么如何解决呢?控制字间距!带出字母间距的神器!(听说报纸的排版也是通过微调字间距来实现豆腐块的排版)。公式也很容易得出:合理的字间距=(框宽-行宽)/本行字符数,只需将字间距应用到每一行的行内样式即可。duang!搞定了哈哈哈~~最后提几个有意思的地方和注意点:空格的宽度怎么取?直接添加到DOM将被忽略。哭了。。。纠结了一会儿这个,后来发现xx减去xx就够了。同一个文本多次应用hyphenjs怎么办?这个一开始没有考虑,后来把文本保存在全局对象window.hyphen_cached中,需要的时候随时提取~hyphenjs目前只应用于纯文本~比如

hyphenjs就是绝对有用.

中的strong标签会被忽略,因为hyphenjs获取的是innerText~这是我第一次写博客,也是刚毕业两个月的新手。如果写的不好,还请大家多多包涵~当然最重要的是如果这个hyphenjs对你的工作有帮助,请给个star,或者发现什么问题也可以提出issue~一位前辈告诉我,“凡事都要遵循简单的实用主义”,我感触很深,基本上任何开发的东西都需要实用,才能应用到实际开发中,才能对我的工作和成长有所帮助。换个画风,嘿嘿嘿……戳这里hyphenjs用力