I have a string that I want to display on a web page that is dynamically passed in. I want to be able to dynamically determine the css width needed to display this string and then wrap it in an html element with the exact size needed to display it.
I am currently using javascript and dojo, so answers using those two are fine, but anything else won't work.
More Detail
I guess I should clarify. I want to display the string in an input field, so not as simple as a div (I think at least)
If you're wanting to set the <input> length to show all characters in the string, you can set it like so:
var myString = "abcdefg"; // this is what got input dynamically
var myInputElement = document.getElementById('someInput');
myInputElement.size = myString.length;
Since usually a good measure of characters are by em.
You can do this;
var element = Document.getElementById("ID");
element.style.length = element.value.length + " em";
You have to remember that before calculating the string's pixel width with regards to it's character count you have to somehow be aware of the metrics on the font used.
If then, you were to take the input string, wrap it in a <span>, embed it in the document, calculate the element's width, then remove the span and add the value to it's final destination you'd have a pretty decent projection of the intended width as long as your span has the same font style rules as the destination element.
If you want to get really fancy and technical about it, then the HTML 5 <canvas> tag is your friend.
A good article to better understand the complexity of font metrics in javascript which will also help you solve this: http://mudcu.be/journal/2011/01/html5-typographic-metrics/#measure
you can create an element and put some callback in it's load event
var span = $("<span/>").text("your input").load(function(e){
console.log($(this).width());
});
this way you can get the current width. don't define any width for the span element and don't float.
Related
Given a div that contains a lot of text that may or may not wrap, I'm looking for the x position of the end of the text in said div. This is user generated text so I don't know what's going to be in it, and also, it needs to be XSS safe, so I cannot use <span> elements in my code because a user could write some script that could execute.
The solutions given here are great, but would allow for unsafe scripts to potentially execute in the browser.
find out length of last incomplete line of text in container
Ideally, I would have a method with a signature something like this:
int getPixelsFromLeftMostSideOfDiv(Element e)
this should be XSS safe assuming that the way you put the user text on the screen is XSS safe.
It follows your linked solution's method of appending a span to the div and getting the x position of that span. Ie
var text = document.getElementById('text');
var span = document.createElement('span');
text.appendChild(span);
console.log(span.getBoundingClientRect().left);
JSFiddle attached for you to play with
https://jsfiddle.net/1d29c24d/1/
I have an element 123456789.
Can I show the number as stars even though the actual number is preserved? The number can be changed with javascript, so it wont help to use
$('.masked_text').text('*************');
I don't know if it is possible to show something without changing the content. I don't want an image placed above the element or something like that, so I'm really out of guesses :-)
You could set in CSS class font to symbols. That way text would become unreadable, unfortunately numbers would remain.
.maskedText {
font-family: Symbol;
}
Just save the number in a variable and replace it with * like so:
var theNumber;
function inputFieldSubmitCallback() {
theNumber = $(".masked_text").text();
$(".masked_text").html(theNumber.replace(/\d/g, "*").show();
}
** you can instead of course store the number in localStorage or a js object... but it's still in the client (not secure.. if that's an issue).
I'm building a tic-tac-toe game with javascript. The issue is when I am checking to see if there are any winners on the board after each move.
When I run this jQuery function
$( "#row1")[0].innerHTML
The output is
"<span0>o</span0><span1>x</span1><span2>o</span2>"
Because each html element has a different span I'm not quite sure how to check without writing out all the possibilities. I have looked at SOF and found this Get array of values use JQuery?. It's quite similar but it doesn't account for the different span tags, e.g (span0, span1, span2).
I'm trying to see how I can only get the 'o','x','o' from the list.
To get you "oxo" in a string which you can then process however you see fit, you can use:
// gets you "oxo"
$( "#row1").text();
If you want those characters in an array, you could do this:
// gets you ["o", "x", "o"]
$( "#row1").text().split("");
I don't think that those spans are valid html5 tags. Each of the span tags should just be . If you are using the individual span names to insert text into them, then it is better to do that by id eg . So wherever you are referencing $("span1") or $("#row1 span1") you would instead reference the id like this: $("#square1") in order to insert the x and o text. There are other ways to do this, but for these purposes it is probably just best to have 9 separate ids. This way the example in the link that you referenced to read them into an array is essentially what you need.
If you really don't want to do that, then add a give all of your span tags a class= 'box' class. eg: . In this case the code to read into an array based on the example you provided in the link would have to change from $('#row1 span') to $('#row1 .box') (notice the period before "box". indicating that we are looking for classes, rather than tag names) I don't like this second solution, because it doesn't fix the invalid html5 tags.
I suppose there may be a way to use a wildcard to search all elements that begin with "span" but that would just be way more ugly.
Demo
Below code will do the job
var html = "<span0>o</span0><span1>x</span1><span2>o</span2>";
var values = $.map($(html), function( n, i ) {
return $(n).html();
});
console.log(values);
Here is how you can get it, we will loop through child span elements of #row1 and alert their text value (which is the inner text):
$("#row1").children().each(function()
({
alert($("this").text());
});
I'm trying to precisely fit a string into a certain width. This means the font-size changes depending on the string. I now use the following function, using jQuery:
function fontResize ( )
{
for (var i = $("#date").css("font-size").slice(0, -2); $("#date").width() < $("#clock").width(); i++)
$("#date").css("font-size", i.toString() + "px");
}
The idea is that I set the font-size in the CSS to the lowest possible value. I initialize the loop with this value and increment the font-size with 1 until the string is wider than the width of the containing element. The string in this case is "date" and the containing element is "clock".
Although this works, I think the main disadvantage is that the string has to be first drawn before the width can be determined. This means I cannot call this function before loading the body.
If anyone knows a better way to do this please let me know! Thanks.
To make sure you're getting all the styles and such applied to it that will be applied when the page is fully rendered, yes, you do want to put the element in the DOM (and in the right place in the DOM) before you do your measurement stuff. But you don't have to wait until everything else is there (unless you think it will affect the styling of the string you're measuring). You can put your code in a script block immediately after the element in question — no waiting for ready. The date element will be there and accessible, according to Google's Closure library engineers. E.g., if date is a span:
<body>
...
<span id="date">December 13th</span>
<script>fontResize();</script>
...
...
</body>
It's unfortunate to intermix code and markup like that (particularly if you have separate teams doing the markup and the code), but if your requirement is to size the text absolutely as soon as possible, that's how.
The above also assumes your fontResize function is already loaded (e.g., in a script block higher on the page). This is another reason it's unfortunate to mix markup and code like this, because normally of course you want to put your scripts at the bottom, just before closing the body tag.
However: It may be worth experimenting to see if you can do your resizing in the script you put just before the closing body tag instead. There'd be a small window of opportunity for the page not to look right, but quite small and of course pages tend to look a little funny as they load anyway. Then you wouldn't have the intermixing problem and wouldn't have to load your scripts early. You may find that the just-before-the-closing-body-tag is soon enough.
How about using the canvas, and the measureText method?
$(function () {
var canvas = $("canvas")[0];
var context = canvas.getContext("2d");
var text = "hello world";
context.font = "40pt Calibri";
var metrics = context.measureText(text);
alert(metrics.width);
});
I have a <textarea> that I want to grow by one row every time the user enters into the last row shown in the <textarea>. Is this possible?
I have seen it done before, but can't figure out how to do it.
Okay, I just created this off the top of my head, so there may be browser compatibility issues. The concept is pretty simple however. Basically, on every keyup event, append a newline to the current text in the textarea element, then check if scrollHeight is greater than offsetHeight. If this is the case, set the elements height to be equal to scrollHeight. After all this, remove the appended newline. Assuming your textarea element has the id ta:
EDIT -- Okay, my original idea caused the cursor position to jump to the end of the text even if the user moved the cursor back, not good. The fix I came up with involves creating an invisible clone of the text area, and inserting the extra newline in that one, as to not disturb the cursor position in the visible one. Not sure I'm enterily comfortable with this method, but it works for now. If there is a better method I'd be happy to hear it. Here's the updated code:
var shadow = document.createElement('textarea');
shadow.className = 'autosize';
shadow.style.visibility = 'hidden';
document.getElementById('ta').onkeyup = function() {
this.parentNode.appendChild(shadow);
shadow.value = this.value + '\n';
if (shadow.scrollHeight > shadow.offsetHeight) {
this.style.height = shadow.scrollHeight + 'px';
}
this.parentNode.removeChild(shadow);
};
And the updated test http://jsfiddle.net/7wezW/1/
Now back to your regular programming...
Works well in Chrome, if someone points out issues in other browsers, I will try work them out.
PS, I should point out that if the user pastes text using just the mouse, the size of the textarea element will not adjust. Should be a trivial issue, but I'll leave it out as not to over-complicate things.
There are code and a demo at http://webdesign.torn.be/tutorials/javascript/prototype/auto-expand-contract-textarea/.
There's also a non-IE6 version that doesn't use frameworks:
http://scrivna.com/blog/2008/04/12/javascript-expanding-textareas/
Yes, there are many plugins for JQuery, such as this one, which comes with a demo: http://james.padolsey.com/javascript/jquery-plugin-autoresize/
Very customizable in terms of maximum height, buffer space, etc.