5

Is there way to create a content-editable div where users can't select/highlight content but can still input things? I want to create an interface where users are forced to delete and enter things key-by-key, without being able to make mass edits via highlighting.

I've looked into the various forms of the "user-select" property in CSS, which works for static content, but doesn't seem to work for content-editable elements/inputs.

Any ideas?

Thanks

Eugene
  • 1,377
  • 2
  • 18
  • 22
  • You need to use DOM for that kind of usage. I don't think CSS or HTML would simply do that. – MahanGM Sep 24 '13 at 17:24
  • 1
    why would you want to take away such a common and accessible feature? I'd curse, double-curse and then triple-curse a person who'd do such a thing to me, so just curious :D – Zathrus Writer Sep 24 '13 at 17:36
  • http://stackoverflow.com/questions/826782/css-rule-to-disable-text-selection-highlighting – Chad Sep 24 '13 at 17:42
  • Thanks for the comments guys. I'll look into lower level DOM control and a non-contenteditable model. I want viewers to be able to follow along when someone writes -mass highlight-deletes and cursor re-positions would be confusing to follow. Also, I want to promote stream-of-conscious writing so I'm trying to limit the amount of editing power writers have. I'll post back here when I figure it out. – Eugene Sep 24 '13 at 18:09
  • Don't forget these aren't idiot proof, anybody who wants to steal your text, can. Any webdev can disable your CSS/HTML/JS. They can also just VIEW SOURGE and copy'n'paste the text. – TravisO Sep 24 '13 at 19:36
  • @TravisO Looks like OP is not trying to prevent copying the content of the page, rather the case is to prevent too fast/large changes to a particular element. – Teemu Sep 24 '13 at 19:45

2 Answers2

1

If you can accept a textarea instead of a contenteditable div, you can do something like this:

window.onload = function () {
    var div = document.getElementById('div');
    if (div.attachEvent) {
        div.attachEvent('onselectstart', function (e) {
            e.returnValue = false;
            return false;
        });
        div.attachEvent('onpaste', function (e) {
            e.returnValue = false;
            return false;
        });
    } else {
        div.addEventListener('paste', function (e) {
            e.preventDefault();
        });
        div.addEventListener('select', function (e) {
            var start = this.selectionStart,
                end = this.selectionEnd;
            if (this.selectionDirection === 'forward') {
                this.setSelectionRange(end, end);
            } else {
                this.setSelectionRange(start, start);
            }
        });
    }
};

HTML:

<form>
    <textarea id="div"></textarea>
</form>

A live demo at jsFiddle.

Some observations on the code:

  • In many browsers onselect is fired only for input or textarea elements within a form. That is a reason for the different HTML from yours.
  • IE9 - 10 don't support selectionDirection, that's why IE's legacy event handling model is used also for these browsers.
  • If not IE, you still can replace a bunch of text by selecting it with mouse and hitting a key without releasing the mouse button. I suppose this could be prevented by detecting if the mouse button is down, and in that case preventing keyboard actions. This would be your homework ; ).
  • The code for IE works with contenteditable divs too.

EDIT

Looks like I've done your "homework" too.

Iago
  • 1,214
  • 1
  • 10
  • 19
Teemu
  • 22,918
  • 7
  • 53
  • 106
  • @user2529253 Any comments? – Teemu Oct 11 '13 at 04:11
  • If i select the text and don't unclick, but write something, the selectable text is still working and the text is changed. – Iago Sep 10 '14 at 03:52
  • @IagoMelanias You can't select any text when using the ["homework code"](http://jsfiddle.net/5xrqv/3/). – Teemu Sep 10 '14 at 04:05
  • 1
    Yep, now is working perfectly. I can't select using mouse, ctrl+a and double click on the text. Great. Thank you. – Iago Sep 10 '14 at 04:17
1

I know you want to disable mass deleting, but if others are wanting to not show a highlight color (which would be user-select: none for other elements), you can put the following in your css:

::selection { background: transparent }

This will make the selection look like user-select: none but it will still allow mass deleting. But it could make users think there is no selection, so they possibly won't mass delete.

Hope this works for you, but mainly towards others.

Cameron
  • 1,049
  • 12
  • 24