HTML textarea에서 유사한 코드 편집기 쓰기 지원

4089 단어
var stopEvent = function (evt) {
    if (evt.preventDefault)
        evt.preventDefault();
    if (evt.returnValue)
        evt.returnValue = false;
    return false;
};

String.prototype.trim = function () {
    return this.replace(/(^\s*)|(\s*$)/g, '');
};

String.prototype.lastChar = function () {
    return this.charAt(this.length - 1);
};

String.prototype.fristChar = function () {
    return this.charAt(0);
};

String.prototype.toUnicode = function () {
    var temp,
        i = 0,
        r = '',
        len = this.length;

    for (; i < len; i++) {
        temp = this.charCodeAt(i).toString(16);
        while (temp.length < 4)
            temp = '0' + temp;

        r += '\\u' + temp;
    }
    return r;
};
String.prototype.countOf = function (reg) {
    if (undefined !== reg)
        return (this.match(reg) || []).length;
    return 0;
};

String.prototype.countOfTab = function () {
    var reg = /\u0020{4}/g;
    return (this.match(reg) || []).length;
};

String.prototype.countOfTabEnter = function () {
    var reg = /\u0020{4}\u000a/g;
    return (this.match(reg) || []).length;
};

String.prototype.countOfTabInCloseTag = function () {
    var reg = /\u007b\u000a*\u0020{4}\u000a*\u007d/g;
    return (this.match(reg) || []).length;
};


window.onkeydown = function (evt) {
    evt = evt || window.event;
    var keyCode = evt.keyCode,
        tab = 9,
        enter = 13;

    var target = evt.target,
        selectionStart = -1,
        selectionEnd = -1,
        tabKey = '\u0020\u0020\u0020\u0020',
        doubleTabKey = tabKey + tabKey,
        enterKey = '\u000a',
        value = '',
        prefix = '',
        suffix = '';
    if (target && target.tagName === 'TEXTAREA') {
        selectionStart = target.selectionStart;
        selectionEnd = target.selectionEnd;
        value = target.value;
        if (selectionStart < 0 || selectionEnd < 0) {
            return;
        } else {
            prefix = value.substring(0, selectionStart);
            suffix = value.substring(selectionEnd);
        }
    } else {
        return;
    }


    //tab
    if (keyCode === tab) {
        value = prefix + tabKey + suffix;

        selectionStart += 4;
        selectionEnd = selectionStart;
        target.value = value;
        target.setSelectionRange(selectionStart, selectionEnd);

        return stopEvent(evt);
    }

    //enter
    if (keyCode === enter) {
        //{}
        var frist = prefix.trim().lastChar(),
            last = suffix.trim().fristChar(),
            count = prefix.countOf(/\u000a/g);
        if (('\u003b' === frist || '\u0029' === frist || '\u007b' === frist) && '\u007d' === last) {
            if (count === 0) {
                value = prefix + enterKey + tabKey + enterKey + suffix;
                selectionStart += 5;
            } else if (count > 0) {
                var tabs = prefix.substring(prefix.lastIndexOf('\u000a'), selectionStart).countOfTab(), i = 0, tabStr = '';
                for (; i < tabs; ++i) {
                    tabStr += tabKey;
                }
                value = '';
                value += prefix;
                value += enterKey;
                value += tabStr;
                if ('\u003b' !== frist) {
                    value += tabKey;
                    ++tabs;
                }
                if (enterKey !== suffix.fristChar()) {
                    value += enterKey;
                    value += tabStr;
                }
                value += suffix;

                selectionStart += 1 + (tabs * 4);
            }
        } else {
            value = prefix + enterKey + suffix;
            ++selectionStart;
        }

        selectionEnd = selectionStart;
        target.value = value;
        target.setSelectionRange(selectionStart, selectionEnd);

        return stopEvent(evt);
    }

};

현재tab키와enter키만 지원되며, 후속적으로 스마트 매칭 기능이 추가됩니다.

좋은 웹페이지 즐겨찾기