2

I'm writing an extension for crossbrowser input&textarea selection getter and setter. So that's the way i write my code:

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 and set_selection_range are those extended functions. So i just wanted to replace

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

with just

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

But then i met couple of difficulties in IE7. First of all, IE7 doesnt know what is HTMLInputElement.

I don't want to extend whole Object. Well, that would be the last thing i'll do, but i want to evade it. Functions get_selection_range and set_selection_range are alright, don't ask what's within, you've seen it couple of times already.

So the question is: is there any legit substitution for HTMLInputElement in JS for IE7?

UPD: I've made my own solution without extending any global object types:

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
        };
    }
});

So now i just have to declare something like:

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
}
Vladislav Qulin
  • 1,872
  • 1
  • 17
  • 20

2 Answers2

0

No. I was recently fighting with IE9 and there I got it to work by switching to HTML5 mode.
I guess that IE7 is too old to support it in any way.

Anyway, try to put this statement to the top of the page:

<!doctype HTML>

EDIT: And check out this answer here: Element.prototype in IE7?

Community
  • 1
  • 1
Nippey
  • 4,708
  • 36
  • 44
0

You should not rely on these objects to be globally defined because you have already noticed that in some browsers they are not.

Konstantin Dinev
  • 34,219
  • 14
  • 75
  • 100