Showing posts with label js. Show all posts
Showing posts with label js. Show all posts

Friday, April 3, 2009

about factorial function

我承认,我被绕进去了。

// The Y combinator, applied to the factorial function
// https://javascriptlint.svn.sourceforge.net/svnroot/javascriptlint/trunk/spidermonkey/src/Y.js

function factorial(proc) {
    return function (n) {
        return (n <= 1) ? 1 : n * proc(n-1);
    }
}

function Y(outer) {
    function inner(proc) {
        function apply(arg) {
            return proc(proc)(arg);
        }
        return outer(apply);
    }
    return inner(inner);
}

print("5! is " + Y(factorial)(5));


// expand

Y(factorial)(5)
inner(inner)(5)
factorial(apply)(5)

(function (n) {
    return (n <= 1) ? 1 : n * proc(n-1);
})(5) // proc = apply

5 * apply(4)
5 * factorial(apply)(4)
5 * (function (n) {
        return (n <= 1) ? 1 : n * proc(n-1);
    })(4)
5 * (4 * apply(3))

Tuesday, March 24, 2009

the js lib in my heart 我心仪的js库

yui loader
jquery dom,dom-ev,ajax
goog class,oop
jsolait fn,package,socket

 

其实 jsolait 的loader 也挺好的,不过他只能同步,不能异步的load。
jaolait 的class和oop也挺好,不过稍显复杂,偏向 goog 的方式。
jquery 提供了良好和足够的操作 dom 和大多数 ajax 的功能,
如果要纯粹的脱离 dom 的事件机制,还是自己实现一下或者用 yui 的,或者 goog 的比较好。
jsoliat 提供的包管理和 socket 机制(通过 as 实现) 也挺不错。

 

希望这个项目里能够实现这个东西。
虽然是东拼西凑,不过确实期盼了很久的东西。
不知道会不会违反他们各自的版权呢。
呵呵。

 

顺应一下国情,先搞出来,
如果有了问题,
我再学习 gnu,自己实现一遍。
只是,
比较仰慕这些已经完善的实现而已。
有对这有兴趣人不,可以一起来搞嘛。

Wednesday, March 18, 2009

what is a empty array in javascript 空数组([]) 是什么东西?

先看测试

[]==false ? 'false' : 'true'//false
[]==true ? 'true' : 'false'//false
Boolean([]) ? 'true' : 'false'//true
(![]) ? 'false' : 'true'//true
([]) ? 'true' : 'false'//true

为啥有时候是 true,有时候是 false 呢?

参看:
逻辑AND(&&)运算符

Saturday, February 7, 2009

[emeditor宏] 插入HTML标签

不知道如何解释,用过 DW 的人应该知道 Ctrl + T ,这个就是模拟那个的,不过没有自动提示就是了。
建议将这个宏也设置快捷键 Ctrl + T 。(具体设置请参见 Emeditor Macros Help)

输入(将~换成空格)输出
table <table>{原来选中的文字}</table>
table~ <table width="100%" border="0" cellpadding="0" cellspacing="0">{原来选中的文字}</table>
table~,tbody,tr,td <table width="100%" border="0" cellpadding="0" cellspacing="0"><tbody><tr><td>{原来选中的文字}</td></tr></tbody></table>
div#abc,p <div id="abc"><p>{原来选中的文字}</p>>div>
div#abc,p,a~,img~ <div id="abc"><p><a href="#"><img src="" width="" height=""/>{原来选中的文字}</a></p>>div>
规则:
  • 将输入作为标签名,补齐开始和结束标所需
  • 如果只是签名和空格,则将空格用一些默认属性填充,具体见 autoprop
  • 遇到逗号(,),则将逗号分割的各词单独补齐成为标签,并将后面的标签添加为前面标签的子标签
  • 之前选中的文字则作为最内层标签的内容,如果最内层是自闭合标签,则之前选中的内容跟随最内层标签后面
待完善功能:
  • 是否使用其他符号替代空格来补齐默认属性
  • 可以更好的交互编辑,类似 TextMate 的 tab 模式
  • 增加同层节点,现在只能创建多层子节点
var tag, autoprop={ a: 'href="#"', div: 'class=""', style: 'type="text/css"', link: 'type="text/css" rel="stylesheet" href=""', script: 'type="text/javascript" src=""', input: 'type="" name="" value=""', img: 'src="" width="" height=""', table: 'width="100%" border="0" cellpadding="0" cellspacing="0"', iframe: 'frameborder="0" scrolling="no" width="" height="" src=""' }, sigletag={'br':1, 'link':1, 'hr':1, 'col':1, 'input':1, 'meta':1, 'img':1}; if(tag = prompt("请输入标签:", "div")){ if(tag.indexOf(',')==-1){ var t = buildTag(tag); document.selection.Text = t[1] + document.selection.Text + t[2]; }else{ var tags = tag.split(/, */), rstr = '', rstr2 = ''; for(var i=0,iM=tags.length;i<iM;i++){ tag = buildTag(tags[i]); rstr += tag[1]; rstr2 = tag[2] + rstr2; } document.selection.Text = rstr + document.selection.Text + rstr2; } } /* 返回 [标签,起始标签,结束标签] */ function buildTag(t){ var tagname=t.split(/ +/)[0]; var autoa = (t == tagname + ' ') && (tagname in autoprop); if(tagname.match(/[#\.]/)){ var id = tagname.match(/#([^\.]+)/), cls = tagname.match(/\.[^\.]+/g); t = tagname = tagname.match(/^([^#\.]+)/)[1]; if(id)t += ' id="' + id[1] + '"'; if(cls){ t += ' class="' + cls.join(' ').replace(/\./g, '').replace(/ +/g, ' ') + '"'; } if(autoa)t += ' '; } if(autoa){ t += autoprop[tagname]; } return [tagname, "<" + t + (tagname in sigletag ? ' />' : '>'), tagname in sigletag ? '' : ("</" + tagname + ">")]; }

date js

关于日期时间操作的 js 函数库 date-js 。简单实用。

/** date set() clone() fmt() Y() ~ FullYear m() ~ Month d() ~ Date H() ~ Hours M() ~ Minutes S() ~ Seconds s() ~ Milliseconds t() ~ Time [static] from() 使用示例 var d = date(), D = new Date(); D.getMonth() == d.m() D.getFullYear() == d.Y() D.setFullYear(1999) == d.Y(1999) D.setHours(8) == d.H(8) d.set('m+1') == D.setMonth(D.getMonth() + 1) d.set('Y2008m0') == (D.setFullYear(2008) && D.setMonth(0)) d.fmt('%Y-%m-%d %H:%M:%S.%s %%s') == '2009-02-04 22:23:45 %s' set() 如果带 +/- 操作,那么表示将相应的项添加或者减少(W 表示增减周.7天.)。 如果不带 +/- 操作,那么: Y 的设置将自动取当前年的前 n 位补齐 Y 不够 4 位的部分,例如 Y34 会被认为是设置 2034 年,Y123 会被认为是设置 2123 年(假设当前时间为 2009年)。 M 的操作会按照月份的数字设定,比如 M1 将设置月份为 1月,M12 设置月份为 12月,M0 则设置为上一年的最后一月(年份会自动减小)。 W 的操作会设置周几,比如,假设当前为周三,那么 W1 会将日期前移 2 天(到周一),W0 会将日期前移 3 天,到上周日,W7 会将日期后移到本周日,如果设置大于 7 也可以,不过应该比较难理解了。 其他按照字面意思进行。 示例: Q: 这个月有多少天? A: d.set('M+1D0').D() Q: 上个月有多少天? A: d.set('D0').D() Q: 5 月有多少天? A: d.set('M6D0').D() Q: 这周的第一天是哪天,最后一天呢(假设第一天是周一)? A: d.set('W1'), d.set('W7') Q: 如果要显示这个月的日历,那么第一天和最后一天是什么(假设第一天是周一)? A: d.set('D1W1'), d.set('M+1D0W7') Q: 上一个问题中,如果所有日历都显示 6 周,那么最后一天如何计算? A: d.set('D1W1'), d.set('D1W7W+5') */ var date = (function(){ function now(){return new date()} function iter(obj, fn, o){ o = o || obj; if(!(obj && typeof obj == 'object')){ return; } var i, l = obj.length; if(typeof l == 'number'){ if(l){ for(i=0;i<l;i++){ if(fn.call(o, obj[i], i, obj) === false){ break; } } } }else{ for(i in obj){ if(obj.hasOwnProperty(i)){ if(fn.call(o, obj[i], i, obj) === false){ break; } } } } return iter; } function mixin(target, source){ for (var x in source) { target[x] = source[x]; } return mixin; } function date(Y, m, d, H, M, S, s){ var r = this; if(this instanceof date){ this._d = new Date; }else{ r = new date; } if(arguments.length){ r.t(new Date(Y, m, d, H, M, S, s).getTime()); } return r; } mixin(date, { conv:{ 'Wm':10080, 'dm':1440, 'WS':604800, 'dS':86400, 'Ws':604800000, 'ds':86400000, 'Hs':3600000, 'Ms':60000, 'Ss':1000, 'ss':1 }, from:function(s){ return new date().set(s); } } ); iter( { Y: 'FullYear', m: 'Month', d: 'Date', H: 'Hours', M: 'Minutes', S: 'Seconds', s: 'Milliseconds', t: 'Time' }, function(v, k){ date.prototype[k] = (function(s,g){ return function(v) { v!==undefined && v!==null && this._d[s](v); return this._d[g](); } })('set' + v, 'get' + v); } ); mixin(date.prototype, { set: function(str){ var d= this; str.replace( /[YmdWHMSs][+-]?\d+/g, function(w){ w= w.match(/(\w)([+-]?)(\d+)/); var f=w[1], //key v= w[3], //value s= w[2]; //type(+/-) if(s==''){ if(f=='Y' && v.length < 4){ v= '' + String(now().Y()).slice(0,4-v.length) + v } if(f=='m'){ v= parseInt(v)-1; d.m(v); }else if(f=='W'){ v= parseInt(v)-d.getDay(); if(v){ d.set('d' + (v>0?'+':'') + v); } }else{ d[f](parseInt(v)) } }else{ v= parseInt(s+v, 10); if(v){ switch(f){ case 'Y': case 'm': d[f](d[f]()+v); break; default:// dWHMSs d.t(d.t() + v * date.conv[f+'s']); break; } } } return '' } ); return this }, fmt: function(str){ if(!str){ str = 'YY-mm-dd HH:MM:SS'; } var d= this; return str.replace( /%([YmdHMS%])/g, function(w, s){ return s == '%' ? s : (('' + d[s]()).replace(/^(\d)$/, '0$1')); } ); }, clone:function(s){ return new date(this.t()).set(s); }, toString: function(){ return this._d.toString.apply(this._d, arguments); }, valueOf: function(){ return this._d.valueOf.apply(this._d, arguments); } } ); //date.prototype.str = date.prototype.format = date.prototype.strfmt = date.prototype.fmt; return { iter: iter, mixin: mixin, date: date, now: now }; })().date;

Friday, February 6, 2009

[Rel] JavaScript正则表达式生成器

看到写的东西,找不到留言的地方,遂自己写一个。

//原始实现 function convertToJsEsc(chars) { var result = ''; for(var i=0; i<chars.length; i++) { var code = chars.charCodeAt(i); switch (code) { case 0x20: result += "\\s"; break; case 0x22: result += "\\\""; break; case 0x27: result += "\\\'"; break; case 0x28: result += "\\("; break; case 0x29: result += "\\)"; break; case 0x2A: result += "\\*"; break; case 0x2B: result += "\\+"; break; case 0x2E: result += "\\."; break; case 0x2F: result += "\\/"; break; case 0x3F: result += "\\?"; break; case 0x5B: result += "\\["; break; case 0x5C: result += "\\\\"; break; case 0x5D: result += "\\]"; break; case 0x7B: result += "\\{"; break; case 0x7D: result += "\\}"; break; default: if(code > 0x1F && code < 0x7F) { result += chars[i]; } else { result += "\\u" + code.toString(16).toUpperCase(); } break; } } return result === "" ? "Nothing to convert" : result; } //我的修改 function convertToJsEsc(chars) { return chars && chars.replace( /([ "'\(\)\*\+\.\/\?\[\\\]\{\}])|([\x1F-\x7F])|(.)/g, function(all, a, b, c){ return a ? ('\\' + (all==' '?'s':all)) : b ? all : ('\\u' + all.charCodeAt().toString(16).toUpperCase()); } ) || 'Nothing to convert'; }

有啥区别?
优点:方便修改
缺点:难于理解。

Thursday, December 4, 2008

自定义滚动条

用法
给需要添加滚动条的 div 添加 class "autoscroller",设置模块高度。
注意,这个 div 只可以包含一个子节点。
html
<div style="height:100px;" class="autoscroller"> <div style="height:150px;"></div> </div> css
.autoscroller{position:relative;overflow:hidden;} .autoscroller .scrollcon{overflow:hidden;} .autoscroller .scrollbar{ position:absolute;right:0;top:0;width:9px; background:#fff;font-size:1px;line-height:1px;} .autoscroller .scrollbar s{ position:absolute;left:3px;top:0;height:100%;width:2px; border-left:1px solid #c3c3c3;background:#000;} .autoscroller .scrollbar i{ width:9px;position:absolute; background:url(scroller_btn.gif) repeat-y 0 0; cursor:n-resize;left:0;top:0;} .autoscroller .scrollbar i b{ background:url(scroller_btn.gif) no-repeat -9px 0; display:block;padding:4px 0 0;} .autoscroller .scrollbar i b b{background-position:-18px 100%;padding:0 0 4px;} .autoscroller .scrollbar i b b b{background-position:100% 50%;}

img

js
//require: jquery, drag, wheel function fix_scrollers(){ var j = jQuery; /* .autoscroller .scrollcon .scrollbar s i b b b*/ j('.autoscroller').each(function(idx, sc){ sc = j(sc); var con = j('<div class="scrollcon"/>').appendTo(sc), con0 = con[0]; con.append(sc.find('>*:first')); var h = [sc[0].offsetHeight, con0.scrollHeight]; if(h[0] - h[1] >= 0)return; var bar = j('<div class="scrollbar"></div>').appendTo(sc), btn = bar.find('>i'); con.css('height', h[0] + 'px'); bar.css('height', h[0] + 'px'); bar.find('>s').css('height', h[0] + 'px'); j(j.dir(btn[0], 'firstChild').pop()).css('height', Math.max(0, (h[0] * h[0] / h[1]) - 8) + 'px'); var btnYA = [0, bar[0].offsetHeight - btn[0].offsetHeight]; var sRate = Math.min(1, btnYA[1] / (h[1] - h[0])), wheelPH = -25 * sRate; var drag_posY = null, drag_top = null; btn.bind('dragstart',function(ev){ drag_posY = ev.offsetY; drag_top = parseInt(btn.css('top')) || 0; }) .bind('drag',function(ev){ var offsetY = ev.offsetY - drag_posY; var top = Math.max(btnYA[0], Math.min(btnYA[1], drag_top + offsetY)); this.style.top = top + 'px'; con0.scrollTop = top / sRate; }); sc.mousewheel(function(ev, delta){ var btnTop = parseInt(btn.css('top')) || 0; if((btnTop==btnYA[0] && delta > 0) || (btnTop==btnYA[1] && delta < 0))return true; btnTop = Math.max(btnYA[0], Math.min(btnYA[1], btnTop + delta * wheelPH)); btn[0].style.top = btnTop + 'px'; con0.scrollTop = btnTop / sRate; return false; }); }); }

Thursday, April 24, 2008

如何获取服务器时间

这个比较常用,比如倒计时时,怕客户端时间不准确就会用到服务器时间。但是怎么得到呢?

<script type="text/javascript">var t1 = new Date;</script> <script type="text/javascript" src="get_server_time.asp"></script> <script type="text/javascript"><!-- var t2 = new Date; console.log('请求开始      ',t1.getTime()); console.log('请求得到的服务器数据',s_now.getTime()); console.log('服务器返回请求并执行',t2.getTime(), t2.getTime() - t1.getTime()); // --> </script>

用上面这段代码可以得到服务器时间,其中 get_server_time.asp 包含

var s_now = new Date(<%=(new Date).getTime()%>);

这个方法有个问题,那就是延迟。延迟不会很大,不超过上面 t2 - t1 的差值,在本地服务器上测试时候徘徊在 50ms。
倒计时有 2 种做法,基础都是每隔一段时间 p 执行一个函数。
一种是每次将剩余时间减去 时间间隔 p,
另一种是取客户端时间计算实际的剩余时间,然后减去服务器与客户端的时间差。
第一种方法的问题在于浏览器中的 setTimeout 和 setInterval 函数都不能绝对准确的按照给定的 p 来周期执行函数,我测试的结果是大概 10 分钟会偏差 1 到 2 秒。
第二种方法的问题在于,你不能保证用户在查看页面的同时不会修改本地系统时间。
如果结合 2 种方法,会好些,代价是牺牲一些效率。