[email protected]:~$

  • 开发编辑器的过程中遇到的一些浏览器差异

    测试新编辑器时发现在firefox下会有很高几率出现一个神奇的bug。 当光标在block元素(blockquote, pre, etc..)中时,按‘下’或‘右’或‘回车’键后,光标会选中block元素中第一段文本。刚开始怀疑是在FF下rangy设置selection的bug,但在注释所有js中keydown的处理事件后,还是会有此bug。 之后百思不得其解,甚至想到用scribe重写编辑器… 在观察scribe的demo在FF下的表现后,终于找出了这个很愚蠢的bug… 在blockquote中我特地的把p标签转换成text + <br>,但实际上在html4中是要求blockquote等块状元素中需要存在p标签(这是来自stackoverflow的一个回答,我没有看html4标准..),所以我特地的去除p标签反而是画蛇添足之举。 在chrome, IE等浏览器下对于<blockquote>test<br></blockquote>这种html没有特殊限制,浏览器的默认行为完全可以正常工作。 但是在firefox下,当光标在test文本末端时,按下回车,本应换行,但是firefox会去寻找当前的p标签(这是html4规范,Firefox依赖了此规范,chrome等则没有),但是我错误的没有把文本放入p标签,所以造成浏览器默认行为出现bug。 正确的标签应该是<blockquote><p>test<br></p></blockquote>这样才符合html规范。 在开发编辑器的过程中,接触到了很多这种浏览器默认行为不一致的问题。 比如firefox下偶尔会对br标签加上type="_moz"的属性。 chrome和safari下拖拽block中元素浏览器会把拖拽的文本放入span并且自动添加很多style属性。 在webkit内核浏览器中block元素里按回车会在下一行自动添加同样的block元素,在FF中则是自动换行。 如果一行中有br,在IE下光标在br之后,其余的浏览器则是在br之前(偶然通过range对象观测到的,在block末尾时IE中的endoffset会多1) 浏览器的很多上层API加上跨平台库已经让人很少能感受到js编程的平台差异,但是在contenteditable中诸如此类html中并无规定的默认行为在不同浏览器上的表现却是千差万别。尤其是号称跨平台的selection库rangy实际上在不同平台上还是会有很多bug与不一致,举例来说最基本的获取range对象,在webkit浏览器上取得range,start和end会优先是textElement,但是在FF上则会得到ElementNode。 html规范毕竟不可能涵盖所有情况,各种标签的嵌套以及不同情况下用户的操作,这些规范之外的情况只能靠具体的实现来决定行为。 就像各种的markdown解析器,在规定之下会输出相同的结果,但若在规定之外,每个parser都会有些许的差别。 看来浏览器距离完美的平台还有不短的距离..

  • javascript学习笔记(二)

    1, 函数中this的四种情况 //1. 函数绑定到对象上时, this为对象 a = {func: function(){ console.log(this)}} a.func() // this是a //2. 没有绑定到对象时,this为全局对象 (function(){ console.log(this) })() //上面的this在浏览器中是window(全局对象) //3. 用new调用时this绑定到新构造的对象 //4. 函数对象的apply方法 (function(){console.log(this)}).apply("hello") //通过apply可以指定function的this值 2, 原型 //javaScript中的原型继承必须通过函数来完成 //function有一个很重要的prototype属性,默认值为{} (function(){}).prototype //=> Object {} //函数的prototype属性是javascript中原型的关键 //用new去调用function时,会以该函数的prototype为原型构建对象(常用此行为来模拟继承) a = {hello: function(){return "world"}} //现在来构建一个链接到a的对象,首先需要一个function A = function(){} A.prototype = a //用new调用A时会构建出以对象a为原型的对象 b =...

  • javascript学习笔记(一)

    以前没怎么用过javascript(仅停留在简单的dom处理与ajax上),身为后端程序员对其印象仅有杂乱 完成简书新richtext编辑器的基本功能后,感到js也没这么不堪,反而基于原型的模型能很轻易的应对反射,动态定义Function/Object等‘元编程任务’ 并且和ruby中的’元编程’不同,在js中这些就是通常编程 “原型”的表达力不弱于OO,并且复杂程度远小于OO。当然在javascript中的实现还是略微杂乱..虽然这门语言很多细节部分的设计让人匪夷所思,但是其核心的原型功能还是兼具了精简与好用这两处优点 遂打算好好学习下js, 并在阅读《JavaScript语言精粹》时把一些知识要点记录下来 本文会以tips的方式罗列从书中获取的知识要点,以及一些我自己的理解和对这门语言的想法 所有内容基于ECMAScript-262 (javascript 1.5) false,js的条件判断中 0, -0, null, false, "", undefined, NaN 均为 false(coffeeScript中的?操作符编译为typeof a !== "undefined" && a !== null;使其行为接近一般语言) Number,js中数字储存为(相当于java中的)double, 所以1/2会等于0.5 基本类型,js中有 Number, Boolean, String, Array, Object, undefined几种类型,Boolean, String, Array, Object都属于Object(因为可以用原型系统, null比较特殊) 对比,js中==仅对比值,===更为严格,要求类型也一致(coffeScript把这两个颠倒了过来,更加接近一般语言的行为) 注释,js中单行注释用//,导致你无法用//来表示一个空的正则,/**/也是 原型继承,js中通过键来获取对象中的值时,如果该对象无此键,则会到对象的原型链中去查找,直到Object的prototype,任何对象都隐含链接到Object.prototype,该值默认是{} 更改对象的键时不会影响到原型 delete操作符,用来删除对象的键(不会影响到原型),这时对象原型的相应键会暴露(如果有的话),再次delete会被忽略并返回true(这代表如果原型上有key,则没办法在对象上删除该键,但是可以赋值为undefined) for..in 语句可以用来遍历对象的所有key hasOwnProperty方法用来判断对象是否有该key(从原型中继承的不算)