Scrolling textarea to specific area with javascript - javascript

I have a textarea with a scrollbar. I need to change the position of your cursor in the textarea with javascript AND scroll the textarea so your cursor is visible. I am using elem.selectionStart and elem.selectionEnd to move your cursor, but when I move it to a point that is not visible, the textarea does not scroll so the cursor is visible.
More details (probably TL;DR)
I am creating a slideshow editor and have a preview of the complete slideshow next to an editor (textarea with scrollbar) for the content. As you move your cursor through the textarea, the slideshow changes slides so you are always viewing the slide that you are editing. I need to get it so changing the slide (using buttons) moves your cursor so you can see the code that generated that slide.
// slideBoundries has numbers which are the indexes where the slides begin/end
// eg: [0, 81, 140, 250] for slideshow with 3 slides
if (doc.editor.selectionEnd > slideBoundries[curSlide] &&
doc.editor.selectionEnd < slideBoundries[curSlide + 1]) {
return;
}
doc.editor.selectionStart = slideBoundries[curSlide];
doc.editor.selectionEnd = slideBoundries[curSlide];
I could just count the number of newlines in the file so I know how far to scroll down, but there are many lines that are long and take up multiple lines. I am using a monospaced font so counting the number of newlines and lines that take up multiple lines, but I would like an easier way. Is there a function I could call to mimic what happens when the user moves their cursor as the textarea always scrolls to that point when the user clicks...
EDIT:
Due to popular demand, here is a fiddle: http://jsfiddle.net/tShQ2/
The method I'm going to use to fix this issue is create a phantom textarea that has same width, but autosizes to height. It has to be visible or else it won't work, so make it abs position and move it off screen. Then put the text before the desired cursor position in it. Then scroll the real textarea to the height of the phantom textarea.

Your solution is a good one, but let me suggest a couple of things to make it easier.
Use a phantom div, rather than a textarea, since a div will autosize automatically. Just make sure to match the styles.
To hide your phantom div use:
visibility: hidden;
position: absolute;
This has the same effect as display: none, while allowing the div to have a height.
One more thing. For IE, you can create a range from the selection and scroll to it explicitly:
document.selection.createRange().scrollIntoView();

Related

Google Charts: tooltips have wrong position when inside a scrolling container

I'm using Google Charts (the Timeline in particular) and I am facing a weird issue.
When the timeline is placed inside a container that can scroll vertically, the bars' tooltip's vertical position is wrong if the container is scrolled.
Basically, the more you scroll the more the tooltip "drifts down", I've taken some screenshot to illustrate this:
Here is the tooltip when the container is not scrolled, the position is correct:
Now, let's scroll a bit, the tooltip vertical position starts to drift:
...and the more we scroll, the more it drifts:
I've tried reproducing this in JSfiddle but with no success, unfortunately the original code is quite complex and difficult to replicate as a simple example, but any suggestion on how to even approach this is welcome.
Well, while waiting for answers I developed this workaround:
//This instruction selects the internal div that actually shows the scrollbar
//The div is generated automatically by the Google library when you put the Timeline inside
//an element (#maincontainer in our case) that has a fixed height too small to fit the entire timeline
//It unfortuantely has no classes to make a more specific selector
let scrollElem = $(`#maincontainer > div > div:nth-child(1) > div > div`);
//We then monitor mouse movement on the scrollable div
scrollElem.on('mousemove', function( event ) {
//When mouse moves, we determine how much the container is scrolled vertically
let scrollAmnt = scrollElem.scrollTop();
//then we update a CSS style tag that forces the tooltip to a specific position
//Y-axis position = level with mouse pointer (= mouse Y-position relative to scrolling container - scroll amount)
//X-axis position = just to the right of the mouse pointer
$('#tooltip-style').text(`.google-visualization-tooltip{
top: ${event.offsetY - scrollAmnt}px !important;
left: ${event.offsetX + 15}px !important;
}`);
});
maybe not the prettiest of solutions, but works great.
I'll leave the question open for a few days to see if someone has a more "proper" solution.

DOM not visually updating with iOS scroll?

This is an odd one.
Let's say I have some text in a container with -webkit-overflow-scrolling:touch applied to it, and a span element with a background color within the content but outside of the viewport.
If you then press a button to remove the span element and replace the contents with the text inside, and then scroll the container so that the span element that was once there is in the viewport, the background color is retained. The span element itself is gone, but the DOM is not visually updated.
jsFiddle (view it on iOS) - http://jsfiddle.net/charlescarver/rdZq4/4/
Now, there are two solutions that I have found that I do not like, but update the container visually:
Remove the -webkit-overflow-scrolling:touch
Add the following code to change an aspect of the CSS, then back:
This method uses .scroll():
$(".text").scroll(function () {
$(".text").css("color", "blue");
setTimeout(function () {
$(".text").css("color", "#000");
}, 1)
});
Problem with this, the residual background color is there until the scrolling stops, which still leaves the artifact.

divs, textareas, text and cursor detection

I have the following problems:
1.) I want to use a contenditable div or a textarea ( preferrably a contenteditable div because I can also use there html tags, not just text ), as a writing pad. However I want the writing to STOP once the cursor reaches the BOTTOM RIGHT corner of the div/textarea. This seems hard to implement. I have managed with max-height and overflow:hidden to make the element ( div / textarea ) to not expand, however the user can still type, it will just be invisible, something unwanted. What I want is the writing to stop when the cursor reaches the bottom right corner and then go on, on a new empty "page".
My first idea was to use some monospace font and calculate the max chars allowed but the issue is that 1st not all browsers show the same number of monospace characters of the same font, per line and 2nd the div can be variable in size, not constant.
The ideal would be a div so that i can enter html tags ( bold, italic, etc. ) and the div that shows the content can be of a different size, depending on the screen resolution.
2.) Given a div which represents a "page" which gets filled with a text/html from the database, how can I show only the content that fills the div, and when the user presses a "next page" button, show the next content. This seems undoable to me, figuring out via javascript how much content can fill into the div.
Any ideas on these two correlated problems would be greatly appreciated
No flash, no java, no plugins. only: html,css,javascript
Thanks in advance.
you can try the below code.
<div id="editable_div"></div>
var content_id = document.getElementById("editable_div");
max = 10;
//binding keyup/down events on the contenteditable div
$('#'+content_id).keyup(function(e){ check_charcount(content_id, max, e); });
$('#'+content_id).keydown(function(e){ check_charcount(content_id, max, e); });
function check_charcount(content_id, max, e)
{
if(e.which != 8 && $('#'+content_id).text().length > max)
{
// $('#'+content_id).text($('#'+content_id).text().substring(0, max));
e.preventDefault();
}
}

JQuery Slider/Carousel Calculation

Basically I have a bottom bar that stores a definitive amount of objects, say 30, with a width of say 2000em.
Now I want to make this div scrollable but every tutorial I look at does not explain their calculation.
My scroller will be unique because I will only allow scrolling via a next and back button (basically like paging) and I need to calculate when the div has 0 space to move so I can AJAX load more items and of course this calculation needs to be resize safe (based on div width and not pre-defined numbers).
Now I am fine with the whole resize (recalc div width on resize event) and AJAX load more objects.
What I'm not fine with is the calculation required to understand how the div should scroll and how to judge when it has no more space to scroll.
Has anyone got experience with making a dynamic scroller that only acts uopn click of a next or previous button that could explain the calculation required to understand scrollLeft/Right?
Thanks for any and all help,
I actually sorted this by:
Taking the current scrollLeft() of the inner ul within the div wrapper and add on the div (wrapper) width.
I checked whether the sum from point 1 was less than the UL width.
If so then scroll otherwise load new page if there is one.
Reverse for the previous button.
Since the wrapper has a width of 100% specified it will always be the size of the screen which means no resize function needed.

How do I stop a textarea from scrolling to the top whenever I change its value

I'm making something where a textarea gets more and more text appended. In firefox, the textarea scroll back up to the top each time.
I currently have something like textarea.scrollTop=1000000; to scroll it back down each time it changes, but it still goes up to the top for a very short time.
Is there any way to stop it doing so?
I ran into this problem, too. It happens in IE and Firefox but not Opera and Chrome.
I thought of hiding the momentary jumps to the top by "double-buffering" changes to the textarea:
Create two textareas with the exact same properties and dimensions. Only one of these is visible; the other one is hidden.
Append text to the hidden textarea: set [the value of the hidden textarea] to [the value of the visible textarea] + [text to append]. (The textarea will automatically scroll to the top, but this textarea is hidden!)
Scroll the hidden textarea to the bottom: set scrollTop to a high integer value like (-1 >>> 1).
Swap the hidden textarea with the visible one. Now the new text is shown, sans jumping to top!
You can swap the hidden/visible textareas by using one of two methods:
Use absolute positioning to place the textareas on top of each other in conjunction with toggling their visible property.
Swap the actual DOM elements. I'm not sure if this will introduce a new type of "flicker." You may have to create a div to contain the visible textarea so the layout of the page doesn't keep changing...
i thing that is problem of adding the content via the script, paste your code which append text to your textarea

Categories

Resources