[ Content | Sidebar ]

Posts tagged javascript

ie下暴力debug js

ie下的脚本错误总是很神秘的样子,告诉你哪个行,确不告诉你哪个文件,Visual Studio带了一个调试工具倒是可以,long long ago之前用过一次,老崩溃的样子~
如果你又遇到了猜不透的bug,可以尝试下面的shell~

//现去firefox里收集一份js列表
var alljs = [];
XN.array.each(document.getElementsByTagName('script'),function(i,v)
{
    if (v.src)
    {
        alljs.push(v.src);
    }
});
console.log(alljs.join('\n'));
Copy Code 

把列表保存到一个文件,下面跑段shell,把所有js的报错位置的代码打印出来

// 10 100是ie里提示的错误位置
sh ~/bin/get_line.sh /tmp/jslist 10 100
Copy Code 

附:

#!/bin/sh
LIST="$1"
ROW="$2"
COL="$3"
 
if [ ! -n "$ROW" ];then
    exit
fi
 
echo "行:${ROW}"
echo "列:${COL}"
 
get_row()
{
    cat /tmp/js_debug_tmp | sed -n "${ROW}p"
}
 
cat "$LIST" | while read line
do
    wget -q "$line" -O /tmp/js_debug_tmp 
    echo "文件:${line}"
    row="`get_row`"
 
    if [ -n "${COL}" ]; then
        row="`echo \"${row}\" | cut -c ${COL}- `"
    fi
 
    echo "$row"
done
rm /tmp/js_debug_tmp
Copy Code 

javascript做html字符串的截断

2010.2.6 日修正
————————————
2010.2.3 日修正

<html>
<!-- html字符截断第二版 bug修正 + 2.6日修正-->
<script>
function sub_html_str(str, num)
{
    var reg = new RegExp( '<[^>]+>' , 'g' );
    var rt, rts = [], indexs = [], tstr, endstr, rstr, sstr, endtag, rtstr;
 
    //提取所有的html标签和标签在字符串中的位置 
    while ( ( rt = reg.exec(str) ) != null )
    {
        rts.push(rt[0]);
        indexs.push(rt['index']);
    }
 
    //删除字符串中所有的html标签
    tstr = str.replace(reg, '');
    //对剩余的纯字符串进行substr
 
    sstr = tstr.substr(num, tstr.length);
    tstr = tstr.substr(0, num);
 
 
 
    //判断有没有把实体腰斩,如果有腰斩的就再接上 
    endstr = (/&[^&]*$/.exec(tstr) || '');
    if ( endstr !== '' ) endstr += '' + (/^[^;]*;/.exec(sstr) || '');
    if (/^(&\w{1,10};|&#\d+;)$/.test(endstr))
    {
        rtstr = tstr.replace(/&[^&]*$/, endstr);
    }
    else
    {
        rtstr = tstr;
    }
 
    //把html标签放回到截断完毕的字符串中,当然有的html标签这时候已经无家可归了
 
    var index = 0;
 
    for (var i = 0; i < rts.length; i ++)
    {
        index = indexs[i];
        if (rtstr.length >= index)
        {
            rtstr = rtstr.substr(0, index) + rts[i] + rtstr.substr(index, rtstr.length);
        } 
        else
        {
            break;
        }
    }
    var lastindex = i ;
    //下面的代码用来闭合没有闭合的标签
    tstr = rtstr;
    rstr = '';
 
    //把闭合的标签全部删除,sstr包含了没有闭合的标签
    while ( rstr != tstr )
    {
        rstr = tstr;
        tstr = tstr.replace(/<[^\/][^>]*>[^<]*<\/[^>]+>/g, '').replace(/<[^>]+ \/>/g, '');
    }
    sstr = tstr;
    //在剩余的部分查找没有闭合的标签
    tstr = str.replace(rtstr, '');
    rstr = '';
    while ( rstr != tstr )
    {
        rstr = tstr;
        tstr = tstr.replace(/<[^\/][^>]*>[^<]*<\/[^>]+>/g, '').replace(/<[^>]+ \/>/g, '');
    }
 
    reg.lastIndex = 0;
    var endreg = new RegExp('<\/[^>]+>', 'g');
    //如果存在没有闭合的标签,从无家可归的标签里找下半身
    while ( reg.exec(sstr) != null ) 
    {
        if ( (rt = endreg.exec(tstr)) != null)
        {
             rtstr += rt[0];
        }
        else
        {
             break;
        }
    }
 
    return rtstr;
}
</script>
<script>
document.writeln('<textarea cols="100" rows="10">');
document.writeln(sub_html_str('<xx><oo>嵌套标签截断测试</oo><fk><test>lala</test></fk></xx>', 5));
document.writeln(sub_html_str('正常字符串测试', 5));
document.writeln(sub_html_str('<xx>带标签的字符串截断</xx>', 5));
document.writeln(sub_html_str('<xx><oo>嵌套标签截断测试</oo><fk>lala</fk></xx>', 5));
document.writeln(sub_html_str('<xx><oo>嵌套标签<img src="http://www.google.com/logo.gif" />截断测试</oo></xx>', 5));
document.writeln(sub_html_str('<xx><oo>实体截断&nbsp;测试测试</oo></xx>', 5));
document.writeln('</textarea>');
</script>
 
</html>
Copy Code | Run Code

——————————————————–
最近各位弟兄都很忙的样子,俺则已经沦为做活动页面的了。。html字符的截断一般都会放到后台技术们做,但是春节的这个东西比较紧,偶就前端代劳一下。
运气不错,这么长的函数没调几次就过了。也是按照自己的思路来。。。
这个函数仅能做到

  • 截取除了html标签之外的前n个字符,一般的需求都是这样的。。
  • 不会截断html实体
  • 查找并闭合被截断的html标签,但是如果给的html就存在没有闭合的就不管了
<html>
<!-- html字符截断第一版 -->
<script>
function sub_html_str(str, num)
{
    var reg = new RegExp( '<[^>]+>' , 'g' );
    var rt, rts = [], indexs = [], tstr, endstr, rstr, endtag;
 
    //提取所有的html标签和标签在字符串中的位置 
    while ( ( rt = reg.exec(str) ) != null )
    {
        rts.push(rt[0]);
        indexs.push(rt['index']);
    }
 
    //删除字符串中所有的html标签
    str = str.replace(reg, '');
    //对剩余的纯字符串进行substr
    tstr = str.substr(0, num);
 
    //判断有没有把实体腰斩,如果有腰斩的就再接上 
    endstr = (/&[^&]*$/.exec(tstr) || '');
    if ( endstr !== '' ) endstr += '' + (/^[^;]*;/.exec(str.substr(num, str.length)) || '');
    if (/^(&\w{1,10};|&#\d+;)$/.test(endstr))
    {
        str = tstr.replace(/&[^&]*$/, endstr);
    }
    else
    {
        str = tstr;
    }
 
    //把html标签放回到截断完毕的字符串中,当然有的html标签这时候已经无家可归了
 
    var index = 0;
 
    for (var i = 0; i < rts.length; i ++)
    {
        index = indexs[i];
        if (str.length >= index)
        {
            str = str.substr(0, index) + rts[i] + str.substr(index, str.length);
        } 
        else
        {
            break;
        }
    }
    var lastindex = i ;
    //下面的代码用来闭合没有闭合的标签
    tstr = str;
    rstr = '';
 
    //把闭合的标签全部删除,tstr包含了没有闭合的标签
    while ( rstr != tstr )
    {
        rstr = tstr;
        tstr = tstr.replace(/<[^>]+>[^<]*<\/[^>]+>/g, '').replace(/<[^>]+ \/>/g, '');
    }
 
    reg.lastIndex = 0;
    //如果存在没有闭合的标签,从无家可归的标签里找下半身
    while ( reg.exec(rstr) != null ) 
    {
        while ( lastindex < rts.length )
        {
            endtag = rts[lastindex];
            //如果它是一个用来闭合的标签,就把它追加到字符串
            if ( /^<[ ]*\//.test(endtag) ) 
            {
                str = str + endtag;
                lastindex ++;
                break;
            }
            //如果它是自闭合的标签
            else if ( /<[^>]+ \/>/.test(endtag) )
            {
                lastindex ++;
            }
            //如果它是一个起始标签
            else
            {
                lastindex += 2;
            }
 
        }
    }
 
    return str;
}
</script>
<script>
document.writeln('<textarea cols="100" rows="10">');
document.writeln(sub_html_str('正常字符串测试', 5));
document.writeln(sub_html_str('<xx>带标签的字符串截断</xx>', 5));
document.writeln(sub_html_str('<xx><oo>嵌套标签截断测试</oo><fk>lala</fk></xx>', 5));
document.writeln(sub_html_str('<xx><oo>嵌套标签<img src="http://www.google.com/logo.gif" />截断测试</oo></xx>', 5));
document.writeln(sub_html_str('<xx><oo>实体截断&nbsp;测试测试</oo></xx>', 5));
document.writeln('</textarea>');
</script>
 
</html>
Copy Code | Run Code

wordpress的插件机制用于产品js代码的解耦

由于半路出家,设计模式几乎没有接触,一直为产品代码的耦合头疼,前两天忽然想到,wordpress区区数行代码便实现了强大的插件接口,何不借鉴一下呢,于是便有了下面的假想代码(不了解wordpress插件机制的同学可以先了解一下):

/*
* 以一个相册浏览的产品为例
* 该应用可以实现无刷新的图片浏览,附加功能:新用户引导,图片评论,对图片处理的第三方应用,圈人
*/
//产品引导开始
addAction('photo_browser_init',function()
{
     guideManager.init();
});
addAction('photo_load_sucess',function(photo)
{
    guideManager.step(3, photo);
});
addAction('photo_change',function(photo)
{
    guideManager.step(4);
});
//产品引导结束
 
//管理员ui开始
addAction('photo_browser_init',function()
{
    if ( !currentUser.isAdmin ) return;
    ......
});
//管理员ui结束
 
//相册圈人开始
addAction('photo_browser_init', function()
{
    photo_tag.init();
});
addAction('photo_load|photo_change', function(photo)
{
    photo_tag.update(photo);
});
//相册圈人结束
 
//相片app
addAction('photo_browser_init',function(photo)
{
    photo_apps.init(photo);
});
addAction('photo_load|photo_change',function(photo)
{
    photo_apps.update(photo);
});
//相片app结束
 
//相片评论开始
addAction('photo_browser_init',function(photo)
{
    photo_comment.init(photo);
});
addAction('photo_load|photo_change',function(photo)
{
    photo_comment.update(photo);
});
//相片评论结束
 
//相片浏览核心功能开始
var photo_browser = {...};
photo_browser.init();
//相片浏览核心功能结束
Copy Code 

其实跟自定义事件有点类似,但是比自定义事件更强大:

  • 自定义依赖于对象,对脚本的加载顺序会有要求,而wordpress里的addFilter和addAction可以完美解决这个缺点。
  • filter可以实现数据过滤,而自定义事件不能

经过解耦之后的产品更方便多人协作开发,代码块清晰,有效避免svn冲突,还有种种其他好处。。

仅仅是个想法,未经实践,实践ing~

javascript 1.7 的新特性

我愧对js工程师这个职位,竟然不知道firefox已经支持javascript 1.7了~

可能是受python的影响,偶然在firebug里输入类似下面代码

"abcdef"[1]

然后结果输出了”b”,当时没有在意,但是后来一想js好像没有这个特性,偶就觉得firefox的js引擎有点小牛了..

但是今天看的这个javascript 1.7新鲜事里好像没有提到这个特性,有点不解~

getAttribute(‘onclick’) in IE

第n次火星了,可是依然没去过火星.
这个是最近用到才知道,需求是替换onclick属性中的关键字,但是俺单纯的以为geAttribute都会返回一个字符串给我,没想到ie又一次显示了它独到的见解~

<html>
<p id="test" onclick="alert('click');">click me~</p>
<script>
document.write('<pre' + '>');
var el = document.getElementById('test');
var at = el.getAttribute('onclick');
document.writeln(at);
document.writeln(typeof at);
document.write('</' + 'pre>');
</script>
</html>
Copy Code | Run Code

ff下输出

alert('click');
string

ie6和ie7下输出:

function anonymous()
{
alert('click');
}
function

ie8下输出:

function onclick()
{
alert('click');
}
function

其他事件属性肯定也会有同样表现,ie8十分搞笑,换了一个函数名…

最后对于ie我只有这样了:

<html>
<p id="test" onclick="alert('click');">click me~</p>
<script>
var el = document.getElementById('test');
var at = el.getAttribute('onclick');
//函数换成字符串
at = at.toString().replace(/^function (anonymous|onclick)\(\)\n\{\n(.*)\n\}$/m, '$2');
//替换关键词
at = at.replace('click', 'wahaha');
//再变成函数放回去
el.setAttribute('onclick', new Function(at));
</script>
</html>
Copy Code | Run Code