— Designsor

顾名思义,拼写检查。

不多说,截图看一下说明问题:

设置元素的这个属性为false即可关闭拼写检查:

默认为true值,如果设置为readonly或者disabled,则默认为false。

除了ie之外,ff,chrome,safari,opera都支持~

经常有产品或者测试问我这货是什么,这次你们都知道怎么和他们解释了吧,你妹的……

同样还有chrome的元素outline(焦点移上带个黄色或者红色边框),max-height,max-width属性(textare的自带拖拽高宽)等小细节,经常让一些测试用chrome的时候感到迷茫,甚至给你提bug,真哭笑不得,可能要怪就怪浏览器帮你做的太多了吧。。。无奈。

Read More

最近越来越需要选择一门比较好,全能型的后端编程语言来学习了,javascript虽然万能,但是写了这么久,虽然自身不足还很多,但是多触类旁通一些别的编程语言,我相信对自己是有利无害的。以前目标订的比较大,想学as,想学python,想学c,想学ruby,想学nodejs,啥我都想学……= =

但是其实匆匆扫过一遍,我发现,到底选哪个真的不是谁告诉你好,就真的好了,还是需要你自己亲自去尝试。

之前我看jsdoc里通过rhino.jar给java扩展的一些js方法,让我对java又重拾了好感,搜索了一圈,发现java也具有自己的一些特点和特性,虽然10个程序员9个java男,但是我相信这么流行他是有理由的。

明确需求吧,我需要一个能做软件,能辅助做小工具,能做web又能做客户端的语言。其实java,python,ruby,c,.net是都满足的,那么好吧,这几天我会以此尝试用这几个语言编写同一段代码实现功能,来自我感受。

那这篇文章就先写对python和java的感觉:

我定制了一个小目标,虽然涵盖不是特别全,但是却都是我感兴趣的知识点-遍历一个目录,然后给目录的文件批量增加时间戳。

OK,就这么个功能,看下代码吧

java的代码

//package java.my.util;
import java.util.Date;
import java.io.*;
public class ReadFile
{
	public interface CallBack{
		String callname(String fliename);
	}
	private static String[] ReadFolderName(String src)
	{
		File flie = new File(src);
		String[] names = flie.list();
		return names;
	}
	private static File[] ReadFolder(String src)
	{
		File flie = new File(src);
		File[] files = flie.listFiles();
		return files;
	}
	private static void ChangeName(String src,CallBack callback){
		String[] names=ReadFile.ReadFolderName(src);
		File[] files=ReadFile.ReadFolder(src);
		for(int i=0;i<files.length;i++){
			String newname = callback.callname(names[i]);
			files[i].renameTo(new File(src+"/"+newname));
		}
	}
	public static void main (String arg[])
	{
		ReadFile.ChangeName("../src/js",new CallBack(){
			public String callname(String fliename){
				Date date = new Date();
				long time = date.getTime();
				String newname = "";
				int dot = fliename.indexOf(".");
				String fordname = fliename.substring(0,dot);
				String remnant = fliename.substring(dot,fliename.length());
				int isAdd = fliename.indexOf("-");

				if(isAdd == -1){
					newname = fordname + "-" + time + remnant;
				}else{
					fordname = fliename.substring(0,isAdd);
					newname = fordname + "-" + time + remnant;
				}

				return newname;
		}
		});
	}
}

python代码:

import os
import yaml
import string
import time

RootPath = os.getcwd()
configFile = open(RootPath + 'config.yaml')

CG = yaml.load(configFile)

def addstrftime(name):
  t = time.strftime('%Y%m%d%H%M%S',time.gmtime())
  if string.find(name,'-') != -1:
    oldname=string.split(name,'-')[0]
    return oldname+'-'+str(t)
  return name+'-'+str(t) 

def changeAllFileName (path, remnant = '' , callback = None):
  for filename in os.listdir(path):
    diction=string.split(filename,'.')
    if callback==None:
      name=diction[0]
    else:
      name=callback(diction[0])
    if remnant=='':
      remnant=diction[1]
    os.rename(path+filename,path+name+'.'+remnant)

changeAllFileName(CG['jsroot'],'css',addstrftime)

我是先写的python的代码,后写的java的代码,然后我就觉得我真不能写java,虽然上手感觉也不难,不得不说,写习惯了js,写别的语言,咔咔咔就可以引进一坨的工具包的感觉确实很爽。读取本地文件,配置文件也相当痛快,好吧,允许我这个没写过多少后台代码的人感叹一下吧= =。

然后就是对比2个语言,明显python的代码实现的更短,支持函数传参回调,当然java我也实现了,但是比较恶心,后来问了朋友,说java支持对象和整型,你要传函数就是不可以- -,python的话,代码写的少,简洁优雅,java的话类型太复杂- -。我写一会就觉得好讨厌,啥玩意都要先来个类型,怪不得以前的java男们总会问我,这个js支持不支持这个类型的参数?o,mygod- – 我当然知道这是避免报错,你看看连方法都要标明是不是void还是return回什么。。写习惯了js,我确实不习惯,但是我也知道,java男们从一入门就开始各种面向对象了,确实不易- -||

引用工具包得方法大同小异,就语言来说,写到这里已经决定了,我肯定是要搞python了,但是java的优点,从那个小例子也看的出来,强迫你写通用的东西,强迫你知道自己在干什么,强迫你搞单元测试,强迫你养成一些基础的编程习惯,就我看来也挺好的。

python相对更灵活,更贴近我现在写的js,当然他们说ruby更贴近,等我过几天把c和ruby的版本搬上来,再看吧。总之……╮(╯▽╰)╭,我也发现了,无论什么东西,其实任何语言都可以实现的,还是看个人喜好,和对“真正”的编程,理解又有多深了。。

Read More

新岗位工作有快一个月了,一个月的产出和工作效率,用一个词来形容就是“荒芜”。意思是,啥积累都木有,零散的页面中的js脚本,和一些根本都没人实现的工作,在一来到这边就开始马不停蹄的开发了。

面对这样的情况,快速实现需求肯定是第一位的了。基于jquery1.6.2的一套自己设计的业务层,就这么被匆忙搭建起来了。

在进行搭架子的时候,最开始想到的是代码的版本管理,由于这边的服务器静态文件没有设置svn,所以我全部本地使用git+localhistory的方法管理自己的代码,由于现在开发人员只是我一个人,这种方式还算说的过去,以后人多了可以直接用git进行多人协作。于是申请了新的git代码仓库:

https://github.com/xiaojue/goodmedia

嗯,目录结构很清晰我自己简单解释一下,里面很多的东西都不完善……

bulid是存放最后打包完的源码,打包采取ANT的方式。css是存放全站样式表的地方,每次bulid都会下载最新的,每次update都会上传本地我最新的。demo是存放一些简单的本地调试例子的,jquery存放jquery源码,php里存放一些本地调试需要的php脚本文件,src存放gm的源码,test里存放测试代码,(这里没有使用测试框架,只是简单的测试例子,可以也理解成demo,后期会转换成统一的测试用例),tool一些自动化工具,xdoc是xweibo的文档【项目里有用到】,xwb放得是xweibo的源码,doc存放的是以后gm的说明文档。

架子搭好,我们主要来说src这一部分:

src里分了4个目录,core主要维护核心的gm对象,widget一些通用性较强的组件,tools经常使用到的工具方法,apps一些通用性不强的单独代码文件。

最开始设计就是这样的,因为底层有jquery强大的支持,很多东西都不用自己写了,所以core主要维护中间层的组织关系和加载方式,调试等。widget和apps是2个对应关系的目录,一个有通用性,一个无通用性【大部分业务代码】,而tools则属于非常常用的方法集合,直接和core捆绑打包成最后的文件。通过这4个目录最后集成的这个东东,我叫它是js的一个中间层。

因为他们之间是有联系,又可以相互之间扩展通讯的,主要看下core目前的样子:

https://github.com/xiaojue/goodmedia/blob/master/src/core/GMcore.js

很简单,以后可能还会扩展方法,目前来说就是用来维护命名空间,定义widget和apps的加载和协议方式,还有一些区分debug和本地开发调试的判断.

而这里widget在最开始我也是打包进最后的文件中的,但是发现它的通用性并不那么强,所以后来又增加了use方法来按需调用:

他和apps的require方法大同小异,这里单说require方法吧,所有的apps目录下的js文件书写是要按照一定的规格的,这里简单引用了一下commonjs的规范,对require进来的js文件,回调中使用exports这个通用接口来使用方法。

例如,随便起一个新的app,那么它初始的代码一定是这样子的:

(function(W,G){
   var newapp=function(){
        //放置似有属性和方法
        return{
            exports:{} //存放对外接口。
        }
   }();
if(G && G.apps) G.apps.newapp=newapp; //挂在到相应命名空间。
})(window,GM)

再看那个gm的require方法:

GM.apps.require=function(appname,callback){
  var appuri = GM.host + 'apps/'+appname+'/'+appname+'-min.js';
	if(GM.debug) appuri=locality(appuri);
	$(function(){
		$.getScript(appuri,function(){
			if(callback) callback(GM.apps[appname]['exports'])
		});
	});
}

这里在getscript之后的回调中,只暴露了我们事先设置好的exports作为统一的模块接口。

那么好,简单的模块式开发的设计就这样完成了……余下的时间就可以专心的分文件编写我们的各种级别代码了。
最后我们用ant进行统一的打包,压缩,部署,这个是老生常谈了,具体可以看我的bulid文件,其中有一个地方要注意,就是在调试或者开发阶段,如何能快速的在线上看到效果而不用每次都跑一下bat脚本,然后等待呢?

嗯,开一个debug,然后路径引用本地相应的src文件就ok了,但是这里只能让apps和widget下的有效,tools和core的还是需要重新打包,日后我可能还会把他们全部拆开,只用一个种子文件进行部署,那么就都可以解决了,学的yui么..

其他的相关代码就没什么好讲的了,都是些应用级别的了~以后要继续完善的就是测试和文档这一块,再然后就是拆分更细的粒度,我感觉有点像kissy啊- -可是我毕竟没那么强大,恩,缺的东西还很多,毕竟jquery阻止代码这一块并不是做的最好的,噢,最后一点,所有的tools都最后用jquery的插件开发模式绑定到jquery对象上了,换句话说,每个tools里的js文件,以后单拆出来,就是一个jquery插件~

恩,期待自己下个月的表现…

Read More