Is there a way for me to add an element at the caret position using the keydown event?

I encountered an issue where a function was not working properly, but strangely, setting a breakpoint in devtools made it work successfully. Why is this happening?

function insertHtmlAtCursor() {
  var range=window.getSelection().getRangeAt(0);
  var node = range.createContextualFragment("<div>this is not show</div>");
  range.insertNode(node);
}

However, when I changed the code to the following, it always ran correctly.

var node = document.createTextNode('this is ok.'); 

I am using Chrome on MacOS, and here is a demo of the issue:

editor.onkeydown=editinput;
function editinput(e) {
  if(e.isComposing||e.keyCode===229) {
    return;
  }
  if(e.keyCode==32) {//space
    var range=window.getSelection().getRangeAt(0);
    var node=range.createContextualFragment('ttttttttttt');
    range.insertNode(node);
  }
}
<div id="editor" contenteditable="true" class="knowleadge" tabIndex="1">
</div>

This demo shows that when I press space, it does not insert the fragment, but while debugging in Chrome, it does insert the fragment.

Thanks to @Dekel, I learned that replacing keydown with keyup might be a solution. However, since I need to handle tab as well, keyup cannot accurately capture the tab key. How can I address this in my code?

I discovered that using setTimeout can solve these issues, but I'm wondering if there are any other solutions. Here is the set timeout implementation:

if(e.keyCode==32) {//space
    setTimeout(dealpace,0);
    e.stopPropagation(); 
    e.preventDefault();  
}
function dealpace() {
    var range=window.getSelection().getRangeAt(0);
    var node=range.createContextualFragment('ttttttttttt');
    range.insertNode(node);
}

Thank you @Dekel, the key wasn't really settimeout, but rather e.preventDefault(); As @Dekel mentioned, keydown inserts the text, while keyup replaces the text with space. Therefore, we need to use e.preventDefault(); like so:

if(e.keyCode==32) {//space
    dealpace();
    e.stopPropagation(); 
    e.preventDefault();  
}
function dealpace() {
    var range=window.getSelection().getRangeAt(0);
    var node=range.createContextualFragment('ttttttttttt');
    range.insertNode(node);
} 

Answer №1

It appears that both methods are functioning correctly:

function addHtmlAtCursor1() {
  var selectionRange = window.getSelection().getRangeAt(0);
  var newNode = selectionRange.createContextualFragment("<div>this is not display</div>");
  selectionRange.insertNode(newNode);
}
function addHtmlAtCursor2() {
  var range = window.getSelection().getRangeAt(0);
  var textNode = document.createTextNode('this is ok.'); 
  range.insertNode(textNode);
}
.box {
  border: 1px solid black;
  background: #fefefe;
}
<div class="box">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum</div>

<button onClick="addHtmlAtCursor1()">Method 1</button>
<button onClick="addHtmlAtCursor2()">Method 2</button>

Have you double-checked your implementation?
Can you pinpoint the exact issue?

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

I am currently working on creating a shopping cart that includes a delete button for removing items with just a click

I am currently working on developing a shopping cart feature that includes a remove button to delete items when clicked. I have achieved this using the filter method. However, I am facing an issue where after deleting an item and then adding it back, the ...

The issue of for loops malfunctioning in JavaScript when using a variable declared in Node.js and passed to Jade

Currently, I am delving into the world of node.js and JADE but seem to be encountering a challenge when it comes to implementing a for loop within a JavaScript block in a jade file. My approach involves experimenting with a basic code where I pass an array ...

iPhone: Span clicking not functioning properly

When trying to access the second level of menu navigation by touching the arrow span, there seems to be an issue. When I tap on the arrow, it behaves as if I tapped on the page itself (e.g., Philosophie). The arrow has a CSS property of cursor:pointer; and ...

Guide to creating a ReactJS higher-order component using modern ES6 syntax

I´m attempting to create a ReactJS higher-order component using ES6 syntax. This is what I have so far: export const withContext = Component => class AppContextComponent extends React.Component { render() { return ( ...

I've noticed that the NextJs router appears to be significantly slower in comparison to React

I currently have a website that is built in both React Js and Next Js. The issue I am currently encountering is that the router in NextJs is noticeably slower compared to react-router-dom. It takes almost 2-3 seconds to change the route. To experience th ...

Issue with angular directive scope not binding correctly

Good day I'm relatively new to Angular and directives, but I'm facing an issue with the scope (in my specific case). I have defined the directive as follows: angular.module('ToolBarMod', ['ngAria']) .controller('ToolBar ...

What steps should be taken to modify it so that the user is prompted to input the time in minutes

I attempted to modify the user input in minutes by changing "remseconds" to remminutes and adjusting the calculations to "x 60", but unfortunately, nothing happened as expected. Instead of "remseconds," I tried using remminutes and multiplied it by 60, bu ...

Unusual Behavior Causing Error: 'RangeError: Invalid time value'

Currently, I am developing a straightforward timestamp API using Express. Essentially, when a user inputs a date in 'regular' format, the API displays a JSON object with both the Unix format and the normal format. Below is the pertinent section o ...

Extracting all usernames of members present in a specific voice channel and converting them into a string using Node.js on Discord

Hey everyone, I'm looking for a code snippet that will help me retrieve all the members from a specific voice channel by using its ID. I also need to extract and store the usernames of these members who are currently in that particular voice channel w ...

Bootstrap modal with sticky-top class displays abnormal margin and padding upon being shown

Whenever I launch a bootstrap modal, I notice unexpected side padding or margin appearing on certain HTML elements. For instance: Before displaying the modal: <div id="fixedMenu" class="d-none container-fluid menu sticky-top px-0" s ...

Trouble with adding an object to an array in AngularJS

I'm having trouble pushing an object to an array. I'm trying to push the comments object (values from forms) on submit click, into dish.comments in dishDetailController. The ng-controller="DishCommentController" is nested inside ng-controller="di ...

Utilizing IndexedDB for data storage

Hey there! I am currently working on storing three fields in an IndexedDB. When I view them in the browser, I see the names of each index - content, content2, and content3. However, only data is being saved into content3. Can you help me figure out why? B ...

Issue with Bootstrap Toast failing to display after Bootstrap Modal closure

I am currently working on an app for a company directory that will help the company manage its employees, departments, and locations. This app is designed to allow users to make changes to the database only after confirming their actions. The app successfu ...

What is the reason for the $watch function in AngularJS triggering console.log to output twice?

Here's the code snippet I've been working on: <!doctype html> <html lang="en-US" ng-app> <!--Head--> <head> <meta charset="UTF-8"> <title>Lesson 5 - ng-show & ng-hide</title> ...

Instruct Vue to scan through a directory full of images without altering the filenames of the images

I came up with a method to instruct Vue to search in a file and assign images to the corresponding number of cards. So far, it's working perfectly. However, I'm curious if there is a more efficient way to achieve this. The current drawback is th ...

Using recycled frame buffers in a threejs fragment shader

I'm currently working on a project to develop an app that emulates the effect of long exposure photography. The concept involves capturing the current frame from the webcam and overlaying it onto a canvas. As time progresses, the image will gradually ...

The JSON parser is still encountering issues with newlines, despite attempting to fix the problem by adding

I'm currently working on a messaging platform for a school project and facing challenges in ensuring database protection, defending against XSS attacks, and accommodating all characters, including newlines. Everything seems to be in place, except for ...

Error encountered while sending AJAX request with JSON data type

Is it possible to submit a Form using ajax with the jsontype? Suppose I have 5 fields in the form, where 4 of them are normal textboxes and one field contains JSON. When trying to send this data via ajax, an error is thrown. How can I resolve this issue? ...

What sets response.setHeader apart from response.writeHead?

When it comes to sending a JSON response from my Nodejs server in my application, I have discovered two different methods. However, I am unsure about the distinctions between them. The first method involves var json = JSON.stringify(result.rows); respons ...

Is there a way to make model.save() return a value?

I'm currently exploring node.js and attempting to store data in MongoDB using mongoose. My goal is to return false in case of an error during the save operation (for example, if a user with the same name already exists). The issue lies in the sequence ...