無標題文檔

nicEdit 中文版

Typecho 的项目已经启动。小组需要个功能强大而且小巧,并且容易 Hack 的 Javascript 编辑器。我首先想到的是 FCKEditor 以及 TinyMCE 。

FCKEditor 功能虽然强大、插件众多,但代码量和占用的客户端的资源也是巨大的。 TinyMCE 相对小巧,功能方面也并不弱,不过其使用协议还是很多不明确的地方。

sluck 以及 joyqi 兄弟的推荐下,尝试使用一款名为 nicEdit 的编辑器,基本上表示满意。

功能方面,nicEdit 已经满足了基本编辑器的需求。而我关注的代码方面,它也是非常精简的。整个编辑器就是声明了个大的 nicEdit 的类(非常的环保),扩展起来非常的容易。

推荐对 Javascript 有兴趣,并且想了解编辑器原理的朋友可以看下它的代码,收获会良多。最后,在看其代码的同时,顺便汉化了下,汉化以后的包可以在 这里下载

同时,也可以先看下我 Blog 上面扔的 DEMO

http://friable.rocks/historic/demo/nicEdit/

YUI 读码日记之 YAHOO.util.Dom - Part.4

YAHOO.util.Dom 中的 getXY 函数让开发者充分体验到不同浏览器的 Hack 的乐趣。 IE8 即将破壳而出,但愿下面的函数不会又多个 if 判断。getXY 函数使用 匿名函数执行返回 函数(听起来有点拗口,可以参考 圆心 Blog 上的 一篇文章 )。

var getXY = function() {
    // 判断是否是 IE
    if (document.documentElement.getBoundingClientRect) {
        // 注1
        return function(el) {
            var box = el.getBoundingClientRect();

            var rootNode = el.ownerDocument;
            return [box.left + 
          Y.Dom.getDocumentScrollLeft(rootNode), box.top +
                    Y.Dom.getDocumentScrollTop(rootNode)];
        };
    } else {
        return function(el) {
            var pos = [el.offsetLeft, el.offsetTop];
            var parentNode = el.offsetParent;

            // 判断是否在 Safari 下,节点是否为 absolute ,
            // 并且父元素是否为 body
            // 注2.
            var accountForBody = (isSafari &&
                    Y.Dom.getStyle(el, 'position') == 'absolute' &&
                    el.offsetParent == el.ownerDocument.body);

            // 如果父元素不是自身
            if (parentNode != el) {
                while (parentNode) {
                    pos[0] += parentNode.offsetLeft;
                    pos[1] += parentNode.offsetTop;
                    if (!accountForBody && isSafari && 
                            Y.Dom.getStyle(parentNode,'position') 
                                                  == 'absolute' ) { 
                        accountForBody = true;
                    }
                    parentNode = parentNode.offsetParent;
                }
            }

            // 还是针对 Safari 的
            if (accountForBody) { //safari doubles in this case
                pos[0] -= el.ownerDocument.body.offsetLeft;
                pos[1] -= el.ownerDocument.body.offsetTop;
            } 
            parentNode = el.parentNode;

            // account for any scrolled ancestors
            while ( parentNode.tagName && 
                         !patterns.ROOT_TAG.test(parentNode.tagName) ) 
            {
               // work around opera inline/table scrollLeft/Top bug
               // 注3.
               if (Y.Dom.getStyle(parentNode, 'display')
                                  .search(/^inline|table-row.*$/i)) { 
                    pos[0] -= parentNode.scrollLeft;
                    pos[1] -= parentNode.scrollTop;
                }
                
                parentNode = parentNode.parentNode; 
            }

            return pos;
        };
    }
}() // NOTE: Executing for loadtime branching
  1. 注. 有关 IE 的 getBoundingClientRect 方法,可以 参考这里
  2. 注. Safari 的 BUG,详细情况 参见这里
  3. 注. 参见老外的原话( 出处 ):
"- Remove parent scroll UNLESS that parent is inline or a table 
to work around Opera inline/table scrollLeft/Top bug"
Fixed in Opera 9.5. (also, Opera 9.5 supports getBoundingClientRect 
and getClientRects.)

最后,有关更多 DOM 的兼容性,可以参看 PPK 的总结怎么又是他 )。

YUI 读码日记之 YAHOO.util.Dom - Part.3

在 YAHOO.util.Dom 中能发现很多有趣的东西。下面先说下 toCamel 的函数,感谢 小马 帮助我理解了这个函数。toCamel 把指定名称替换为驼峰写法,比如把 border-width 替换为 borderWidth 。

var patterns = {
    HYPHEN: /(-[a-z])/i,
    ROOT_TAG: /^body|html$/i
};

var toCamel = function(property) {
    // 如果没有 -[a-z] 字母,则直接返回
    if ( !patterns.HYPHEN.test(property) ) {
        return property;
    }
    
    // 如果有缓存,直接返回替换后的值
    if (propertyCache[property]) {
        return propertyCache[property];
    }
   
    // 使用正则替换
    var converted = property;
    while( patterns.HYPHEN.exec(converted) ) {
        converted = converted.replace(RegExp.$1,
                RegExp.$1.substr(1).toUpperCase());
    }
    
    // 存入缓存
    propertyCache[property] = converted;
    return converted;
};

在 YAHOO.util.Dom 中,getStyle 函数考虑了更多不同浏览器兼容性方面的问题,代码如下

// 使用 W3C DOM 标准的浏览器,比如 Firefox、Opera、Safari
if (document.defaultView && document.defaultView.getComputedStyle) {
    getStyle = function(el, property) {
        var value = null;

        // 重命名部分 CSS 样式名
        if (property == 'float') {
            property = 'cssFloat';
        }

        // 获取通过 CSS 加上去的属性
        var computed = document.defaultView.getComputedStyle(el, '');
        if (computed) {
            value = computed[toCamel(property)];
        }
        
        return el.style[property] || value;
    };
// 如果是 IE 浏览器
} else if (document.documentElement.currentStyle && isIE) {
    getStyle = function(el, property) {                         
        switch( toCamel(property) ) {
            // 「转换」名称为 IE 可以认识的
            case 'opacity' :
                var val = 100;
                try {
                    val = 
                        el.filters['DXImageTransform.Microsoft.Alpha'].opacity;
                } catch(e) {
                    try {
                        val = el.filters('alpha').opacity;
                    } catch(e) {
                    }
                }
                // 百分比
                return val / 100;
            case 'float': 
                property = 'styleFloat'; 
            default: 
                var value = el.currentStyle ? el.currentStyle[property] : null;
                return ( el.style[property] || value );
        }
    };
} else {
    // 获取内联样式
    getStyle = function(el, property) { return el.style[property]; };
}

另外,PPK 在他的 Blog 上的 有关 getStyle 的阐述 ,也很精彩,有兴趣的可以去看下。

我的照片

嗨!我叫「明城」,八零后、码农、宁波佬,现居杭州。除了这里,同时也欢迎您关注我的 GitHubTwitterInstagram 等。

这个 Blog 原先的名字叫 Gracecode.com 、现在叫 「無標題文檔」 。 要知道作为码农取名是件很难的事情,所以不想在取名这事情上太费心思。

作为八零后,自认为还仅存点点可能不怎么被理解的幽默感,以及对平淡生活的追求和向往。 为了避免不必要的麻烦,声明本站所输出的内容以及观点仅代表个人,不代表自己所服务公司或组织的任何立场。

如果您想联系我,可以发我邮件 `echo bWluZ2NoZW5nQG91dGxvb2suY29tCg== | base64 -d`

分类

搜索

文章