Removing automatically added line breaks when combining Javascript + HTML - javascript

Just starting off in web development and hoped one of you all could help me out.
I am building a site that displays the weather along with the four-day forecast with the help of SimpleWeather.js. There's a section in my javascript where I want to display a particular day's High & Low with a "|" in the middle to divide them. I also wanted to declare a class for the "|" part so that I can change the color of the divider. However, when I do this, it adds two line breaks, and I don't understand why or how to fix it.
The code is
$("#high-low-one").html(weather.forecasts.one.high+'<p class="high-low-divider">|</p>'+weather.forecasts.one.low);
However it shows up as:
30
|
28
(where the 30 is the high and 28 is the low temperature for any given day.)
I've also tried fixing this in CSS using inline-text, inline-block, block, and nowrap, just to name a few. Any help would be greatly appreciated!

<p> Is a block element by default. You can change this with CSS but use <span> instead as it is by default an inline element
You would end up with:
$("#high-low-one").html(weather.forecasts.one.high+'<span class="high-low-divider">|</span>'+weather.forecasts.one.low);
However I would style the temps in span elements and use the :after pseudo-element to add and style the pipe character.
Something like:
$("#high-low-one").html("<span class='high'>" + weather.forecasts.one.high + "</span><span class='low'>" + weather.forecasts.one.low + "</span>");
With some sample css:
#high-low-one .high
{
color:#F00;
}
#high-low-one .high:after
{
content: "|";
color: #0F0;
padding-left:0.5em;
padding-right:0.5em;
}
#high-low-one .low
{
color:#00F;
}
Which would give you something like: http://jsfiddle.net/D29AH/
For Completeness if you really had to use <p> use the following CSS
.high-low-divider
{
display:inline;
}

Related

CSS transition depends on order of style assignments

Trying to make a container with text gradually expand upon adding new text to it, I used css transition property. Precisely, I fix current width, add text and then release the width. JS code is following:
footer.style['max-width'] = footer.offsetWidth + 'px'
footer.innerHTML += ' additional text'
footer.style['max-width'] = '500px'
with this css for footer:
overflow: hidden;
text-overflow: clip;
white-space: nowrap;
This did't work. Trying to find a workaround I added another line of code:
footer.style['height'] = footer.offsetHeight + 'px'
Now, with this line being put before assignment of max-width (so in the beginning of the snippet), it doesn't work. But putting it after that line (making it second line) — does. The question is why? and what is the proper way to work with transitions? (but mainly, why?)
Fiddle tested in firefox 40.0 and chrome 39.0: http://jsfiddle.net/53dbm6vz/
It's likely that the problem is that both of your footer.style['max-width'] assignments occur inside the same synchronous operation. The browser(s) probably ignore the intermediate value completely.
It can be resolved if you split the operation to 2 parts:
Set the initialization width and...
Use a setTimeout to trigger the actual assignment.
Try like this:
footer.style['max-width'] = footer.offsetWidth + 'px'
window.setTimeout(function() {
footer.innerHTML += ' additional text'
footer.style['max-width'] = '500px'
}, 0)

How to change different language to different font-size at same line without unique each container?

How to change different language to different font-size at same line without unique each container? is it possible? with css or javascript?
div{
font-family: "English", "中文"
font-size: 20px;
// I need to make "中文" font-size 10px.
}
<div>This is English. 這是中文 This is English</div>
<div>This is English. 這是中文這是中文這是中文 This is English</div>
...
If you alter the text using JavaScript (since your question allowed for JavaScript), you can use CSS upon the results changed by JavaScript (which as others have said, requires adding a container).
For example :
window.onload = function () {
// Note that the following might also be used for Japanese or Korean
// Note also that I have not included (deprecated) compatibility characters. As
// per http://www.unicode.org/reports/tr38/#BlockListing , to cover those
// you would need to add:
// 1. \u3358-\u3370\u337B-\u337F\u33E0-\u33FE (e.g., immediately after "\u32CB")
// 2. \uFA2E-\uFA6D\uFA70-\uFAD9 (e.g., immediately after "\uFA29")
// 3. Replace \uFA0E\uFA0F\uFA11\uFA13\uFA14\uFA1F\uFA21\uFA23\uFA24\uFA27-\uFA29 with \uF900-\uFA2D OR if you want to keep the compat. listed separately from non-compat. (though there is no need for this), add the following, e.g., before \uFA0E: \uF900-\uFA0D\uFA10\uFA12\uFA15-\uFA1E\uFA20\uFA22\uFA25\uFA26\uFA2A-\uFA2D
// 4. Immediately before ")+\s?)+/g", add |\ud87e[\udc00-\ude1d]
// The portion \u2E80 up to \u32CB is for punctuation and special characters like radicals,
// but this does not support some punctuation characters which might be reused outside of
// CJK as well as in CJK.
var chineseChars = /((?:[\u2E80-\u2E99\u2E9B-\u2EF3\u2F00-\u2FD5\u2FF0\u2FFB\u3000-\u303F\u3105-\u312D\u3190-\u31B7\u31C0-\u31E3\u3220-\u3243\u3280-\u32B0\u32C0-\u32CB\u4E00-\u9FCC\u3400-\u4DB5\uFA0E\uFA0F\uFA11\uFA13\uFA14\uFA1F\uFA21\uFA23\uFA24\uFA27-\uFA29]|[\ud840-\ud868][\udc00-\udfff]|\ud869[\udc00-\uded6\udf00-\udfff]|[\ud86a-\ud86c][\udc00-\udfff]|\ud86d[\udc00-\udf34\udf40-\udfff]|\ud86e[\udc00-\udc1d])+\s?)+/g;
document.body.innerHTML = document.body.innerHTML.replace(
chineseChars,
'<span lang="zh">$1</span>'
);
};
with your CSS:
body {font-size: 12px;}
span:lang(zh) {font-size: 10px}
JSFiddle
My use of lang="zh" is based on an assumption that you know these to be used for Chinese as opposed to Japanese or Korean. If you do not know, you can change the span in JS to this:
'<span class="cjk">$1</span>'
and the Chinese part of the CSS to this:
span.cjk {font-size: 10px}
That won't make any assumptions about the language, only the characters.
JSFiddle
http://jsbin.com/qozidepi/1/watch?js,output
JS:
// Get the div
var div = document.getElementById("text");
// Get the value
var value = div.innerHTML;
// Regular expression finds Chinese characters and wraps them
// in a span tag, which have font-size 40px
value = value.replace(/([\u3400-\u9FBF]+)/g, function(match){
return "<span>" + match + "</span>";
});
// Set the div's value
div.innerHTML = value;

How to get content of particular column of html page after split using css-rule(-webkit-column-width:)

i splited html page in multiple columns using css rule
var mySheet = document.styleSheets[0];
function addCSSRule(selector, newRule)
{
if (mySheet.addRule) {
mySheet.addRule(selector, newRule);// For Internet Explorer
} else {
ruleIndex = mySheet.cssRules.length;
mySheet.insertRule(selector + '{' + newRule + ';}', ruleIndex)//for firefox..
}
}
addCSSRule('html', 'padding: 0px; height: 460px; -webkit-column-gap: 0px; -webkit-column- width: 320px;');
How do I get content from particular column.
Please help me.
I'm pretty sure there is no simple way to do this. Your best bet is to find the length of the text and get the 1st half (or third, or fourth as the case may be) of the content.
It won't be accurate, but it will be close.
The other way could be to select the content starting at the top, and figure out the end of a column by the position of the caret. (I'm just riffing here. Not sure if this actually works)
I can get the content after one hour to find and deploy . I hope my sharing will help someone.
Pls check in: jsfiddle.net/cuongtakien/7YMSL/1/
You can change the position of start and end point and calculate the height of each column . Finally,you change the my hard fixed in code and get content.
Thank mattsven to share about createRange in javascript.
Have a nice code!

How to calculate the width of an input HTML element so that it matches the size of its content?

How to calculate the width of an input HTML element so that it matches the size of its content ?
I already update an input on the fly as the user types :
<input type='text' onkeydown='this.size=this.value.length' />
However, this does not seem completely correct because it does not take into account the fact that some characters are longer than others :
I will get more and more whitespace if I type only some "l" characters
the size will be insufficient if I type only some "w" characters
How to proceed?
PS: Why I want to do this (already answered this in a answer that was deleted)?
I have sentences in which I have to replace the bracket content by inputs (ex: [user] is [years] old). I have no idea what the sentence can be, so I do not know an adequate length for the inputs, and I would like to keep it readable on one line (avoiding too much whitespace).
You could use a (hidden) canvas and the measureText() method of the context to get your string's width.
EDIT:
Looks fast enough.
First, define some CSS...
input,
#input-helper {
display: inline;
font-size: 14px;
font-family: serif;
line-height: 16px;
}
#input-helper {
position: absolute;
top: -10000px;
}
...then use some JavaScript...
var div = document.createElement("div");
div.id = "input-helper";
document.body.appendChild(div);
var input = document.querySelector("input");
input.addEventListener("keyup", function() {
div.textContent = this.value;
input.style.width = div.offsetWidth + "px";
});​
jsFiddle.
You will want to choose a reasonable start width for your input element too.
If using jQuery is not a problem, here is a demo I put together on jsFiddle. It uses an Autoexpand.js file that does what you want. Check out the last example in the fiddle.
Some specifics:
It's based on .keyup and .keypress for the fastest response possible.
It takes into account the HTML markup that's pasted into the box. Things like linebreaks are dealt with.
The source file shows smart processing by taking everything about the font into consideration.
Also included in the jsFiddle are links to download a pastebin version of the fiddle since jsFiddle Sandbox breaks in IE8. That said, it also works in IE7 too!
First : Add this div where you want
<div id="calcsize" style="display:none;"></div>
Second : Use this function
function getWidthof(txt)
{
$('#calcsize').empty().append(txt);
return $('#calcsize').width();
}

How can I highlight the line of text that is closest to the mouse?

I have a long text and I'd like to offer the user a reading help: The current line should be highlighted. To make it easier, I'll just use the Y coordinate of the mouse (this way, the mouse pointer isn't going to get in the way). I have a big DIV with the id content which fills the whole width and a small DIV with the class content for the text (see here for an example).
I'm using jQuery 1.4. How can I highlight the line of text that is closest to the current mouse position?
Not sure if jQuery will help you out much here, but you could take a look at the element.getClientRects method, documented on MSDN and MDC. More specifically, this example at MSDN is sort of similar to what you want to achieve, highlighting lines using a cleverly z-indexed div element that goes behind the text at the co-ordinates returned by getClientRects().
You should be able to achieve the same thing by looping through the TextRectangle objects returned in the document's onmousemove and checking to see if the y value of the mouse cursor is > the top and < the bottom of each rectangle and moving the cleverly z-indexed div to the same position/height.
All the current major browsers support getClientRects().
http://jsbin.com/avuku/15
UPDATED - working in Chrome, IE6/7/8, Firefox, Opera, Safari. The initial problems I had in the other browsers were related to the DIV needing to be display: inline.
UPDATED AGAIN - I had to refer to this answer for some newer questions, so I took the time to update it to recalc the lines on window resize. It looks like others have been playing around too, it's now on revision 15.
I don't see how you could feasibly do this without explicitly-wrapped text (i.e., newlines or <br> elements).
To the best of my knowledge, there's no way for the DOM to discover where a specific piece of text has wrapped, character-wise nor pixel-wise - including what I know of the Range API - not to mention the dynamic nature text can assume, such as with the text-zooming feature of browsers.
But if you could somehow manage to generate/inject explicit line-endings, then I think I have a solution for you.
EDIT
Thanks to the awesome information in Pekka's answer, I've cobbled together a functional prototype, but it has a significant caveat - works with plain-text content only. Any HTML present the body of the element will be stripped.
jQuery.fn.wrapLines = function( openTag, closeTag )
{
var dummy = this.clone().css({
top: -9999,
left: -9999,
position: 'absolute',
width: this.width()
}).appendTo(this.parent())
, text = dummy.text().match(/\S+\s+/g);
var words = text.length
, lastTopOffset = 0
, lines = []
, lineText = ''
;
for ( var i = 0; i < words; ++i )
{
dummy.html(
text.slice(0,i).join('') +
text[i].replace(/(\S)/, '$1<span/>') +
text.slice(i+1).join('')
);
var topOffset = jQuery( 'span', dummy ).offset().top;
if ( topOffset !== lastTopOffset && i != 0 )
{
lines.push( lineText );
lineText = text[i];
} else {
lineText += text[i];
}
lastTopOffset = topOffset;
}
lines.push( lineText );
this.html( openTag + lines.join( closeTag + openTag ) + closeTag );
};
$(function()
{
$('p').wrapLines( '<span class="line">', '</span>' );
});
span.line {
display: inline;
}
span.line:hover {
background-color: lightblue;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<p style="max-width:400px">
one two three four five six seven eight nine ten eleven twelve thirteen fourteen fifteen sixteen seventeen eighteen nineteen twenty twenty-one twenty-two twenty-three
</p>
The best approach that comes to mind is splitting each line into a <span> or <div> element that has a :hover CSS class with the "highlight" setting set:
span.line:hover { background-color: lightblue; }
That would be the least expensive solution, as the browser is going to take care of all the highlighting itself. If you want fancy effects, you can still achieve that by adding mouseover and mouseout events to every line.
The tough part, of course, is splitting the content into lines at the browser's line break. You need to do that dynamically so the lines actually reflect the positions at which the browser breaks the text.
Maybe the accepted answer to this question is a step into the right direction:
Getting a specific line using jQuery
How it works:
It goes through the entire element (actually, a clone of the element) inserting a element within each word. The span's top-offset is cached - when this offset changes we can assume we're on a new line.

Categories