Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Disable cursor clicks without blocking highlighting

I am making a typewriter-like website (here) that uses a textarea and javascript (from button clicks) to add/remove from the textarea.

After following these 2 answers (1, 2) I am now using the default typing indicator to show text position.

To prevent users from clicking in other places in the textarea I added pointer-events:none to the textarea's css, however this also blocks highlighting part or all of the text to manually copy it.

This is the textarea

<textarea id="textarea" class="textarea" data-gramm_editor="false" data-gramm="false">
</textarea>

with this css

.textarea {
    pointer-events:none;
    font-size: 23px;
    width: 100%;
    height: 150px;
    padding: 12px 20px;
    box-sizing: border-box;
    border: 2px solid #ccc;
    border-radius: 4px;
    background-color: #f8f8f8;
    resize: none;
    }

Visual explanation: I want to be able to select like this without being able to click around and do this this.

Is there a way to separate the click and highlighting and only block the clicks?

If a solution won't work smoothly on mobile devices that's still ok just indicate/explain.

like image 914
Ali Avatar asked Jul 26 '26 11:07

Ali


1 Answers

Ok I edited my previous answer:

If I understand correctly you want to keep highlight (select text) but do not let user to move cursor on the textarea. If that is the case, then you can do something like this. First let's remove

pointer-events:none;

Then add readonly on the textarea

example:

<textarea readonly id="textarea" class="textarea" data-gramm_editor="false" data-gramm="false">
</textarea>

Note: Generally avoid using pointer-events: none it will disable highlight and select and also cursor style.

Now in your case (having active select, having cursor active, do not let user move cursor in textarea), you can do something similar to this, you can use a div instead of textarea and edit inneHTML of that div. As you can see, I created a cursor which is html element and it is similar to a real cursor. By doing this, you have more control on your keyboard, I hope it can help. Generally it is not possible to achieve all you want with textarea only.

const editable = document.getElementById('editableC');

addCursor()

const buttons = document.querySelectorAll('button');

buttons.forEach(el =>
  el.addEventListener('click', event => {
    removeCursor();
    const letter = event.target.innerHTML;
    if (letter === 'clear') {
      editable.innerHTML = editable.innerHTML.slice(0, -1);
    }else {
      editable.innerHTML += letter;
    }
    addCursor()
  })
);


function addCursor(){
  let span = document.createElement('span');
  span.classList.add('blinking-cursor');
  let text = document.createTextNode('|');
  span.appendChild(text);
  editable.appendChild(span);
}

function removeCursor(){
  const span = editable.querySelector('span')
  span.remove()

}
.editableC {
  width: 300px;
  height: 100px;
  border: 1px solid #ccc;
  padding: 5px;
  word-break: break-all;
  
}

.blinking-cursor {
    user-select: none;
        -moz-user-select: none;
        -khtml-user-select: none;
        -webkit-user-select: none;
        -o-user-select: none;
  font-size: 18px;
  margin-left: 2px;
  color:red;
  -webkit-animation: 1s blink step-end infinite;
  -moz-animation: 1s blink step-end infinite;
  -ms-animation: 1s blink step-end infinite;
  -o-animation: 1s blink step-end infinite;
  animation: 1s blink step-end infinite;
}

@keyframes "blink" {
  from,
  to {
    color: transparent;
  }
  50% {
    color: red;
  }
}

@-moz-keyframes blink {
  from,
  to {
    color: transparent;
  }
  50% {
    color: red;
  }
}

@-webkit-keyframes "blink" {
  from,
  to {
    color: transparent;
  }
  50% {
    color: red;
  }
}

@-ms-keyframes "blink" {
  from,
  to {
    color: transparent;
  }
  50% {
    color: red;
  }
}

@-o-keyframes "blink" {
  from,
  to {
    color: transparent;
  }
  50% {
    color: red;
  }
}
<div id="editableC" class="editableC"></div>

<div style="margin-top:10px">
  <button>A</button>
  <button>B</button>
  <button>clear</button>
</div>
like image 125
Yasin Farmani Avatar answered Jul 29 '26 00:07

Yasin Farmani



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!