富文本编辑器实现(二)

在上一篇文章中已经介绍了一些在实现一个富文本编辑器时需要用的一些必备知识点。如果不清楚还请参考上一篇文章。

本篇文章会重点介绍编辑器实现的具体过程。

首先来考虑的是编辑的界面。界面包含两个大部分:工具栏和内容编辑区。

内容编辑区比较简单,主要主要组成部分就是一个iframe,当然还要考虑一些样式和行为方面的问题,这部分比较简单。

比较复杂的就是工具栏了,在上一个编辑器设计的时候由于设计的样式问题,导致按钮样式没法有效的通用,所以在这一次设计时让按钮的样式保持统一化,既简化设计又简化实现。

目前按钮主要包含三种形式:一种是直接点击的按钮;一种是有下拉选项的按钮;一种是有弹出内容交换的按钮。所以这里使用了插件的形式来实现工具栏的按钮。

首先是实现了三种插件类和一个插件管理器,根据需要使用的按钮进行实例化并注册到插件管理器中。

先来看一下主体对象Editor,Editor对象主要包含以下属性:

//编辑器的DOM
self.dom = {};
//编辑器对用的textarea的引用
self.textarea = dk.$(textareaId);
//当前是否为设计模式
self.designMode = true;
//编辑配置,包含工具栏按钮等等
self.options = {
otoolbar: [
o['font_family', 'font_size'],
o['bold', 'italic', 'underline', 'del'], 
o['font_color', 'bg_color'], 
o['aleft', 'acenter', 'aright'],
o['link', 'unlink', 'image'],
o['source']
o]
};

下面看一下Editor对象的初始化函数:

self.init =function(){
o//初始化选项
oself.initOptions();
o//初始化界面
oself.initUI();
o//初始化iframe
oself.initIframe();
o//初始化事件
oself.initEvents();
o//同步内容
oself.syncContent();
};

选项初始化比较简单,下面说一下界面的初始化。界面的初始化就是根据编辑器的DOM结构生成相应的DOM树,唯一有所不同的地方就是工具栏中的按钮是根据Editor.options.toolbar的配置,从插件管理器中获取并插入到文档中的。下一篇文章中会对工具栏的插件机制进行介绍。

接下来是iframe的初始化。要将iframe的document的designMode设置为on碧昂打开文档并写入需要写入的样式等然后关闭。

self.initIframe =function(){
ovar iframe = self.dom.iframe;
ovar doc = iframe.currentDocument || iframe.contentWindow.document;
ovar win = iframe.contentWindow;
odoc.designMode = 'on';
odoc.contentEditable = true;
odoc.charset = "utf-8";
odoc.open();
odoc.write('<!DOCTYPE html><html><head><meta charset="utf-8" /><style>.view{padding:0;word-wrap:break-word;cursor:text;width:100%;height:100%;overflow:hidden;}.viewbody{margin:0;padding:0;width:100%;height:100%;overflow:auto;}p{margin:10px 0;}</style></head><body></body></html>')
odoc.write(self.textarea.value);
odoc.close();
oself.win = win;
oself.doc = doc;
}

再接下来就是事件的初始化,包括iframe的keypress的事件,点击事件,以及在IE中对选中内容的保存等等。

self.initEvents = function(){
o//add editor keyboard events
odk.addEvent(self.doc.body, 'keypress', function(e){
oif(e.which == 13){
oself.doc.execCommand('formatblock', false, '

'); o} o}); o//add editor click events odk.addEvent(self.doc.body, 'click', function(e){ oself.setStatusBar(); o}); o odk.addEvent(self.win, 'beforedeactivate', function(e){ o//console.log('before deactivate'); oself.rangeBackup = self.doc.selection.createRange().duplicate(); o//console.log(self.rangeBackup.text); o}); odk.addEvent(self.win, 'activate', function(e){ o//console.log('activate'); oif(self.rangeBackup){ oself.rangeBackup.select(); o} o}); }

最后一步就是同步编辑器内容,根据designMode的模式,对编辑器的内容进行同步。

这里简单的说了一下Editor对象的内容。下一篇文章中会对Editor对象的插件内容进行说明。

转载请注明原文出处《富文本编辑器实现(二)》 如无特别声明,所有文章均遵守创作共用 署名-非商业-禁止演绎 3.0协议。

富文本编辑器实现(一)

这里简单的聊一下如何实现一个简单的富文本编辑器。见以前的文章动手做一个在线富文本编辑器

1.富文本编辑器的基础

document对象有一个designMode属性,你可以使用这个属性来让当前的document进入可编辑模式。

当进入可编辑模式时,整个文档可以获取焦点并可以进行编辑,同样你也可以执行脚本来控制。

这一属性是IE首先支持的,在Mozilla1.3中也引入此属性来用于富文本编辑器的实现。这一点是我们用于实现富文本编辑器的基础,有了这个我们才能进行下一步的工作。

这里我们在页面中创建了一个iframe来作为编辑器的主体。

var iframe = document.createElement('iframe');
var idoc = iframe.currentDocument || iframe.contentWindow.document;
var iwin = iframe.contentWindow;
var idoc.designMode = 'on';
idoc.open();
idoc.write('');
idoc.close();

2.在编辑器中执行命令

在编辑器中要对选中的内容进行操作需要使用到execCommand方法。

document.execCommand(sCommand [, bUserInterface] [, vValue])

本方法能够对当前文档,当前选区或给定的范围执行一个命令。如果命令被成功执行则会返回ture。

示例:

//创建链接
document.execCommand('CreateLink');
//设置颜色
document.execCommand('ForeColor', 'false', '#f03');

这里列举几个常用的命令:

    o

  • BackColor – 设置或获取当前选中区域的背景颜色
  • o

  • Bold – 切换当前选中区域是否加粗
  • o

  • Copy – 将当前选中区域复制到粘贴板
  • o

  • CreateBookmark – 创建一个书签锚点或获取当前选中区域或插入点的书签锚点的名称
  • o

  • CreateLink – 在当前选中区域插入超链接,或显示一个对话框允许用户指定为当前选中区域插入的超链接的url
  • o

  • Cut – 将当前选中区域复制到剪切板并删除
  • o

  • Delete – 删除当前选中区域
  • o

  • FontName – 设置或获取当前选中区域的字体
  • o

  • FontSize – 设置或获取当前选中区域的字体大小
  • o

  • ForeColor – 设置获取当前选中区域的前景(文本)颜色
  • o

  • FormatBlock – 设置当前块格式化标签
  • o

  • Indent – 增加选中文本的缩进
  • o

  • InsertButton –  用按钮控件覆盖当前选中区
  • o

  • InsertImage – 用图像覆盖当前选中区
  • o

  • InsertOderedList – 切换当前选中区域是编号列表还是常规格式化块
  • o

  • InsertParagraph – 用换行覆盖当前选中区
  • o

  • InsertUnorderedList – 切换当前选中区域是符号列表还是常规格式化块。
  • o

  • Italic – 切换当前选中区域斜体显示与否
  • o

  • JustifyCenter – 将当前选中区所在格式化块居中
  • o

  • JustifyFull – 将当前选中区所在格式化块全对齐
  • o

  • JustifyLeft – 将当前选中区所在格式化块居左
  • o

  • JustifyNone – 取消设置
  • o

  • JustifyRight – 将当前选中区所在格式化块居右
  • o

  • Paste – 将剪贴板中的内容覆盖当前选中区
  • o

  • Redo – 重做
  • o

  • RemoveFormat – 从当前选中区删除格式化标签
  • o

  • StrikeThrough – 切换当前选中区删除线显示与否
  • o

  • UnBookmark – 从当前选中区中删除全部标签
  • o

  • Underline – 切换当前选中区下划线显示与否
  • o

  • Undo – 撤销
  • o

  • Unlink- 从当前选中区中删除全部超链接

3.选区(Selection)和范围(Range)

选区和范围也是非常重要的一个基础内容。

选区(Selection)代表当前激活的选中区域,即用户在页面上拖拽时选中的文本或其他元素。当然它不仅仅可以由用户操作生成,同样也可以有脚本控制生成。

IE中有两种范围(Range)分别是TextRange和controlRange集合。TextRange表示HTML元素中的文本。controlRange集合表示一组元素的集合。

FireFox和webkit中的SelectionRange与IE中的差别比较大。只有一个Range对象,代表了文档的一个片段,它可以包含给定文档节点和文本节点的一部分。当然这几个浏览器之间这几个对象的属性和方法之间差距还是很大的。所以这里需要对着几个对象进行一些封装,以便于使用以及代码的格式化整理。本部分内容在后面用到的时候还再进行讨论。

本篇文章主要讨论了实现一个富文本编辑器用到的基础知识,虽然不多,但是相对来说第三点内容还是比较复杂的。在下一篇文章中会开始讨论具体一点的实现过程。

  1. 动手做一个在线富文本编辑器

转载请注明原文出处《富文本编辑器实现(一)》 如无特别声明,所有文章均遵守创作共用 署名-非商业-禁止演绎 3.0协议。

jQuery插件实现-自定义Placeholder

HTML5中文本框的新属性placeholder是个非常好用的属性,但是IE系列直至IE9都不支持这一属性,这就让大家在用这一属性的时候有些犹豫不决。自己曾经写过很多类似共的小控件,但是都不是很通用,这里分享一个渐进增强的自定义placeholder的jQuery插件。有点是使用简单,大家也可以根据自己的需要进行改进。平常写jQuery插件比较少,考虑到用jQuery的同学比较多,这里就用jQuery插件的形式编写了。

在这里简单的介绍一下实现思路。

    o

  1. 表现与html5原生的placeholder尽量类似
  2. o

  3. 渐进增强对于支持placeholder的浏览器不做处理

1.首先是几个工具方法:

    o

  • supportProperty(nodeType, property),获取浏览器是否支持某一控件的某一属性
  • o

  • getPositionInDoc(target, parent),获取对象在文档中的位置
  • o

  • $c,一个快速创建Dom对象的方法

这几个工具方法都是一些比较常见通用的方法,如果你有自己的或者更合适的可以自行替换。

2.主体,CustomPlaceholder对象。这个对象主要是维护每一个文本框的信息,包括其位置,应该显示的提示信息等等,另外它还包含创建提示信息以及定位等方法以及对象的相应事件。

事件主要是在initEvents函数中进行的处理,这里特别要注意的是对提示信息事件的处理,当提示信息被点击时焦点应该被重新定位到文本框。而文本框要处理的则是focusblur事件。

$(self.hint).bind( 'click', function(e){
oself.input.focus();
});

$(self.input).bind( 'focus', function(e){
oself.hint.style.display = 'none';
});

$(self.input).bind( 'blur', function(e){
oif(this.value == ''){
oself.hint.style.display = 'inline';
o}
});

CustomPlacehodler对象的两个主要方法是createHintLabel(text, position)position()createHintLabel是用于创建提示信息的DOM对象并对其进行定位,并返回这个对象。position方法用于强制对提示消息进行重新定位。主要用于页面大小改变的情况。这两个方法的功能和实现都比较简单。

3.插件的功能实现部分。jQuery插件实现方式就不多说了。这里首先进行了能力检测,如果原生支持placeholder则直接返回。

if(supportProperty('input', 'placeholder')){
oreturn;
}

接下来是根据选择的input对象,生成相应的CustomPlaceholder对象,保存在数组中,并获取每个对象的提示信息的DOM对象,添加到容器中,最后将容器附加到body对象中。

var customPlaceholders = [];
if(this.length > 0){
ovar box = $c('div', 'dk_placeholderfixed_box');
ofor(var i = 0, len = this.length; i < len; i++){
ovar input = this[i];
ocustomPlaceholders.push(new CustomPlaceholder(box, input, option));
o}

odocument.body.appendChild(box);
}

最后还有一件比较重要的事情,为window对象绑定resize事件,当window对象触发resize事件时对所有的customPlacehoder对象进行重新定位。

$(window).bind( 'resize', function(e){
ofor(var i = 0, len = customPlaceholders.length; i < len; i++){
ovar customPlaceholder = customPlaceholders[i];
ocustomPlaceholder.position();
o}

});

这个简单的小插件到这里就写完了。

点击这里查看源码

抛砖引玉,欢迎不吝赐教。

转载请注明原文出处《jQuery插件实现-自定义Placeholder》 如无特别声明,所有文章均遵守创作共用 署名-非商业-禁止演绎 3.0协议。

ZF2-事件管理器(The EventManager)

概述

EventManger是一个为以下使用情况设计的组件:

    o

  • 实现简单的主题/观察者模式
  • o

  • 实现面向切面的设计
  • o

  • 实现事件驱动的架构

基本的架构允许你添加和解除指定事件的侦听器,无论是在一个实例基础还是一个共享的集合;触发事件;终止侦听器的执行。 继续阅读 »

转载请注明原文出处《ZF2-事件管理器(The EventManager)》 如无特别声明,所有文章均遵守创作共用 署名-非商业-禁止演绎 3.0协议。

使用Canvas实现动画效果

这是动手开发一个HTML5赛车小游戏系列文章。你可以查看前一篇内容:

    o

  1. 动手开发一个HTML5赛车小游戏

这里我们使用Canvas开发这个游戏,而不是采用传统的DOM方式实现,虽然这个简单的游戏使用DOM也可以实现(甚至有可能更容易点)。但是Canvas可以更加方便的控制图片,功能更更加强大,因为你可以完全按照自己的想法进行绘制和操作图像。

Canvas是HTML5中新加入的标签。它定义了一个图形,可以是图表或任何内容,但是它只是一个容器,你必须使用JavaScript来进行绘制图形。Canvas并不是为动画准备的,但是你可以使用它来实现动画效果。

前面介绍过在HTML中如何使用JavaScript实现DOM的动画效果:

    o

  1. Javascript动画效果的实现(一)
  2. o

  3. Javascript动画效果的实现(二)
  4. o

  5. Javascript动画效果的实现(三)

其实使用Canvas中的动画实现某种程度也利用了同样的思想。快速的定时的改变所绘制的图形的位置。当然Canvas上所绘制的图形不会自动消失,如果你不断的画图形会不断的重复出现在画布中,所以你需要在重绘之前清除画布,这样你得到的才是动画而不是动画的轨迹。

JavaScript中没有诸如sleep等阻塞的方法,所以我们需要使用setTimeout或setInterval来实现定时执行的功能。大部分现代浏览器中提供了一个新的方法requestAnimationFrame来代替普通的定时器,这是由FireFox首先实现的,虽然目前还不是标准,但是大部分现代浏览器中已经支持这个方法,你可能需要使用不同的前缀调用它,如:mozRequestAnimationFramewebkitRequestAnimationFrame。这个方法类似setTimeout,它由浏览器自行判断执行的时机,当页面不可见时它会自动降频,以达到节约资源的目的。它是你实现动画的最佳选择。它的执行频率大于是每秒60次,因为这是浏览器刷新的极限,如果再高对浏览器来说就没有意义了。当然对于不支持的浏览器我们可以使用setTimeout或setInterval来代替,相信你可以很容易的实现类似功能。下面是一个兼容的写法:

window.requestAnimFrame = (function() {
oreturn window.requestAnimationFrame
o|| window.webkitRequestAnimationFrame
o|| window.mozRequestAnimationFrame
o|| window.oRequestAnimationFrame
o|| window.msRequestAnimationFrame || function() {
o//return setTimeout(arguments[0], 1000 / 60);
oreturn -1;
o} // return -1 if unsupported
})();

window.cancelRequestAnimFrame = (function() {
oreturn window.cancelAnimationFrame
o|| window.webkitCancelRequestAnimationFrame
o|| window.mozCancelRequestAnimationFrame
o|| window.oCancelRequestAnimationFrame
o|| window.msCancelRequestAnimationFrame || function() {
oreturn -1;
o} // return -1 if unsupported
})();

当然你还要熟悉一下Canvas绘图的API。

首先你需要获取一个画布的对象,然后通过画布对象的getContext()方法获取一个绘图上下文。这个方法接受一个字符串参数"2d",这是目前你所能用的,当然还有其他的模式,比如WebGL,虽然已经被Chrome和FireFox所支持,但是MS的IE浏览器应该是不会支持了。通过这个绘图上下文你可以画线也可以画图形,可以描边路径也可以填充它,还可以直接绘制图片,或者直接操作图片数据等等。

网上有很多这方面的资料,这里就不多说了,文章的结尾我会给出一些参考资料。如果你对Canvas绘图不是很熟悉,MDN的Canvas教程将会是你的好选择。

这里我们做一个最简单的实例,让一个圆在画布上移动起来:

    o

  1. 首先我们需要把一个方框画到画布上。点击查看示例:http://jsfiddle.net/mqVZ7/1/
  2. o

  3. 接下来让我们每秒将小方块向右向下移动5个像素,并改变它的颜色。为了方便查看我们将小方块的透明度设置为.5。你会看到一串小方块运动的轨迹:http://jsfiddle.net/mqVZ7/2/
  4. o

  5. 这并不是我们需要的动画效果,它绘制的是一个轨迹而不是动画,要想实现动画效果,我们需要在每帧的绘制之前清除画布的所有内容,当然你还可以只重绘需要的部分。这里我们重绘整个画布,为了运动更平滑我们将移动的距离改为1个像素:http://jsfiddle.net/mqVZ7/3/

好了我们实现了我们想要的效果。当然你同样可以使用前面用过的数学公式。先说到这,后面会继续跟大家讨论控制动画对象等内容。

引用内容:

    o

  1. HTML DOM CanvasRenderingContext2D 对象
  2. o

  3. 玩转html5<canvas>画图
  4. o

  5. The canvas element
  6. o

  7. MDN Canvas

转载请注明原文出处《使用Canvas实现动画效果》 如无特别声明,所有文章均遵守创作共用 署名-非商业-禁止演绎 3.0协议。

动手开发一个HTML5赛车小游戏

你是不是曾经也有自己做一个游戏的冲动呢?是不是因为事情太多,手头没空或者没有做过游戏的基础而屡屡放弃了呢?现在HTML5正如火如荼,让我们一起使用HTML5中的新功能做一个小游戏玩玩吧。

先来看看效果:

在线演示地址:点击查看

源代码GitHub:点击查看

麻雀虽小,五脏俱全。先来说一下这个小游戏有的内容:

    o

  1. 一个开始画面,写了游戏的名字和一个开始按钮。
  2. o

  3. 游戏的主体内容,一个可以自己控制的小汽车,还有很多打酱油的汽车,另外还有马路及马路旁边的龙套树木和自行车道…
  4. o

  5. 一个结束游戏的画面。

好了这就是全部游戏的内容。游戏的玩法很简单,相信大家应该都玩过,就是一辆汽车在马路上跑,你要尽量躲避开其他汽车,不与他们相撞,否则游戏结束,游戏会以你跑过的旅程计算分数。

主要用的技术是HTML5中的画布元素Canvas和JavaScript。主要要做的工作就是实现Canvas的tween动画,一些简单的矢量,速度,位移等效果的处理。另外还有一些Sprint动画的处理。

具体的实现过程会在以后的文章中详细讲解。

目前本人正在进一步完善这个简单的JavaScript游戏引擎,以便使用这个游戏引擎实现一个SRPG游戏。新的游戏正在开发当中,如果您对此感兴趣欢迎联系我:dukai86@gmail.com

转载请注明原文出处《动手开发一个HTML5赛车小游戏》 如无特别声明,所有文章均遵守创作共用 署名-非商业-禁止演绎 3.0协议。