整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

banner设计经验分享之字形字体篇

banner设计经验分享之字形字体篇

家好,今天我们一起来探讨一下Banner的设计,在这一次的教程中我会介绍一些平时总结下来的可以让banner迅速达成效果的简单小窍门,如果你在平时有大量的banner设计工作,并且总觉得时间不够用,那么希望本次的教程可以帮助到你。

好了,那么我们进入正题。

首先让我们认识一下banner,平时大家在各种网站或者移动端的app里经常可以见到,印象里他们大都长这个样子:

当然了,这就是我们常说的banner,但其实banner还有几个远房表兄、同父异母什么的兄弟姐妹们,它们可能长这个样子:

恩……其实以上这些在广义上来说都可以归纳为Banner,就形状来说现在的banner也已经不再局限于从前大家所理解和看到的那些出现在固定广告位的长条形广告了,他可以是长的、方的、必要的时候也可以是其他什么乱七八糟的形状,总之,不管是侧边栏广告、焦点图、专题页的头图、我们都可以理解为是banner,在设计方法上,其实都是共通的。

如果要是分类的话其实可以大概分为两类:

1.“促使点击”

2.“渲染气氛”

第一种就是大家经常在各种大大小小的网站都能看到的广告banner或者焦点图,她们有大有小可长可短,但是他们共同的作用就是通过各种方式引导你去点击。

通常你在做这种类型的banner时,一般会是上图这个场面。

第二种大家通常可以在各种游戏网站,房地产网站,各种活动专题页中见到,也就是大家常说的头图,这种类型的banner通常并不是引导用户去触发点击,而是服务于内容,为整个页面做好气氛的渲染。

通常你在做这种类型的banner时,一般会是上图这个场面

说这么多,其实我是希望通过这种介绍和分类方式,让大家在拿到设计需求时可以确定一个正确的设计方向,降低设计成本,从而提高工作效率。

下面我们介绍几个设计小窍门,也许通过这些方法可以让你在最短的时间内有效的达成效果。

首先我们来说一下字体和字形,大家都知道我们从图形上解读信息的能力是要大于单纯的阅读文字,但是在banner的设计中,大多数情况下我们都是通过文字来了解信息,图片只是起到一个衬托的作用,在我自己平时做banner的时间分配里对字形的处理可能要占到百分之五十甚至更多的时间,所以今天我们重点来说一下这方面的处理技巧

1.钢笔造字

钢笔造字是在做字形设计上一个比较讨巧的方法,但却又十分有效。对平时没有太多字形设计经验的同学来说非常适合的,只要你了解基本的字形设计规律(笔画的粗细,字体的重心等),那么此方法可以让你快速的让banner高大上起来,具体的设计方法大家可以移步字形设计大师@刘兵克老湿的设计教程:http://v.youku.com/v_show/id_XNDI4MDMwMTg4.html

2.笔画链接

当你没有时间完整的设计banner上字体的字形时,笔画链接未尝不是一种好的方法,在做笔画链接时只有合理的安排需要链接的笔画,做到不突兀,不影响易读性,那么都会出来一个比较好的视觉效果,在做笔画连接的时候我推荐大家使用一些笔画粗细比较统一的非衬线字体比方说雅黑、悦黑、幼圆等等。

3. 随“意”变形

顾名思义就是根据文字的具体含义来设计字形的一种方法,当上面介绍的两种技巧都让你感觉头大的时候不妨试试这种处理技巧,你只需要脑洞大开,了解文字的具体含义并用相应的图形在文字上加以体现就可以了,就酱简单!

4. 3D

如果要在banner中想突出文字,把文字做成3D效果可谓是最“粗暴”的一种解决方法,只要处理方法得当也可以达到很好的效果,如何处理3D这种细节问题这里就不提及了,网上有大堆大堆的教程可供参考。切记,处理3D文字的时配色是关键,稍不注意就会显得山寨和俗气。

好了,以上是一些在设计banner时可以用到的字形设计技巧,可能有童鞋要说我平时banner的设计工作很繁重,时间也很紧张,没有精力去做字形,或者由于版权的问题,在大多数情况下不得不使用那么几种字体,像这样的情况有没有好的办法让banner中的文字出效果呢。答案当然是有啦,下面就给大家介绍几个方法。看看如何在使用简单的默认字体的同时打破字体的沉默。

字体如何打破沉默——不破不立

看到没有,同样是简单的字体,只是打破了整段的文字,做单个字体的倾斜,整体看起来就活泼跳动了很多,或者可以做单个字体的叠加,凹凸效果同样可以让简单的默认字体变得跳跃起来。

如何打破字体的沉默——空间独立

说起这种方法我们就不得不提到banner中的空间关系,在设计banner时通常我们如果我们想突出文字,那么就要使文字和背景拉开空间,而为文字做一个简单的纯色底色不可谓不是一个省事的办法。

如何打破字体的沉默——斜能压正

文字必须横平竖直才是最好看的嘛?当然不是,在一些设计中一个倾斜的文字排版不仅可以打破默认字体的沉默还可以帮助整个画面的构图,真是百试不爽。

如何打破字体的沉默——长短粗细变换自如

通常我们在做一段文字的排版时,经常会根据段落中的关键字做相印的加粗或者高亮,这种方法看似简单,但是在实际操作的过程中稍有不当就会导致整段字体看起来凌乱不堪,其实只要设计的时候把文字看作图形,注意整个字体排版的走向是否有规律可循就容易很多。

OK,以上就是今天为大家总结的一些字形与字体的处理方法,希望对大家有所启发,在banenr的设计中还有很多种有效的技巧可以用到,如果你有什么特别的技巧也可以告诉我们。

作者:LipengBian 转自/uec.nq

更多视频教程学习请关注:视觉设计联盟公众号:shijueshejilianmeng,回复“教程”

、UEditor

因为已经不再维护了,需要大量修改源码,很多都是专门为jsp等服务器渲染项目写的代码需要删除, 然后越删越害怕越删越不敢用,依赖jquery,需要专门用js去parse编辑完成的内容,parse完的内容还可能污染全局css,兼容老浏览器还不错, 但是,我们不怎么考虑兼容IE。所以,告辞。

2、wangEditor

中文文档,上手快,依赖jquery,功能少点要花时间去写插件,需要单独为图片上传功能写个接口,老项目忙着上线临时用过,感觉并不适合当前业务这么重的编辑功能于是放弃了。

3、Quill

api友好, 功能少,需要特定的css去解析文本(这点我不大喜欢),ui好看,适合作为论坛回帖功能使用。

4、CKEditor

CKEditor目前主流的还是4.x的版本,但是文档看着很瞎眼实在是提不起兴致去配置,草草用了下就放弃了,5.x版本刚从beta结束,需要指定专门的node以及npm版本,虽然功能强大配置灵活ui漂亮不过目前糟糕的兼容性基本是不可能出现在大众视野了。

5、KingEditor

丑,不喜欢,不爱用

6、Draft-js

知乎最近刚改的文本编辑器就是在draft的基础上开发的,依赖react, 弃。

7、Medium-editor:

虽然看着感觉很酷炫,但是,不适合我们的业务场景啊, api也简陋可怕。

8、trix:

嗯,又一个小而美,放弃

9、Slate

react,放弃

10、Bootstrap-wysiwyg:

bootstrap, jquery, 放弃

11、vue-quill-editor

轻量级,工具条配置少,IE10+ 根据quillJs封装。

扩展使用:www.jianshu.com/p/dc2492160…

12、tinymce

文档好,功能强,bug少,无外部依赖,大家用了都说好,嗯,没错就是它了。

编辑器配置方面只要能看得懂英文耍起来还是比较简单的,适配中碰到的大部分问题都可以通过看文档解决,即便看文档解决不了网上也有大量的文章能告诉你怎么配置能解决。

当然了,主要是我这里需要解决一些别人觉得超简单自己一想都很烦人的需求,比如:

  • word文档粘贴进来要带格式
  • 兼容移动端
  • word文档粘贴进来要正常显示并且还要兼容移动端
  • 电脑网页里粘贴进来内容要正常显示并且排版还不能乱
  • 电脑网页拷过来的内容还要兼容到移动端

高级使用方式

你可能还想要通过一些更高级的方式来使用tinyMCE。

比如npm: npm install tinymce

bower: bowerinstall tinymce 或者

bower install tinymce-src=git://github.com/tinymce/tinymce

composer: php composer.phar require"tinymce/tinymce" ">=4"

nuget: Install-PackageTinyMCE

sdk: 你可以在这里下载:www.tinymce.com/download/

jQuery: 如果你希望得到一个jQuery插件形式的tinyMCE,你可以在这里定制:www.tinymce.com/download/cu…。你可以根据你的意愿,定制你需要的功能。这样,你可以得到一个尽可能小的适用的tinyMCE。

1、插件

tinyMCE有很多插件可以使用,比如代码编辑模式、高亮模式,图片上传等等。插件拓展或新增了tinyMCE的功能。或者,你也可以自定义一些插件。

关于插件的内容过多,不进行翻译,后续一些插件也以挂出官网的链接形式展示。

2、自主义UI

1、主题和皮肤

你可以定制主题和皮肤,通过threm和spin来配置它们。

2、尺寸

这些配置帮助你定制尺寸,width、height、min_width、max_width、min_height、max_height。

你可能还需要自适应尺寸(www.tinymce.com/docs/plugin…)的插件来帮助你使尺寸更智能。或者,你可以使用resize配置。

3、样式

content_css 可用帮助你定制主体区域的样式。

statusbar 设为false可以隐藏状态栏。

4、源码模式

www.tinymce.com/docs/get-st…。页尾。

5、上传图片

https://www.tinymce.com/docs/get-started/upload-images/

6、拼写检查

www.tinymce.com/docs/get-st…

7、内容过滤

https://www.tinymce.com/docs/get-started/filter-content/

兼容性

移动端:

PC端:

初始化

因为tinymce的Plugins是按需加载的

为了能先快速上手这个编辑器

就先在vue-cli的index.html中默认塞入一条在线cdn地址

<script src="https://cdn.bootcss.com/tinymce/4.7.4/tinymce.min.js"></script>
复制代码

记得去下载语言包到本地,

然后就在文件内引入

import './zh_CN.js'
复制代码

后面有机会再写下单独打包的事项,毕竟这货体积还不小。

插入vue组件模板

<template>
 <div>
 <textarea :id="Id"></textarea>
 </div>
</template>
复制代码

记得一定要在textarea外面包一层div,不然...你自己试试看就知道了。

组件基础配置

将tinymce通过指定的selector挂载到组件中

<template>
 <div>
 <textarea :id="Id"></textarea>
 </div>
</template>
<script>
 import './zh_CN.js'
 export default {
 data () {
 const Id=Date.now()
 return {
 Id: Id,
 Editor: null,
 DefaultConfig: {}
 }
 },
 props: {
 value: {
 default: '',
 type: String
 },
 config: {
 type: Object,
 default: ()=> {
 return {
 theme: 'modern',
 height: 300
 }
 }
 }
 },
 mounted () {
 this.init()
 },
 beforeDestroy () {
 // 销毁tinymce
 this.$emit('on-destroy')
 window.tinymce.remove(`#${this.Id}`)
 },
 methods: {
 init () {
 const self=this
 this.Editor=window.tinymce.init({
 // 默认配置
 ...this.DefaultConfig,
 
 // prop内传入的的config
 ...this.config, 
 
 // 挂载的DOM对象
 selector: `#${this.Id}`,
 
 setup: (editor)=> {
 // 抛出 'on-ready' 事件钩子
 editor.on(
 'init', ()=> {
 self.loading=false
 self.$emit('on-ready')
 editor.setContent(self.value)
 }
 )
 // 抛出 'input' 事件钩子,同步value数据
 editor.on(
 'input change undo redo', ()=> {
 self.$emit('input', editor.getContent())
 }
 )
 }
 })
 }
 }
 }
</script>
复制代码

好了,组件基本的初始化完成,后面正式开始踩坑之旅

API

具体内容看官网的API就行,英语不好的用chrome翻译下对照着demo也能看个七七八八,当然主要原因还是我比较懒。

我这边根据自身业务需求在组件的data内写了个默认配置

DefaultConfig: {
 // GLOBAL
 height: 500,
 theme: 'modern',
 menubar: false,
 toolbar: `styleselect | fontselect | formatselect | fontsizeselect | forecolor backcolor | bold italic underline strikethrough | image media | table | alignleft aligncenter alignright alignjustify | outdent indent | numlist bullist | preview removeformat hr | paste code link | undo redo | fullscreen `,
 plugins: `
 paste
 importcss
 image
 code
 table
 advlist
 fullscreen
 link
 media
 lists
 textcolor
 colorpicker
 hr
 preview
 `,
 
 // CONFIG
 forced_root_block: 'p',
 force_p_newlines: true,
 importcss_append: true,
 // CONFIG: ContentStyle 这块很重要, 在最后呈现的页面也要写入这个基本样式保证前后一致, `table`和`img`的问题基本就靠这个来填坑了
 content_style: `
 * { padding:0; margin:0; }
 html, body { height:100%; }
 img { max-width:100%; display:block;height:auto; }
 a { text-decoration: none; }
 iframe { width: 100%; }
 p { line-height:1.6; margin: 0px; }
 table { word-wrap:break-word; word-break:break-all; max-width:100%; border:none; border-color:#999; }
 .mce-object-iframe { width:100%; box-sizing:border-box; margin:0; padding:0; }
 ul,ol { list-style-position:inside; }
 `,
 insert_button_items: 'image link | inserttable',
 // CONFIG: Paste
 paste_retain_style_properties: 'all',
 paste_word_valid_elements: '*[*]', // word需要它
 paste_data_images: true, // 粘贴的同时能把内容里的图片自动上传,非常强力的功能
 paste_convert_word_fake_lists: false, // 插入word文档需要该属性
 paste_webkit_styles: 'all',
 paste_merge_formats: true,
 nonbreaking_force_tab: false,
 paste_auto_cleanup_on_paste: false,
 // CONFIG: Font
 fontsize_formats: '10px 11px 12px 14px 16px 18px 20px 24px',
 // CONFIG: StyleSelect
 style_formats: [
 {
 title: '首行缩进',
 block: 'p',
 styles: { 'text-indent': '2em' }
 },
 {
 title: '行高',
 items: [
 {title: '1', styles: { 'line-height': '1' }, inline: 'span'},
 {title: '1.5', styles: { 'line-height': '1.5' }, inline: 'span'},
 {title: '2', styles: { 'line-height': '2' }, inline: 'span'},
 {title: '2.5', styles: { 'line-height': '2.5' }, inline: 'span'},
 {title: '3', styles: { 'line-height': '3' }, inline: 'span'}
 ]
 }
 ],
 // FontSelect
 font_formats: `
 微软雅黑=微软雅黑;
 宋体=宋体;
 黑体=黑体;
 仿宋=仿宋;
 楷体=楷体;
 隶书=隶书;
 幼圆=幼圆;
 Andale Mono=andale mono,times;
 Arial=arial, helvetica,
 sans-serif;
 Arial Black=arial black, avant garde;
 Book Antiqua=book antiqua,palatino;
 Comic Sans MS=comic sans ms,sans-serif;
 Courier New=courier new,courier;
 Georgia=georgia,palatino;
 Helvetica=helvetica;
 Impact=impact,chicago;
 Symbol=symbol;
 Tahoma=tahoma,arial,helvetica,sans-serif;
 Terminal=terminal,monaco;
 Times New Roman=times new roman,times;
 Trebuchet MS=trebuchet ms,geneva;
 Verdana=verdana,geneva;
 Webdings=webdings;
 Wingdings=wingdings,zapf dingbats`,
 // Tab
 tabfocus_elements: ':prev,:next',
 object_resizing: true,
 // Image
 imagetools_toolbar: 'rotateleft rotateright | flipv fliph | editimage imageoptions'
}
复制代码

因为本人比较懒,以上配置导出的代码可能会有代码注入的风险,建议保存的时候再前后端都做下注入过滤,不过一般数据安全问题主要还是服务器那边的事情?。

后面的图片上传可以单独拆出来做个小配置,直接写到props里好了。

url: {
 default: '',
 type: String
 },
 accept: {
 default: 'image/jpeg, image/png',
 type: String
 },
 maxSize: {
 default: 2097152,
 type: Number
 },
 withCredentials: {
 default: false,
 type: Boolean
 }
复制代码

然后把这套东西塞到init配置里

// 图片上传
 images_upload_handler: function (blobInfo, success, failure) {
 if (blobInfo.blob().size > self.maxSize) {
 failure('文件体积过大')
 }
 
 if (self.accept.indexOf(blobInfo.blob().type) >=0) {
 uploadPic()
 } else {
 failure('图片格式错误')
 }
 function uploadPic () {
 const xhr=new XMLHttpRequest()
 const formData=new FormData()
 xhr.withCredentials=self.withCredentials
 xhr.open('POST', self.url)
 xhr.onload=function () {
 if (xhr.status !==200) {
 // 抛出 'on-upload-fail' 钩子
 self.$emit('on-upload-fail')
 failure('上传失败: ' + xhr.status)
 return
 }
 const json=JSON.parse(xhr.responseText)
 // 抛出 'on-upload-success' 钩子
 self.$emit('on-upload-complete' , [
 json, success, failure
 ])
 }
 formData.append('file', blobInfo.blob())
 xhr.send(formData)
 }
 }
复制代码

至此, 一个组件的封装基本算是完成了

看下初阶成果

<template>
 <div>
 <textarea :id="Id"></textarea>
 </div>
</template>
<script>
 import './zh_CN.js'
 export default {
 data () {
 const Id=Date.now()
 return {
 Id: Id,
 Editor: null,
 DefaultConfig: {
 // GLOBAL
 height: 500,
 theme: 'modern',
 menubar: false,
 toolbar: `styleselect | fontselect | formatselect | fontsizeselect | forecolor backcolor | bold italic underline strikethrough | image media | table | alignleft aligncenter alignright alignjustify | outdent indent | numlist bullist | preview removeformat hr | paste code link | undo redo | fullscreen `,
 plugins: `
 paste
 importcss
 image
 code
 table
 advlist
 fullscreen
 link
 media
 lists
 textcolor
 colorpicker
 hr
 preview
 `,
 
 // CONFIG
 forced_root_block: 'p',
 force_p_newlines: true,
 importcss_append: true,
 // CONFIG: ContentStyle 这块很重要, 在最后呈现的页面也要写入这个基本样式保证前后一致, `table`和`img`的问题基本就靠这个来填坑了
 content_style: `
 * { padding:0; margin:0; }
 html, body { height:100%; }
 img { max-width:100%; display:block;height:auto; }
 a { text-decoration: none; }
 iframe { width: 100%; }
 p { line-height:1.6; margin: 0px; }
 table { word-wrap:break-word; word-break:break-all; max-width:100%; border:none; border-color:#999; }
 .mce-object-iframe { width:100%; box-sizing:border-box; margin:0; padding:0; }
 ul,ol { list-style-position:inside; }
 `,
 insert_button_items: 'image link | inserttable',
 // CONFIG: Paste
 paste_retain_style_properties: 'all',
 paste_word_valid_elements: '*[*]', // word需要它
 paste_data_images: true, // 粘贴的同时能把内容里的图片自动上传,非常强力的功能
 paste_convert_word_fake_lists: false, // 插入word文档需要该属性
 paste_webkit_styles: 'all',
 paste_merge_formats: true,
 nonbreaking_force_tab: false,
 paste_auto_cleanup_on_paste: false,
 // CONFIG: Font
 fontsize_formats: '10px 11px 12px 14px 16px 18px 20px 24px',
 // CONFIG: StyleSelect
 style_formats: [
 {
 title: '首行缩进',
 block: 'p',
 styles: { 'text-indent': '2em' }
 },
 {
 title: '行高',
 items: [
 {title: '1', styles: { 'line-height': '1' }, inline: 'span'},
 {title: '1.5', styles: { 'line-height': '1.5' }, inline: 'span'},
 {title: '2', styles: { 'line-height': '2' }, inline: 'span'},
 {title: '2.5', styles: { 'line-height': '2.5' }, inline: 'span'},
 {title: '3', styles: { 'line-height': '3' }, inline: 'span'}
 ]
 }
 ],
 // FontSelect
 font_formats: `
 微软雅黑=微软雅黑;
 宋体=宋体;
 黑体=黑体;
 仿宋=仿宋;
 楷体=楷体;
 隶书=隶书;
 幼圆=幼圆;
 Andale Mono=andale mono,times;
 Arial=arial, helvetica,
 sans-serif;
 Arial Black=arial black, avant garde;
 Book Antiqua=book antiqua,palatino;
 Comic Sans MS=comic sans ms,sans-serif;
 Courier New=courier new,courier;
 Georgia=georgia,palatino;
 Helvetica=helvetica;
 Impact=impact,chicago;
 Symbol=symbol;
 Tahoma=tahoma,arial,helvetica,sans-serif;
 Terminal=terminal,monaco;
 Times New Roman=times new roman,times;
 Trebuchet MS=trebuchet ms,geneva;
 Verdana=verdana,geneva;
 Webdings=webdings;
 Wingdings=wingdings,zapf dingbats`,
 // Tab
 tabfocus_elements: ':prev,:next',
 object_resizing: true,
 // Image
 imagetools_toolbar: 'rotateleft rotateright | flipv fliph | editimage imageoptions'
 }
 }
 },
 props: {
 value: {
 default: '',
 type: String
 },
 config: {
 type: Object,
 default: ()=> {
 return {
 theme: 'modern',
 height: 300
 }
 }
 },
 url: {
 default: '',
 type: String
 },
 accept: {
 default: 'image/jpeg, image/png',
 type: String
 },
 maxSize: {
 default: 2097152,
 type: Number
 },
 withCredentials: {
 default: false,
 type: Boolean
 }
 },
 mounted () {
 this.init()
 },
 beforeDestroy () {
 // 销毁tinymce
 this.$emit('on-destroy')
 window.tinymce.remove(`$#{this.Id}`)
 },
 methods: {
 init () {
 const self=this
 
 this.Editor=window.tinymce.init({
 // 默认配置
 ...this.DefaultConfig,
 
 // 图片上传
 images_upload_handler: function (blobInfo, success, failure) {
 if (blobInfo.blob().size > self.maxSize) {
 failure('文件体积过大')
 }
 
 if (self.accept.indexOf(blobInfo.blob().type) >=0) {
 uploadPic()
 } else {
 failure('图片格式错误')
 }
 function uploadPic () {
 const xhr=new XMLHttpRequest()
 const formData=new FormData()
 xhr.withCredentials=self.withCredentials
 xhr.open('POST', self.url)
 xhr.onload=function () {
 if (xhr.status !==200) {
 // 抛出 'on-upload-fail' 钩子
 self.$emit('on-upload-fail')
 failure('上传失败: ' + xhr.status)
 return
 }
 const json=JSON.parse(xhr.responseText)
 // 抛出 'on-upload-complete' 钩子
 self.$emit('on-upload-complete' , [
 json, success, failure
 ])
 }
 formData.append('file', blobInfo.blob())
 xhr.send(formData)
 }
 },
 // prop内传入的的config
 ...this.config, 
 
 // 挂载的DOM对象
 selector: `#${this.Id}`,
 setup: (editor)=> {
 // 抛出 'on-ready' 事件钩子
 editor.on(
 'init', ()=> {
 self.loading=false
 self.$emit('on-ready')
 editor.setContent(self.value)
 }
 )
 // 抛出 'input' 事件钩子,同步value数据
 editor.on(
 'input change undo redo', ()=> {
 self.$emit('input', editor.getContent())
 }
 )
 }
 })
 }
 }
 }
</script>
复制代码

直接引入组件调用就行了

<template>
 <mce-editor 
 :config="Config"
 v-model="Value"
 :url="Url"
 :max-size="MaxSize"
 :accept="Accept"
 :with-credentials=false
 @on-ready="onEditorReady"
 @on-destroy="onEditorDestroy"
 @on-upload-success="onEditorUploadComplete"
 @on-upload-fail="onEditorUploadFail"
 ></mce-editor>
</template>
复制代码

但是作为一名优秀的程序员,这怎么可能够嘛。

下面说下打包的事情

塞入webpack

为了加快页面载入速度就要首先解决载入文件过多的问题,而大部分时间用户并不需要每次打开页面都先加载一遍editor的核心文件,而editor本身也要按需加载内容,一开始想把每个plugin都搞成独立组件模块按需载入,但是这就要涉及到修改编辑器本身源码,或者说对window.tinymce删掉点特性,这些都太麻烦也都有风险,对后面的代码维护影响也大,索性就都先留着。

后面边做边改吧

还是以vue-cli为例

把官网下载的包塞到stataic文件夹中

然后删掉index.html模版中的cdn代码吧不需要了

当然这里有俩选择

要么做成一个异步组件,单独打包,按需载入

要么直接引入到main.js中将包打成为一个巨无霸

所以我选择前者,

首先老规矩 引入编辑器主体

import '../../static/tinymce/tinymce.min.js'
复制代码

然后刷新下页面,不出意外应该是报这么个错Uncaught SyntaxError: Unexpected token <

眼尖的朋友应该知道是怎么回事了theme.js:1

在默认配置下, tinymce载入的theme的路径居然是这个

Request URL:http://localhost:8080/themes/modern/theme.js

然后我跑去官网搜了下api 只搜到一个叫document_base_url的api,但是根据多年程序员的直觉经验告诉我 不是这货(嗯,我在这里卡住了),网上翻了下各地文献,都没有啊,

那怎么办呢

于是我就跑去看源码...但是4万行...算了...

然后我就在控台打印了下tinymce对象,然后发现了一个叫baseURL的string对象,嗯,有希望了。

在源码里搜了下baseURL

蹦出来这段代码 .... 算了有很多段...

大致思想就是通过当前URI拆出来个baseURL,改掉就行了

window.tinymce.baseURL='/static/tinymce'
复制代码

如果需要载入的地址是另一个比如自己公司的cdn的路径,那改成全路径就行了

window.tinymce.baseURL='http://cdn.xxx.com/static/tinymce'
复制代码

貌似路径的问题解决了

但是新的问题又出现了,

插件下过来都是带min的,但默认载入的插件都是不带min的,一定是我源码没看仔细,

然后我又搜了一下代码

if (!baseURL && document.currentScript) {
 src=document.currentScript.src;
 if (src.indexOf('.min') !=-1) {
 suffix='.min';
 }
 baseURL=src.substring(0, src.lastIndexOf('/'));
}
复制代码

希望就在眼前,貌似是业务我载入的方式是直接导入到模块的,于是一个叫suffix的默认值为空了,于是我去又加了行代码:

window.tinymce.suffix='.min'
复制代码

成功!

你看嘛,超级简单的是不是,根本不用改源码,网上说的动不动就去改源码什么的不要信啊不要信,大部分面向对象的事情改个默认值就行了。

对了,还记得前面的语言包嘛,

下过来塞到/static/tinymce/langs文件夹里

然后删掉

import './zh_CN.js'
复制代码

这行代码

在DefaultConfig中放入一个新配置项

language: 'zh_CN'
复制代码

好了,后面就是模块打包的事情了,

打包

前面打的包有一个问题是默认配置是载入tinyMce本体,那么就会造成这个包大概有500k的体积,如果这个组件不做异步载入的处理,那么对于某些业务来说就是灾难。虽然这么做打开只用载入一个文件,业务比较稳定。

但我觉得这样不优雅所以最后还是把它单独拎出来了。

同理,根据这个库本身的特性,我们完全可以把这么多个必须的plugin按需要直接统一打成一个包,直接载入。这样,我们就又多了一个几百k的plugins包。

然后把plugins包和tinyMce主体包在不阻塞页面加载的情况下,做个懒加载提前缓存好文件方便后面使用,而组件本身在挂载前做个监听window.tinymce全局变量的方法,然后cdn控制下文件的过期时间即可。

这样,在保证了灵活度的前提下也保证了业务载入的速度。

文重要内容

  • CSS的单位
  • 字体属性
  • 文本属性
  • 定位属性:position、float、overflow等

CSS的单位

html中的单位只有一种,那就是像素px,所以单位是可以省略的,但是在CSS中不一样。 CSS中的单位是必须要写的,因为它没有默认单位。

绝对单位

1 in=2.54cm=25.4mm=72pt=6pc。

各种单位的含义:

  • in:英寸Inches (1 英寸=2.54 厘米)
  • cm:厘米Centimeters
  • mm:毫米Millimeters
  • pt:点Points,或者叫英镑 (1点=1/72英寸)
  • pc:皮卡Picas (1 皮卡=12 点)

相对单位

px:像素 em:印刷单位相当于12个点 %:百分比,相对周围的文字的大小

为什么说像素px是一个相对单位呢,这也很好理解。比如说,电脑屏幕的的尺寸是不变的,但是我们可以让其显示不同的分辨率,在不同的分辨率下,单个像素的长度肯定是不一样的啦。

百分比%这个相对单位要怎么用呢?这里也举个例子:

font 字体属性

CSS中,有很多非布局样式(与布局无关),包括:字体、行高、颜色、大小、背景、边框、滚动、换行、装饰性属性(粗体、斜体、下划线)等。

这一段,我们先来讲一下字体属性。

css样式中,常见的字体属性有以下几种:

p{
	font-size: 50px; 		/*字体大小*/
	line-height: 30px;      /*行高*/
	font-family: 幼圆,黑体; 	/*字体类型:如果没有幼圆就显示黑体,没有黑体就显示默认*/
	font-style: italic ;		/*italic表示斜体,normal表示不倾斜*/
	font-weight: bold;	/*粗体*/
	font-variant: small-caps;  /*小写变大写*/
}

行高

CSS中,所有的行,都有行高。盒子模型的padding,绝对不是直接作用在文字上的,而是作用在“行”上的。

如下图所示:

上图中,我们设置行高为30px,30px * 5=150px,通过查看审查元素,这个p标签的高度果然为150px。而且我们发现,我们并没有给这个p标签设置高度,显然是内容将其撑高的。

垂直方向来看,文字在自己的行里是居中的。比如,文字是14px,行高是24px,那么padding就是5px:

为了严格保证字在行里面居中,我们的工程师有一个约定: 行高、字号,一般都是偶数。这样可以保证,它们的差一定偶数,就能够被2整除。

如何让单行文本垂直居中

小技巧:如果一段文本只有一行,如果此时设置行高=盒子高,就可以保证单行文本垂直居中。这个很好理解。

上面这个小技巧,只适用于单行文本垂直居中,不适用于多行。如果想让多行文本垂直居中,还需要计算盒子的padding。计算方式如下:

vertical-align: middle; 属性

vertical-align: middle; /*指定行内元素(inline)或表格单元格(table-cell)元素的垂直对齐方式。*/

字号、行高、字体三大属性

(1)字号:

	font-size:14px;

(2)行高:

	line-height:24px;

(3)字体:(font-family就是“字体”,family是“家庭”的意思)

	font-family:"宋体";

是否加粗属性以及上面这三个属性,我们可以连写:(是否加粗、字号 font-size、行高 line-height、字体 font-family)

格式:

	font: 加粗 字号/行高/ 字体

举例:

	font: 400 14px/24px "宋体";

PS:400是nomal,700是bold。

上面这几个属性可以连写,但是有一个要求,font属性连写至少要有字号和字体,否则连写是不生效的(相当于没有这一行代码)。

2、字体属性的说明:

(1)网页中不是所有字体都能用,因为这个字体要看用户的电脑里面装没装,比如你设置:

	font-family: "华文彩云";

上方代码中,如果用户的 Windows 电脑里面没有这个字体,那么就会变成宋体。

页面中,中文我们一般使用:微软雅黑、宋体、黑体。英文使用:Arial、Times New Roman。页面中如果需要其他的字体,就需要单独安装字体,或者切图。

(2)为了防止用户电脑里,没有微软雅黑这个字体。就要用英语的逗号,提供备选字体。如下:(可以备选多个)

	font-family: "微软雅黑","宋体";

上方代码表示:如果用户电脑里没有安装微软雅黑字体,那么就是宋体。

(3)我们须将英语字体放在最前面,这样所有的中文,就不能匹配英语字体,就自动的变为后面的中文字体:

	font-family: "Times New Roman","微软雅黑","宋体";

上方代码的意思是,英文会采用Times New Roman字体,而中文会采用微软雅黑字体(因为美国人设计的Times New Roman字体并不针对中文,所以中文会采用后面的微软雅黑)。比如说,对于smyhvae哈哈哈这段文字,smyhvae会采用Times New Roman字体,而哈哈哈会采用微软雅黑字体。

可是,如果我们把中文字体写在前面:(错误写法)

	font-family: "微软雅黑","Times New Roman","宋体";

上方代码会导致,中文和英文都会采用微软雅黑字体。

(4)所有的中文字体,都有英语别名。

微软雅黑的英语别名:

	font-family: "Microsoft YaHei";

宋体的英语别名:

	font-family: "SimSun";

于是,当我们把字号、行高、字体这三个属性合二为一时,也可以写成:

	font:12px/30px  "Times New Roman","Microsoft YaHei","SimSun";

(5)行高可以用百分比,表示字号的百分之多少。

一般来说,百分比都是大于100%的,因为行高一定要大于字号。

比如说, font:12px/200% “宋体”等价于font:12px/24px “宋体”。200%可以理解成word里面的2倍行高。

反过来, font:16px/48px “宋体”;等价于font:16px/300% “宋体”。

字体加粗属性

.div {
	font-weight: normal; /*正常*/
	font-weight: bold;  /*加粗*/
	font-weight: 100;
	font-weight: 200;
	font-weight: 900;
}

在设置字体是否加粗时,属性值既可以填写normal、bold这样的加粗字体,也可以直接填写 100至900 这样的数字。normal的值相当于400,bold的值相当于700。

文本属性

CSS样式中,常见的文本属性有以下几种:

  • letter-spacing: 0.5cm ; 单个字母之间的间距
  • word-spacing: 1cm; 单词之间的间距
  • text-decoration: none; 字体修饰:none 去掉下划线、underline 下划线、line-through 中划线、overline 上划线
  • text-transform: lowercase; 单词字体大小写。uppercase大写、lowercase小写
  • color:red; 字体颜色
  • text-align: center; 在当前容器中的对齐方式。属性值可以是:left、right、center(在当前容器的中间)、justify
  • text-transform: lowercase; 单词的字体大小写。属性值可以是:uppercase(单词大写)、lowercase(单词小写)、capitalize(每个单词的首字母大写)

这里来一张表格的图片吧,一览无遗:

列表属性

ul li{
	list-style-image:url(images/2.gif) ;  /*列表项前设置为图片*/
	margin-left:80px;  /*公有属性*/
}

另外还有一个简写属性叫做list-style,它的作用是:将上面的多个属性写在一个声明中。

我们来看一下list-style-image属性的效果:

给列表前面的图片加个边距吧,不然显示不完整:

这里来一张表格的图片吧,一览无遗:

overflow属性:超出范围的内容要怎么处理

overflow属性的属性值可以是:

  • visible:默认值。多余的内容不剪切也不添加滚动条,会全部显示出来。
  • hidden:不显示超过对象尺寸的内容。
  • auto:如果内容不超出,则不显示滚动条;如果内容超出,则显示滚动条。
  • scroll:Windows 平台下,无论内容是否超出,总是显示滚动条。Mac 平台下,和 auto属性相同。

针对上面的不同的属性值,我们来看一下效果: 举例:

<!doctype html>
<html lang="en">
 <head>
  <meta charset="UTF-8">
  <meta name="Generator" content="EditPlus?">
  <meta name="Author" content="">
  <meta name="Keywords" content="">
  <meta name="Description" content="">
  <title>Document</title>

	<style type="text/css">

		div{
			width: 100px;
			height: 100px;
			background-color: #00cc66;
			margin-right: 100px;
			float: left;
		}

		#div1{
			overflow: auto;/*超出的部分让浏览器自行解决*/
		}
		#div2{
			overflow: visible;/*超出的部分会显示出来*/
		}

		#div3{
			overflow: hidden;/*超出的部分将剪切掉*/
		}

	</style>

 </head>

 <body>

	<div id="div1">其实很简单 其实很自然 两个人的爱由两人分担 其实并不难 是你太悲观 隔着一道墙不跟谁分享 不想让你为难 你不再需要给我个答案</div>
	<div id="div2">其实很简单 其实很自然 两个人的爱由两人分担 其实并不难 是你太悲观 隔着一道墙不跟谁分享 不想让你为难 你不再需要给我个答案</div>
	<div id="div3">其实很简单 其实很自然 两个人的爱由两人分担 其实并不难 是你太悲观 隔着一道墙不跟谁分享 不想让你为难 你不再需要给我个答案</div>
 </body>

</html>

效果:

鼠标的属性 cursor

鼠标的属性cursor有以下几个属性值:

  • auto:默认值。浏览器根据当前情况自动确定鼠标光标类型。
  • pointer:IE6.0,竖起一只手指的手形光标。就像通常用户将光标移到超链接上时那样。
  • hand:和pointer的作用一样:竖起一只手指的手形光标。就像通常用户将光标移到超链接上时那样。

比如说,我想让鼠标放在那个标签上时,光标显示手状,代码如下:

p:hover{
	cursor: pointer;
}

另外还有以下的属性:(不用记,需要的时候查一下就行了)

  • all-scroll :  IE6.0 有上下左右四个箭头,中间有一个圆点的光标。用于标示页面可以向上下左右任何方向滚动。
  • col-resize :  IE6.0 有左右两个箭头,中间由竖线分隔开的光标。用于标示项目或标题栏可以被水平改变尺寸。
  • crosshair :  简单的十字线光标。
  • default :  客户端平台的默认光标。通常是一个箭头。
  • hand :  竖起一只手指的手形光标。就像通常用户将光标移到超链接上时那样。
  • move :  十字箭头光标。用于标示对象可被移动。
  • help :  带有问号标记的箭头。用于标示有帮助信息存在。
  • no-drop :  IE6.0 带有一个被斜线贯穿的圆圈的手形光标。用于标示被拖起的对象不允许在光标的当前位置被放下。
  • not-allowed :  IE6.0 禁止标记(一个被斜线贯穿的圆圈)光标。用于标示请求的操作不允许被执行。
  • progress :  IE6.0 带有沙漏标记的箭头光标。用于标示一个进程正在后台运行。
  • row-resize :  IE6.0 有上下两个箭头,中间由横线分隔开的光标。用于标示项目或标题栏可以被垂直改变尺寸。
  • text :  用于标示可编辑的水平文本的光标。通常是大写字母 I 的形状。
  • vertical-text :  IE6.0 用于标示可编辑的垂直文本的光标。通常是大写字母 I 旋转90度的形状。
  • wait :  用于标示程序忙用户需要等待的光标。通常是沙漏或手表的形状。
  • *-resize :  用于标示对象可被改变尺寸方向的箭头光标。
  • w-resize | s-resize | n-resize | e-resize | ne-resize | sw-resize | se-resize | nw-resize
  • url ( url ) :  IE6.0 用户自定义光标。使用绝对或相对 url 地址指定光标文件(后缀为 .cur 或者 .ani )。

滤镜

这里只举一个滤镜的例子吧。比如说让图片变成灰度图的效果,可以这样设置滤镜:

	<img src="3.jpg" style="filter:gray()">

举例代码:

 <body>
	<table>
		<tr>
			<td>原始图片</td>
			<td>图片加入黑白效果</td>
		</tr>
	<tr>
		<td><img src="3.jpg"></td>
		<td><img src="3.jpg" style="filter:gray()"></td> /*滤镜:设置图片为灰白效果*/
	</tr>
	</table>
 </body>

效果如下:(IE有效果,google浏览器无效果)

延伸: 滤镜本身是平面设计中的知识。如果你懂一点PS的话···打开PS看看吧:

爆料一下,表示博主有两年多的平面设计经验,我做设计的时间其实比写代码的时间要长,嘿嘿···

导航栏的制作(本段内容请忽略)

现在,我们利用float浮动属性来把无序列表做成一个简单的导航栏吧,效果如下:

代码:

<!doctype html>
<html lang="en">
 <head>
  <meta charset="UTF-8">
  <meta name="Generator" content="EditPlus?">
  <meta name="Author" content="">
  <meta name="Keywords" content="">
  <meta name="Description" content="">
  <title>Document</title>

	<style type="text/css">
		ul{
			list-style: none;/*去掉列表前面的圆点*/
			width: 420px;
			height: 60px;
			background-color: black;/*设置整个导航栏的背景为灰色*/
		}

		li{
			float: left;/*平铺*/
			margin-right: 30px;
			margin-top: 16px;
		}

		a{
			text-decoration: none;/*去掉超链的下划线*/
			font-size: 20px;
			color: #BBBBBB;/*设置超链的字体为黑色*/
			font-family:微软雅黑;
		}

	</style>

 </head>
 <body>
	<ul>
		<li><a href="">博客园</a></li>
		<li><a href="">新随笔</a></li>
		<li><a href="">联系</a></li>
		<li><a href="">订阅</a></li>
		<li><a href="">管理</a></li>

	</ul>
 </body>
</html>

实现效果如下:

国庆这四天,连续写了四天的博客,白天和黑夜,从未停歇,只交替没交换,为的就是这每日一发。以后会不断更新的。