2

我正在为跨浏览器输入和文本区域选择 getter 和 setter 编写扩展。这就是我编写代码的方式:

HTMLInputElement.prototype.getSelectionRange = get_selection_range;
HTMLInputElement.prototype.setSelection = set_selection_range;
HTMLTextAreaElement.prototype.getSelectionRange = get_selection_range;
HTMLTextAreaElement.prototype.setSelection = set_selection_range;

get_selection_range 和 set_selection_range 是那些扩展函数。所以我只想更换

someInputElement.selectionStart = a;  // and whole lot of code due to browser
someInputElement.selectionEnd = b;    // compatibility

只需

someInputElement.setSelection(a, b);
someInputElement.setSelection({ start: a, end: b });
someOtherElement.setSelection(someInputElement.getSelection());

但后来我在 IE7 中遇到了一些困难。首先,IE7 不知道什么是 HTMLInputElement。

我不想扩展整个对象。好吧,那将是我要做的最后一件事,但我想逃避它。函数 get_selection_range 和 set_selection_range 没问题,不要问里面有什么,你已经看过几次了。

所以问题是:对于 IE7,JS 中的 HTMLInputElement 是否有任何合法替代?

UPD:我在没有扩展任何全局对象类型的情况下制作了自己的解决方案:

var SmartInputSelection = Base.extend({
    constructor: function (options) {
        this.node = options.node;
        this.CHARACTER = "character";
        this.END_TO_END = "EndToEnd";
        this.END_TO_START = "EndToStart";
    },
    setSelection: function (a, b) {
        if (b === undefined && typeof a == "number")
            b = a;
        else if (b === undefined) {
            b = a.end;
            a = a.start;
        }

        if (this.node.selectionStart !== undefined) {
            this.node.selectionStart = a;
            this.node.selectionEnd = b;
        } else {
            var textRange = this.node.createTextRange();
            textRange.collapse(true);
            textRange.moveStart(this.CHARACTER, a);
            textRange.moveEnd(this.CHARACTER, b - a);
            textRange.select();
        }
    },
    getSelection: function () {
        var start, end;
        if (this.node.selectionStart !== undefined) {
            start = this.node.selectionStart;
            end = this.node.selectionEnd;
        } else {
            var range = document.selection.createRange();
            if (range == null) {
                start = end = 0;
            }

            var textRange = this.node.createTextRange(),
            duplicate = textRange.duplicate();
            textRange.moveToBookmark(range.getBookmark());
            duplicate.setEndPoint(this.END_TO_END, textRange);
            end = duplicate.text.length;
            duplicate.setEndPoint(this.END_TO_START, textRange);
            start = duplicate.text.length;
        }

        return {
            start: start,
            end: end
        };
    }
});

所以现在我只需要声明如下内容:

function SelectSomeTextInsideInput (input /* input is some DOM element */) {
    var smartInputSelection = new SmartInputSelection({ node: input });
    smartInputSelection.setSelection(0);
    smartInputSelection.setSelection(2, 5);
    smartInputSelection.setSelection({ start: 2, end: 5 });
    smartInputSelection.getSelection(); // start: 2, end: 5
}
4

2 回答 2

0

您不应该依赖全局定义这些对象,因为您已经注意到在某些浏览器中它们不是。

于 2012-09-12T07:28:09.600 回答
0

不。我最近在与 IE9 作斗争,我通过切换到 HTML5 模式让它工作。
我猜 IE7 太旧了,无法以任何方式支持它。

不管怎样,试着把这句话放在页面顶部:

<!doctype HTML>

编辑:在这里查看这个答案:Element.prototype in IE7?

于 2012-09-12T07:04:16.660 回答