If I have a string in a div
<div id="article">
lots of text goes here
<strong> it's really interesting</strong>
and it's free to read
</div>
if a user double click or single click on a particular word, is there a way to determine the position/index of the character clicked?
If that cannot be done, how about determining how many space character there are before the clicked position. So if I click on the word 'goes' in the above example, it returns 3 because there are three spaces before the word goes which is clicked.
Thank You very much for your time.
The ugly hack solution to such a problem involves programming converting the characters into event capturing objects.
For instance
<div id="article">
<span>lots </span><span>of </span><span>text</span>...
</div>
Now this can be done programmatically.
You can grab whatever the current content of a div and convert it to something like the formatting above. Then attach event handlers to the contained spans which count the number of spans preceding it in the same container.
a way to determine the position/index of the character clicked
Well, first I need to use a fixed width size font like Courier.
Then, I'd create two span with only a char each. With those two, I should be able to know the width of a char (beware padding and margin) and its height.
Then, you need to know your upper left coordinates for your div whose id is 'article' and capture click event with event.x and event.y.
After that,
var line = (event.x - divLeft) / charHeight;
var column = (event.y - divTop) / charWidth;
Related
After a lot of research, I haven't found a post with exactly the same requirements so I thought write a new post.
I'm trying to create a fixed area (e.g. 200px by 300px) where the user can enter text input. He should be able to enter any character (including line breaks).
However, he should not be able to 'write outside the box' (i.e. there shouldn't be overflow scroll or hidden for the 200x300 area).
Once user reaches the 'bottom' of the area, they can't enter any more line breaks.
And once they reach the 'bottom right' corner of the 200x300 area, they shouldn't be able to enter any more characters at all.
Is this possible in css, angular, js, jquery, etc?
Limit the length of characters with base in font and div's size, but you must change the font size and family or line height because every browser can have different styles.
To limit the length of characters in the div is need to ignore the HTML tags in the content, like interpreting.
Firstly calculate how many characters fits there.
You can restrict the number of characters per line with the cols="" attribute and set the displayed the number of editable lines with the rows="" attribute. However limiting the number of rows could only be one with the maxlength attribute which would control the number of characters you can have, which you'd have to estimate. There are some hacks to limit the number of rows with event listeners, but they seem to have fairly major bugs.
It is possible, you just need to do following:
Use event handlers to control character input process. It is required to be able to stop processing further keystrokes when limit is reached. Use keypress and keydown, first handles character processing, second - control keys processing.
Each time user presses a key, use a separate buffer to produce final result, compute its bounding rectangle, and if it is bigger than limit, prevent event handling.
Height of text body could be calculated by multiplying number of lines by line height (interpret font-size and line-height CSS properties).
Width of text body could be computed rather easy with help of HTML5 canvas measureText method.
If you don't have canvas, you can use offscreen span (or any other inline) element - just fill innerHTML with text block and use its offsetWidth attribute. Actually, if you replace line break characters with <br>, you may use span approach to get both dimensions in one go - just make sure it has same style as editable container.
ContentEditable containers, as i remember, store text body in HTML format already (in other words - with <br>s instead of line break characters).
I have an UIWebView with a huge book in it. I'm changing it's font size via javascript, using "document.getElementsByTagName('body')[0].style.webkitTextSizeAdjust='150%';
Html-page gets larger, but the scroll position remains the same, causing text to shift out of a users sight.
The only idea that I have, is really weird and inefficient:
Wrap every word in <span> tags;
find the first onscreen <span> and remember it's id;
resize font;
scroll to span, that I've found in step 2.
Is there a better way to preserve the position, that user was reading?
Finally I've found an acceptable way:
Before changing font size I use a little javascript to find and store a position of a first letter on a page:
var range = document.caretRangeFromPoint(0,0); // get a range of a first onscreen letter
var textContainer = range.startContainer.parentNode;// get an element to which it belongs
var path = getElementXPath(textContainer); // get an XPath for that element (this function is not biult in, but you can find it in some other question)
path+='|'+range.startOffset; // stick XPath and index of the letter together
After that I change the font size, find needed element by XPath, insert invisible <a> right before my letter, scroll to that invisible <a>, don't forget to remove it.
Done. That is not a stragihtforward idea, but at least it works and does not consume to much of CPU or RAM, like the idea that I'have explained in original question.
Here is the place to get getElementXPath() function
I am trying to have a text-input field that is only wide enough to handle one character.
But when the one character is typed, it grows to the left and to the right so now it can hold 2 characters.
Then, when the second character is typed grows again so that it can hold 3 characters.
This goes on and on as long as the user types in input.
How can this be done in javascript / jQuery ?
This is a good question but no easy way to do it really first you need a max-width setting in the css of your text input,
after witch you can use some jQuery like so
$("#input_id").keyup(function(){
$("body").append("<div id=\"remove_me\">"+$(this).val()+"</div>");
var width = $("#remove_me").width()+30;
$(this).animate({"width":width});
$("#remove_me").remove();
});
Let's say I have a very long paragraph. When I click on a line, JS/jQuery will add an empty <span> tag at the beginning of this specific line - right before the first word in this line.
f.e: This is my paragraph:
<p>
It is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout. The point of using Lorem Ipsum is that it has.
</p>
When I click the second line, a <span> tag will be insert before the first word in the second line.
Any ideas how to do it?
jQuery can't detect where a wrapped line occurs, unless it happens with a hard-coded break (<br /> or similar).
That said, there is one option, although it's a little hacky.
Duplicate the container
Give it a left of -3000 (to make it invisible, without using display:none because that gives it 0 height)
Remove one word at a time (using .lastIndexOf(' ')), and measure the height each time. When it resizes to the smallest non-zero height, that's where you want to insert your <span>, so then...
.substring() with the position you've just found - .substring(0, position) + '<span>' + .substring(position)
Hello Friend You can find the possible duplicate here in the following link
Get caret position in contentEditable div
Hope this solves your problem.
I have a long series of paragraphs and I'd like to trim each down to 2 lines (50 characters) and when you click a link "more" it will show the full paragraph.
I am using the prototype library and rails.
I'd ideally like to do this with out breaking the paragraph into 2 divs and showing the other when you click on more. Or is that the only way?
Put your text in a div and set the height to your desired height (with overflow: hidden). When the more link is clicked set the div height to div.scrollHeight . If you're using jquery or mootools you can throw in a neat transition.
<div id="myText" style="overflow:hidden; height:50px;">Text here...</div>
more
<script type="text/javascript">
function showMore() {
var mydiv = document.getElementById('myText');
mydiv.style.height = mydiv.scrollHeight;
}
// or with a transition (mootools)
function showMoreTransition() {
new Fx.Tween($('myText'), {
duration: 1000
}).start('height', $('myText').getScrollHeight());
}
</script>
Do you have a problem with spans? It seems the most effective way set this up is to wrap the excess in a hidden span tag. You can even wrap the whole operationin a nice helper method to make it reusable.
Assuming prototype:
def sample_with_more(body, html_options = {})
more_link = link_to_function(" More...", "$('more').hide(); $('hidden').show();', :id => 'more')
content_tag(:div, html_options) do
body[0..49] + more_link +
content_tag(:span, body[50..-1], :style => "display:none", :id => "hidden")
end
end
Because I'm a jQuery guy, here is some psuedo code
Select element which contains p
Select after first 50 chars and wrap a div around with a class 'more-text'
Insert with Js after a <button>more</button>
Add a click event button that sets display: block or something more fancy on the more-text
Remove button or change it's text to 'less' and change necessary code
The above answers assume that you send the full text to the browser, then let it only display a certain amount of it by clipping it vertically. This is actually a good idea, as truncating a text afer a certain amount of characters is actually not as straight-forward as it seems.
In an early project, I had a long list of truncated texts and didn't want to send them all to the browser in full length. The important thing to keep in mind here is if your text may contain control or escape characters (e.g. HTML, BBCode, HTML-Entities, etc) you need to take special care about them.
I ended up writing a small HTML-tag parser to not deliver HTML tags which were cut in half, and to add end-tags to e.g. bold, italic, etc, to not screw up the rest of the screen layout.
Additionally, it's usually not what you want - i.e. you won't get two lines worth of text for different screen widths or when having line break characters in your text.