Skip navigation.

exploreopera

| Help

Sign up | Help

极湖

无不用其“极”

Posts tagged with "JavaScript"

发布一个 jQuery 插件 —— ColorPicker

, ,

效果图(ScreenShot):


用法:
一.绑定到单个text输入框
$('#txt_color').colorPicker();


二.绑定到多个text输入框)
$('.color_fields').colorPicker();


三. 所选颜色值传递给回调函数(callback)
$.colorInput.toggleMenu($('#test_box'), function(sColor){
    alert(sColor);
});


下载(Download):
jquery.colorPicker.js

jQuery 判断 checkbox 是否被选中的几种方法

,

方法一:
if ($("#checkbox-id")get(0).checked) {
    // do something
}

方法二:
if($('#checkbox-id').is(':checked')) {
    // do something
}

方法三:
if ($('#checkbox-id').attr('checked')) {
    // do something
}

用土办法记忆可编辑 div 内的光标位置

, ,

可编辑 div 内光标位置的记忆和恢复实在是太难,情急之下想了个很土的办法:做一个不可见的 span 紧跟光标,在光标位置插入内容的时候只需找到这个 span 即可。

程序如下:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>(jQuery) Cursor Position Test </title>
<script type="text/javascript" src="jquery.pack.js"></script>
<style type="text/css" media="all">
#editor {
        width:500;
        height:100;
        margin:10px;
        padding:2px;
        border:1px solid #0000FF;
        overflow:auto;
}
#info {
        width:500;
        height:200;
        margin:10px;
        padding:2px;
        border:1px solid #00FF00;
        background-color:#F8F8F8;
        overflow:auto;
}
#caret_pos {
        display:none;
        cursor:default;
}
</style>
<script type="text/javascript">
    function trace(obj) {
        if(typeof(obj) == 'object') {
            for(var x in obj) {
                $('#info').append(x + '<br/>');
            }
        } else {
            $('#info').append(obj + '<br/>');
        }
    }
        
    $(document).ready(function(){
        var caretRange;
        //update Caret Pos
        function updateCaretPos(e) {
                caretRange = document.selection.createRange();
                if(caretRange.text != '') {
                        return;
                }
                var caretHtml = '<span id="caret_pos"></span>';
                if($('#caret_pos').length > 0) {
                        $('#caret_pos').remove();
                }
                caretRange = document.selection.createRange();
                caretRange.pasteHTML(caretHtml);
                caretRange.collapse(true);
        }

        //insert HTML at Caret Pos
        function insertAtCaret(sHtml) {
                $('#caret_pos').before(sHtml);
                var caret = document.getElementById('caret_pos');
                var txtRange = document.body.createTextRange();
                txtRange.moveToElementText(caret);
                txtRange.select();
        }
        $('#editor').keyup(function(e){
                updateCaretPos(e);
        }).click(function(e){
                updateCaretPos(e);
        }).focus(function(e){
                updateCaretPos(e);
        });
            
        $('#insert').click(function(e){
                insertAtCaret($('#instext').val());
        });
        $('#editor_html').click(function(e){
                $('#info').text($('#editor').html());
        });
        $('#clear_info').click(function(e){
                $('#info').html('');
        });
    });
</script>
</head>
<body>
        <div><h2>Caret Position Test</h2></div>
    <div id="editor" contentEditable="true">
        <span>start</span>
    </div>
    &nbsp;&nbsp;
    <input type="button" id="editor_html" value="Html in Editor" />
    &nbsp;&nbsp;
    <input type="text" id="instext" value="" />
    &nbsp;
    <input type="button" id="insert" value="Insert" />
    &nbsp;&nbsp;
    <div id="info">
    </div>
    &nbsp;&nbsp;
    <input type="button" id="clear_info" value="Clear Info" />
</body>
</html>

注:以上程序仅适用于IE。Mozilla系浏览器只需修改pasteHTML部分的代码

CodeMirror:浏览器内的高亮文本编辑器

, ,

因为要做编辑器,所以找了很多 OpenSource 的 WYSIIWYG 编辑器代码,当然都是 JavaScript。无意间发现一个好东西——CodeMirror,看了这个东西,我吃惊不少,因为它几乎已经达到了桌面程序的水平,写程序代码能够高亮彩显(目前支持 HTML 和 Javascript),还有自动缩进、匹配提示等功能,而且比较流畅。

看了一下 CodeMirror 的代码,觉得很不一般,称得上短小精悍,一看就知道作者的 JavaScript 功底相当深厚,称得上是大师级的水平。作者在他网站上还发布了一本 JavaScript 的教程——Eloquent JavaScript,我看也是个难得的东西,初学者或者是有经验的开发人员都可以参考。

用 JavaScript 写的类似编辑器还有


以上列表也是 CodeMirror 的作者介绍的,看看这些东西,也许您会和我一样惊叹:JavaScript 实在是神奇!

jQuery 鼠标位置测试

, ,

废话不多说,直接贴程序:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>jQuery Mouse Test</title>
<script type="text/javascript" src="jquery.pack.js"></script>
<style type="text/css" media="all">
    table.simple_grid {
        width:100%;
        height:100%;
        margin:0;padding:0;
        border:1px dashed #FF0000;
        border-collapse:collapse;
        border-spacing:0;
    }

    table.simple_grid td {
        border: 1px dashed #FF0000;
        text-align:center;
        vertical-align:middle;
    }
</style>
<script type="text/javascript">
    function getMousePosition(e){
        var x = 0, y = 0;
        var e = e || window.event;
        if (e.pageX || e.pageY) {
            x = e.pageX;
            y = e.pageY;
        } else if (e.clientX || e.clientY) {
            x = e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft;
            y = e.clientY + document.body.scrollTop  + document.documentElement.scrollTop;
        }
        return { 'x': x, 'y': y };
    }

    $(document).ready(function(){
        $('#mouse_test').mousemove(function(e){
            var o =  $(this).offset();
            var oX = o.left;
            var oY = o.top;
            $('#lblOriginXY').html(oX + ',' + oY);

            var cX = oX + $(this).width()/2;
            var cY = oY + $(this).height()/2;
            $('#lblCenterXY').html(cX + ',' + cY);

            pos = getMousePosition(e);
            var mouseX = pos.x;     //- this.offsetLeft;
            var mouseY = pos.y;     //- this.offsetTop;
            $('#lblMouseXY').html(mouseX + ',' + mouseY);

            if(mouseY < cY) {
                if(mouseX < cX) {
                    $('#lblInfo').html('左上').hide().fadeIn();
                } else {
                    $('#lblInfo').html('右上').hide().fadeIn();
                }
            } else {
                if(mouseX < cX) {
                    $('#lblInfo').html('左下').hide().fadeIn();
                } else {
                    $('#lblInfo').html('右下').hide().fadeIn();
                }
            }
        });
    });
</script>
</head>
<body>
    <div id="mouse_test">
        <table class="simple_grid">
            <tr height="50%">
                <td width="50%">Origin:<label id="lblOriginXY"></label></td>
                <td width="50%">Center:<label id="lblCenterXY"></label></td>
            </tr>
            <tr height="50%">
                <td width="50%">Mouse:<label id="lblMouseXY"></label></td>
                <td><label id="lblInfo"></label></td>
            </tr>
        </table>
    </div>
</body>
</html>

利用 ContentEditable 做 WYSIWYG 编辑器

, ,

接下来要做的项目,需要在网页中实现一个拖方式的 WYSIWYG 编辑器,找了很多开源的基于 JavaScript 的编辑器,都难以实现复杂的拖放功能,因为它们几乎都是清一色使用 iframe 的 DesignMode="on" 属性,而跨 frame 的拖放非常困难,在网上很难找到现成的例子。

后来发现除了 Firefox 的其他浏览器,几乎都支持 div 的 ContentEditable="true" 属性,而 Firefox 3 也将支持该属性,所以决定用 div 做编辑器。刚开始觉得不难,然而一开始做就遇到不少难点,最主要是:

  • 输入焦点的控制
  • 光标位置的控制
  • 选取区域的控制

这几个问题不解决,很难做出令人满意的编辑器。因此,正在努力解决以上问题。

jQuery plugin 改造:Select Box replacement

, ,

Select Box replacement 是一个用图片和text输入框代替select的Plugin,发现之后想用这个Plugin,试用过程中发现有不少问题,所以修改了一下代码。

由于改动比较多,就不一一细说了。

修改后的代码可以从这儿下载

通过浏览器自动安装 DRM 许可证的代码 (Windows Media Player)

, , ,

Windows 媒体播放器下的 DRM 的版权保护机制,用 JavaScript 控制 HTML 内嵌对象来实现。
为了对不同的文件安装不同的许可证,需要动态生成相应的代码,以下是我的一个土办法(Perl):
# 这儿是许可证
$licenseID = "......"; 

# 页面载入时的JavaScript代码
my $add_js = qq|
<script Language="JavaScript">
    function StoreLicense() {
        GetLicenseObj.StoreLicense('<LICENSERESPONSE>$licenseID</LICENSERESPONSE>');
    }

    try{
        window.addEventListener('load', StoreLicense, true);
    } catch(ex) {
        window.attachEvent('onload', StoreLicense);
    }
</script>
|;

# DRM对象的HTML代码
my $add_html = qq|
<object id="GetLicenseObj" classid="clsid:A9FC132B-096D-460B-B7D5-1DB0FAE0C062" name="GetLicenseObj" viewastext>
    <embed mayscript type="application/x-drm-x2" hidden="true">
    </embed>
</object>
|;

# 打开 HTML 文件,插入以上代码并送出
open(TMP, $html_path) or die "Can not open temp file: $html_path";
print "Content-type: text/html\n\n";
while(<TMP>) {
    
    if( /[\s\t]*<\/head/i ) {
        print $add_js;
    } elsif( /[\s\t]*<\/body/i ) {
        print $add_html;
    }
    print $_;
}

close(TMP);

以上方法,仅供参考,切勿照抄。

用 JSON “包装”函数的试验

,

JSON 是我最喜欢的数据格式,JSON 格式的数据可以包装哈希、数组、单独的数或字符串,问题是,能不能在JSON里面混入函数呢?带着这个问题,做了一个小试验,如下:

var JSONOBJ = {
  'a':1,
  'b':[1,2,3],
  'c':{'x':1,'y':2, 'z':[1,2]},
  'd':function(x){return x+this['a']}
};

alert(JSONOBJ['d'](3));

结果,弹出窗口显示:4

也就是说,用JSON也可以“包装”函数。

单循环赛程算法

, , ,

这儿看到题目,翻译如下:

任意偶数个队,进行单循环赛,须在最短日期之内举行完全部赛事,请作出日程表之一。
(补充:每个队每天只能举行一场比赛)

并非只有一解的情况也有。
如果有余力,请给出所有可能的答案。

这属于体育赛事日程安排的问题,在数学上,比较接近“柯克曼女生问题”。

例如,4个队的情况下

1-2 3-4
1-3 2-4
1-4 2-3

6个队的情况下

1-2 3-4 5-6
1-3 2-5 4-6
1-4 2-6 3-5
1-5 2-4 3-6
1-6 2-3 4-5

是其一解。

这个问题看起来简单,做起来却颇伤脑筋。
我在网上找了一个比较容易理解的算法,就是一个队不动,其它队组成一个“环”之后旋转,每转一次得到一天的赛程。

用 JavaScript 实现的程序如下:
/**
 * 旋转数组
 */
function rotateArray(aOld) {
    var iLast = aOld.length - 1;
    return [aOld[iLast]].concat(aOld.slice(0, iLast));
}

/**
 * 生成日程表
 */
function getLeageSchedule(aTeam) {
    var aResult = [];
    if(aTeam.length%2 != 0) {
        aTeam.push('');
    }
    var vFirst = aTeam[0];
    var aCycle = aTeam.slice(1);
    var iHalfLen = aTeam.length/2;
    for(var i=0; i<aCycle.length; i++) {
        var aLeft = [vFirst].concat(aCycle.slice(iHalfLen).reverse());
        var aRight = aCycle.slice(0, iHalfLen);
        var aGames = [];
        for(var j=0; j<aLeft.length; j++) {
            if(aLeft[j] != '' && aRight[j] != '') {
                aGames.push(aLeft[j] + '-' + aRight[j]);
            }
        }
        aResult.push(aGames);
        aCycle = rotateArray(aCycle);
    }
    return aResult;
}

//测试
var aTeam = [1,2,3,4,5,6];
var aSchedule = getLeageSchedule(aTeam);
for(var i=0; i<aSchedule.length; i++) {
    document.write(aSchedule[i].join('  ') + '
');
}

程序运行的结果如下:
1-2 6-3 5-4
1-6 5-2 4-3
1-5 4-6 3-2
1-4 3-5 2-6
1-3 2-4 6-5

这个算法可能不是太好,只不过比较简单,有一点自己的发挥就是还考虑了奇数队的情况。
问题后面有人用 Ruby 实现了这一算法,总共才8行,实在让人佩服。
July 2008
SMTWTFS
June 2008August 2008
12345
6789101112
13141516171819
20212223242526
2728293031