Is it possible to get the positions of cursor of writing (absolute x,y pixels positions of the last character) inside the input textarea
Note: its not just count number of characters, but I have to deal with new lines, for example, if the user type the Enter key (I have to detect the new position in pixels of the last character
I want this because i need to display a popup with suggestions while users type texts
if you have an example in reactjs or in classic javascript (not jquery) please share with your code
i hope that my question was clear.
Thank you in advance
Finally i found a solution:
here the code for reactjs
var text = this.refs.areatext,
coords = {};
var carPos = text.selectionEnd,
div = document.createElement("div"),
span = document.createElement("span"),
copyStyle = getComputedStyle(text);
[].forEach.call(copyStyle, function(prop){
div.style[prop] = copyStyle[prop];
});
div.style.position = "absolute";
document.body.appendChild(div);
div.textContent = text.value.substr(0, carPos);
span.textContent = text.value.substr(carPos) || ".";
div.appendChild(span);
coords = {
"TOP": span.offsetTop,
"LEFT": span.offsetLeft
};
document.body.removeChild(div);
this.setState({x:coords.LEFT,y:coords.TOP})
for javascript
(function() {
var text = document.querySelector(‘textarea’),
indicator = document.querySelector(‘.indicator’),
getCoord = function(e) {
var carPos = text.selectionEnd,
div = document.createElement(‘div’),
span = document.createElement(‘span’),
copyStyle = getComputedStyle(text),
coords = {};
[].forEach.call(copyStyle, function(prop){
div.style[prop] = copyStyle[prop];
});
div.style.position = ‘absolute’;
document.body.appendChild(div);
div.textContent = text.value.substr(0, carPos);
span.textContent = text.value.substr(carPos) || ‘.’;
div.appendChild(span);
coords = {
‘TOP’: span.offsetTop,
‘LEFT’: span.offsetLeft
};
console.log(coords);
indicator.style.left = coords.LEFT + ‘px’;
indicator.style.top = coords.TOP + ‘px’;
document.body.removeChild(div);
};
text.addEventListener(‘input’, getCoord);
}());
Please check this code, i have made cursor detection in javascript, hope will help you.
window.onload = init;
function init() {
if (window.Event) {
document.captureEvents(Event.MOUSEMOVE);
}
document.onmousemove = getCursorXY;
}
function getCursorXY(e) {
document.getElementById('cursorX').value = (window.Event) ? e.pageX : event.clientX + (document.documentElement.scrollLeft ? document.documentElement.scrollLeft : document.body.scrollLeft);
document.getElementById('cursorY').value = (window.Event) ? e.pageY : event.clientY + (document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop);
}
<html>
<body>
<input type="text" id="cursorX" size="3"> X-position of the mouse cursor
<br /><br />
<input type="text" id="cursorY" size="3"> Y-position of the mouse cursor
</body>
</html>
Related
My cursor is here(red flash), I need to detect its position, and locate the beginning "{{?" and the ending"{{?}}" of this expression.
First, how can I find my cursor location?
To get the caret position inside an input field you could use this:
HTML
<input type="text" id="input">
JS
function getCaretPosition(input) {
var position = 0;
if (document.selection) { //FOR IE...
var selrange = document.selection.createRange();
selrange.moveStart('character', -input.value.length);
position = selrange.text.length;
} else if (typeof input.selectionStart !== 'undefined') { //OTHERS
position = input.selectionStart;
}
return position;
}
You can call it like this:
var position = getCaretPosition(document.getElementById('input'));
This can be done by using range on editable content.
Example:
HTML:
<p contenteditable="true">This<!--cursor--> is an editable paragraph.</p>
Code:
selection = document.getSelection();
range = selection.getRangeAt(0);
startPosition = range.startOffset;
output: 4
<input type="text" id="Javascript_example" value="{{? ...}}1{{??}}22{{?}}" onclick="getposition()">
<script>
function getposition(){
var ptr = document.getElementById('Javascript_example');
alert(ptr);
var startPosition = ptr.selectionStart;
alert(startPosition);
var endPosition = ptr.selectionEnd;
alert(endPosition);
}
</script>
function foo(event) {
var x = event.clientX; // Get the horizontal coordinate
var y = event.clientY; // Get the vertical coordinate
var test = "X coords: " + x + ", Y coords: " + y;
document.querySelector('.test').innerHTML = test;
}
document.addEventListener('mousemove',foo);
.test {
width: 100%;
height: 100%;
background: #ccc;
}
<div class="test"></div>
This is how you can do this.
Here is the example made by experts :) >> 0o0o0o0o0o0o0
I'm attempting to combine a JavaScript mechanism for auto placing the users cursor inside of an input box through the mouseover and mousemove listeners.
I have an almost perfect working example here: http://codepen.io/anon/pen/doxNLm?editors=101
var current_element = document.getElementById("hover");
current_element.onmousemove = function showCoords(evt) {
var form = document.forms.form_coords;
var parent_id = this.id;
form.parentId.value = parent_id;
form.pageXCoords.value = evt.pageX;
form.pageYCoords.value = evt.pageY;
form.layerXCoords.value = evt.layerX;
form.layerYCoords.value = evt.layerY;
function getTextWidth(text, font) {
// re-use canvas object for better performance
var canvas = getTextWidth.canvas || (getTextWidth.canvas = document.createElement("canvas"));
var context = canvas.getContext("2d");
context.font = font;
var metrics = context.measureText(text);
return metrics.width;
};
var element_base_browser_styles = window.getDefaultComputedStyle(current_element);
var total_text_pixal_length = getTextWidth(current_element.value, element_base_browser_styles.fontFamily + " " + element_base_browser_styles.fontSize);
var add_char_pixal_lengths = 0;
var myStringArray = current_element.value.split('');
var arrayLength = myStringArray.length;
for (var i = 0; i <= arrayLength; i++) {
var get_char_value = getTextWidth(myStringArray[i], element_base_browser_styles.fontFamily + " " + element_base_browser_styles.fontSize);
add_char_pixal_lengths = add_char_pixal_lengths + (get_char_value) + 1.311111111111; //every char value is added together.
// console.log("Total: " + x);
if ((add_char_pixal_lengths)> (evt.layerX)) {
this.setSelectionRange(i, i);
add_char_pixal_lengths = 0;
break;
}
}
}
current_element.onmouseover = function() {
this.focus()
}
The problem I'm having is like Geosynchronous orbit; the cursor shifts out of place sometimes a few pixels (left or right). My calculation probably sucks, but I'm not sure canvas is really the best way to do the measurement? Is there a better way?
mousemove listener to receive element cursor coordinates from e.pageX
font style using window.getComputedStyles(input_element)
arr.split('') from input_element.text string: x = ['a','b','c']
'for loop' the array, generate a canvas and measure each characters width
add all char widths one by one until the value is greater than e.pageX
set the 'for loop' iterate as the setSelectionRange(i, i)
Any help or suggestions on making this better would be appreciated. Thanks!
How to use parameter variable "id" from "BubbleGum.prototype.ToolBar = function(id)" through a function "checkmousepos(e,id)" body scope ?.
I've tried to use inline method onClick , traditional method element.onClick = dosomething(); and W3C Standard and microsoft method element.addEventListener with same problem happening which is variable id = undefined.
Can someone please for the love of universe vibrations provide me with a concise and simplistic answer not some tricky hack semi-trash.
BubbleGum.prototype.ToolBar = function(id) {
var TB = document.getElementById(id);
TB.style.position = "relative";
TB.style.marginLeft = (RootFrame.style.marginLeft);
TB.style.marginTop = "-22.0em";
TB.style.left = "0em";
TB.style.top = 0;
TB.style.height = "2em";
TB.style.width = (RootFrame.style.width);
TB.style.color = "black";
TB.style.backgroundColor = "#6a071a";
TB.style.borderTopLeftRadius = "0.4em";
TB.style.borderTopRightRadius = "0.4em";
TB.style.textAlign = "center";
TB.onclick = checkmousepos(id);
function checkmousepos(e, id) {
document.write(id);
//var TB = document.getElementById(id);
var mousex = e.pageX;
var mousey = e.pageY;
id.style.marginLeft = mousex + "px";
//TB.addEventListener("mousemove",dick,false);
//document.write("jello");
};
};
this points to element that has onclick attached. Passing this you have access to that element in the elper method checkmousepos
TB already points to selected element – why you don't use it?
function BubbleGum() {}
BubbleGum.prototype.ToolBar = function(id) {
var TB = document.getElementById(id);
TB.style.color = "green";
TB.onclick = function(e) {
checkmousepos(e, this)
}
function checkmousepos(e, id) {
console.log('arg', arguments)
var mousex = e.pageX;
var mousey = e.pageY;
id.style.marginLeft = mousex + "px";
};
}
var s = new BubbleGum().ToolBar('toolbar');
<div id="toolbar">
some content
</div>
You have to assign the callback as onclick handler, while in your code you calling the checkmousepose function and assigning the return value which is undefined as nothing is returned.
So you have to return a function which will be assigned as a onclick handler like this
function checkmousepos(id) {
return function(e){
document.write(id);
//var TB = document.getElementById(id);
var mousex = e.pageX;
var mousey = e.pageY;
id.style.marginLeft = mousex + "px";
//TB.addEventListener("mousemove",dick,false);
//document.write("jello");
}
};
id is already in BubbleGum.prototype.ToolBar closure context, so it is availble checkmousepos function, just use it.
If I created a virtual grid 32x32 as a <div> example:
I want to fill one of the tile with a black box on click I have so far this:
var _proto = {
id:0,
x:0,
y:0
}
var objects = [];
$(".test").on("mousedown", function(e) {
var offset = $(this).offset();
var prex2 = 0, prey2 = 0;
prex2 = _proto.x = e.pageX-offset.left;
prey2 = _proto.y = e.pageY-offset.top;
_proto.id = (_objects.length)?_objects[_objects.length-1].id+1:0;
// Add to grid (not sure how to get proper cordinates)
$("<div style='display:absolute;width:32px;height:32px;background:black'></div>")
.css("top","")
.css("left","")
.appendTo("#maindiv");
});
I have the coordinates as prex2, and prey2 where the user clicked, but how do I know where to put it in the grid? I'm sure there a simple math equation but I can't figure it out.
Here's a snippet from a map editor that I was working on a few months back. It might help you grapple with your own code.
mapBlanket.addEventListener("mousedown", function(e) {
var sideWidth = document.getElementById("mapSide").offsetWidth;
var headHeight = document.getElementById("system").offsetHeight + 32;
var clickX = e.pageX - mapBlanket.offsetLeft - sideWidth + mapBlanket.parentNode.scrollLeft;
var clickY = e.pageY - mapBlanket.offsetTop - headHeight + mapBlanket.parentNode.scrollTop;
var tileX = clickX - (clickX % map.grid);
var tileY = clickY - (clickY % map.grid);
if (paintOn == 5) {
eventThis(tileX, tileY);
} else if (paintOn < 5) {
paintThis(tileX, tileY);
}
...
}
For reference, the map.grid was 32, same as yours. I just had a good bit defined in an object at the top of the file.
I am working on a project where we can move an image like in google map,, it works perfectly in crome,ff and above ie9, but when i checked in ie8 the image is not moving smoothly,it takes a 2 to 3 sec of time to move.
/* Map dragging */
var previousX;
var previousY;
var previousLeft;
var previousTop;
var cids = self.data.cuLocation;
var lumids = self.data.lumLocation;
$('#MapView img').css( 'cursor', 'pointer' );
$("#MapView img").mousedown(function(e) {
//console.log("mousedown");
e.preventDefault();
drag.state = true;
previousX = e.originalEvent.clientX;
previousY = e.originalEvent.clientY;
previousLeft = $("#MapView img").position().left;
previousTop = $("#MapView img").position().top;
});
$("#MapView img").mousemove(function(e) {
var old_pos = self.getPosition();
if (drag.state) {
e.preventDefault();
drag.x = e.originalEvent.clientX - previousX;
drag.y = e.originalEvent.clientY - previousY;
var cur_position = $("#MapView img").position();
var new_left = cur_position.left + drag.x;
var new_top = cur_position.top + drag.y;
previousX = e.originalEvent.clientX;
previousY = e.originalEvent.clientY;
}
});
$("#MapView img").mouseleave(function(e) {
//console.log("mouseleave");
drag.state = false;
});
$(document).mouseup(function(e) {
// alert("mouseup");
drag.state = false;
});
Use the following Link for your better understanding in Draggable event so than you can use it to Drag your Image wherever you want.
http://jqueryui.com/draggable/
and for Drap & Drop of one element onto other element ::
http://jqueryui.com/draggable/#snap-to