CSS Transitions not working inside parametrized functions - javascript

So I got the following code to create a simple fixed red box:
var red_box = document.createElement('div');
red_box.id = 'caixa_apresentacao_texto';
red_box.style.width = "40%";
red_box.style.overflow = "hidden";
red_box.style.backgroundColor = "white";
red_box.style.color = "black";
red_box.style.border = "5px double red";
/* Centralizing */
red_box.style.position = "fixed";
red_box.style.left = "50%";
red_box.style.marginLeft = "-20%"; //Por que a largura é 40%...
red_box.style.transition = "max-height 1s";
red_box.style.display = "none";
red_box.style.zIndex = "99999999999999";
red_box.style.marginTop = "50px";
red_box.style.maxHeight = "0px";
document.documentElement.insertBefore(red_box,document.body);
So, the idea is that, when I pass some text to this box, it enlarges slowly in order to display it. I get this behaviour with the following code:
var timerHeight;
function expandBox(text){
clearInterval(timerHeight);
/* if the box is empty...*/
if(document.querySelector("#red_box").style.maxHeight == "0px"){
document.querySelector("#red_box").style.display = "inline-block";
red_box.innerHTML = text;
/* Call a function that enlarge the maxHeight property , theorically with the transition letting it more beautiful */
var someText = "text";
timerHeight= setTimeout(enlargeBoxHeight(someText),1);
}
}
function enlargeBoxHeight(anyText){
document.querySelector("#red_box").style.maxHeight ="50px";
}
expandBox("Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut sollicitudin euismod metus, at blandit neque maximus ac. Integer fermentum nulla at nibh suscipit, a placerat est pretium. Morbi varius ornare enim, ac pulvinar elit aliquet in. Nullam non diam in nibh consectetur fringilla id nec enim. Mauris lacinia a augue ac consectetur. Etiam tempor et elit a dictum. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam interdum pulvinar pharetra. Aliquam erat volutpat. Aliquam non diam eget turpis tincidunt venenatis at in est. Duis laoreet nibh ultrices erat faucibus hendrerit.")
You can see the fiddle here.
So, I know that 50px is not a good height, but what matters here is that the transition is not working. You may have noticed that the var someText is useless here; but it does have the purpose to express my doubt. I've tried to take it off of the enlargeBoxHeight call. So the last part of the code now is:
...
timerHeight= setTimeout(enlargeBoxHeight,1);
}
}
function enlargeBoxHeight(){
document.querySelector("#red_box").style.maxHeight ="50px";
}
expandBox("Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut sollicitudin euismod metus, at blandit neque maximus ac. Integer fermentum nulla at nibh suscipit, a placerat est pretium. Morbi varius ornare enim, ac pulvinar elit aliquet in. Nullam non diam in nibh consectetur fringilla id nec enim. Mauris lacinia a augue ac consectetur. Etiam tempor et elit a dictum. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam interdum pulvinar pharetra. Aliquam erat volutpat. Aliquam non diam eget turpis tincidunt venenatis at in est. Duis laoreet nibh ultrices erat faucibus hendrerit.")
And the surprise: the transition works now. Why? What I am missing here?

When you do:
setTimeout(enlargeBoxHeight,1);
Without the parentheses (), you pass the function enlargeBoxHeight to the timeout, without calling it yet. The timeout will call it after 1ms. Which produced expected behavior + transition.
When you do:
timerHeight= setTimeout(enlargeBoxHeight(someText),1);
You pass the result of the function enlargeBoxHeight to the timeout. () part forces javascript to immediately call the function, and process everything before the timeout. So the transition does not work. After the 1ms, javascript handles the result (with is undefined or irrelevant).
If you want to pass a parameter to a timeout, do:
timerHeight= setTimeout(enlargeBoxHeight.bind(someText),1);
Which should work as expected.

Related

How to set styling of div based on another div using Javascript?

i have a unique case here. So i have 2 divs, one on the left and one on right. How can i make it so that if the height of left div exceeds the height of the div on right, the function should make the heights equal and hide any text for the left div. So if i calculate the offsetheight on load and for one on right is 443 px and one on left is 583 px, it should make both heights equal and height the rest 140px of data of left one.
I created a pen
var text = document.getElementById('overflow_text')
function mounted() {
var toggleBtn = document.getElementById('toggle_text')
var offsetDiv = document.getElementById('offset_height')
var offsetDivHeight = offsetDiv.offsetHeight + 'px'
var textHeight = text.offsetHeight + 'px'
console.log(textHeight)
console.log(offsetDivHeight)
if (textHeight > offsetHeight) {
text.style.maxHeight = offsetDivHeight
text.style.overflow = 'hidden'
text.style.textOverflow = 'ellipsis'
text.style.whiteSpace = 'nowrap'
}
}
#toggle_text {
cursor: pointer;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.1.3/css/bootstrap.min.css" rel="stylesheet" />
<body onLoad='mounted()'>
<div class="container">
<div class="row">
<div class="col-md-6">
<p id='overflow_text' class="readMore">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus imperdiet, nulla et dictum interdum, nisi lorem egestas vitae scelerisque enim ligula venenatis dolor. Maecenas nisl est, ultrices nec congue eget, auctor vitae massa. Fusce luctus
vestibulum augue ut aliquet. Nunc sagittis dictum nisi, sed ullamcorper ipsum dignissim ac. In at libero sed nunc venenatis imperdiet sed ornare turpis. Donec vitae dui eget tellus gravida venenatis. Integer fringilla congue eros non fermentum.
Sed dapibus pulvinar nibh tempor porta.Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus imperdiet, nulla et dictum interdum, nisi lorem egestas vitae scelerisque enim ligula venenatis dolor. Maecenas nisl est, ultrices nec
congue eget, auctor vitae massa. Fusce luctus vestibulum augue ut aliquet. Nunc sagittis dictum nisi, sed ullamcorper ipsum dignissim ac. In at libero sed nunc venenatis imperdiet sed ornare turpis. Donec vitae dui eget tellus gravida venenatis.
Integer fringilla congue eros non fermentum. Sed dapibus pulvinar nibh tempor porta. Sed dapibus pulvinar nibh tempor porta.Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus imperdiet, nulla et dictum interdum, nisi lorem egestas
vitae scelerisque enim ligula venenatis dolor. Maecenas nisl est, ultrices nec Sed dapibus pulvinar nibh tempor porta.Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus imperdiet, nulla et dictum interdum, nisi lorem egestas
vitae scelerisque enim ligula venenatis dolor. Maecenas nisl est, ultrices nec Sed dapibus pulvinar nibh tempor porta.Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus imperdiet, nulla et dictum interdum, nisi lorem egestas
vitae scelerisque enim ligula venenatis dolor. Maecenas nisl est, ultrices nec</p>
<span onClick="myFunction()" id="toggle_text">Read More</span>
</div>
<div class="col-md-6">
<p id="offset_height">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus imperdiet, nulla et dictum interdum, nisi lorem egestas vitae scelerisque enim ligula venenatis dolor. Maecenas nisl est, ultrices nec congue eget, auctor vitae massa. Fusce luctus
vestibulum augue ut aliquet. Nunc sagittis dictum nisi, sed ullamcorper ipsum dignissim ac. In at libero sed nunc venenatis imperdiet sed ornare turpis. Donec vitae dui eget tellus gravida venenatis. Integer fringilla congue eros non fermentum.
Sed dapibus pulvinar nibh tempor porta.Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus imperdiet, nulla et dictum interdum, nisi lorem egestas vitae scelerisque enim ligula venenatis dolor. Maecenas nisl est,Donec vitae dui
eget tellus gravida venenatis. Integer fringilla congue eros non fermentum. Sed dapibus pulvinar nibh tempor porta.Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus imperdiet, nulla et dictum interdum, nisi lorem egestas vitae
scelerisque enim ligula venenatis dolor. Maecenas nisl estDonec vitae dui eget tellus gravida venenatis. Integer fringilla congue eros non fermentum. Sed dapibus pulvinar nibh tempor porta.Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Phasellus imperdiet, nulla et dictum interdum, nisi lorem egestas vitae scelerisque enim ligula venenatis dolor. Maecenas nisl est </p>
</div>
</div>
</div>
</body>
So if you check the console, you will see what the heights of both divs are onLoad. Not sure how i can set the CSS through Javascript. Thank you in advance.
If any one has any other ideas on how to achieve this, i am open to suggestions.
The solution is a bit tricky, since you cannot simply use textOverflow: ellipsis css property if your text has multiple lines.
First we set height of the left text container to the height of the right which is smaller. Then we have to shrink the number of words displayed inside the left container. We remove words from the end of the container until container's scrollHeight is smaller or equal to the container's height.
In this way we know that the container has only as much words as it's able to display with restriction that it's no taller than the right container.
The drawback is that we remove overflowing words from the element so you're no longer able to get original content from this container.
function mounted() {
var leftContainer = document.getElementById('overflow_text')
var rightContainer = document.getElementById('offset_height')
var rightOffsetHeight = rightContainer.offsetHeight;
var leftOffsetHeight = leftContainer.offsetHeight;
if (leftOffsetHeight > rightOffsetHeight) {
leftContainer.style.height = rightOffsetHeight + "px"
var wordArray = leftContainer.innerHTML.split(' ');
while(leftContainer.scrollHeight > leftContainer.offsetHeight) {
wordArray.pop();
leftContainer.innerHTML = wordArray.join(' ') + '...';
}
}
}
Your if statement needs to use the variable name, offsetDivHeight.
if (textHeight > offsetHeight)
offsetHeight is never defined. Do you mean offsetDivHeight?
text.style.whiteSpace = 'nowrap'
If you do this, all of the text in the div will be confined to one line.
Demo with these changes made.

link for max characters in javascript not working

Ive got a js that runs to see if a maximum amount of characters is reached. Its got text along with href, but when the max amount of characters is reached, the link doesnt work and converts it to just text. When the limit of less then 580 characters, link works. When it does reach the limit, the read more link does work. Any advice or help please and thanks
$(document).ready(function () {
var stylistText = $('#stylistText');
var stylistText2 = document.getElementById("stylistText").innerHTML;
var countActualText = stylistText2.valueOf().length;
var maxLength = 580;
var aElement = document.createElement('a');
var linkText = document.createTextNode(" ...Read more");
aElement.appendChild(linkText);
aElement.href = "#";
if (countActualText > maxLength) {
stylistText.text(stylistText.text().substring(0, 580));
stylistText.append(aElement);
}
});
here is the html
<div class="stylistInfo">
<img id="stylistPhoto" src="images/Test.jpg" alt="peekaboo beans stylist" />
<p id="stylistText">
This is supposed to be a link Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis nec mauris odio. Sed varius, felis eget rutrum scelerisque, enim ligula porta nulla, id rhoncus orci nisi at nunc. Fusce cursus, libero a sagittis viverra, arcu eros luctus arcu, sit amet euismod sapien purus quis nisl. Praesent aliquam aliquam ante ornare pulvinar. Mauris ultrices dictum quam, at ornare dui blandit id. Sed erat elit, fringilla quis diam at, euismod rhoncus massa. Curabitur at arcu nisl. Nullam tincidunt lacus sapien, sed porttitor odio sodales sit amet. Nunc tincidunt nisi et nulla aliquam cras amet.Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis nec mauris odio. Sed varius, felis eget rutrum scelerisque, enim ligula porta nulla, id rhoncus orci nisi at nunc. Fusce cursus, libero a sagittis viverra, arcu eros luctus arcu, sit amet euismod sapien purus quis nisl. Praesent aliquam aliquam ante ornare pulvinar. Mauris ultrices dictum quam, at ornare dui blandit id. Sed erat elit, fringilla quis diam at, euismod rhoncus massa. Curabitur at arcu nisl. Nullam tincidunt lacus sapien, sed porttitor odio sodales sit amet. Nunc tincidunt nisi et nulla aliquam cras amet.
</p>
</div>
Change stylistText.text(stylistText.text().substring(0, 580));
to stylistText.html(stylistText.html().substring(0, 580));
However, truncating a block of text that contains HTML may cause other problems, especially if the truncation occurs in the middle of an element. I would recommend rethinking your whole strategy on this.

Expanding a Read more / Read less jQuery script

I have this great script that uses jQuery to display a small portion of content & allow the user to read more/read less of the content.
Here is my current Fiddle: http://jsfiddle.net/Tqwdh/1/
Summary: When you click the image, it needs to reveal the additional text.
I would love to know how I can update this script to allow the user to click the associated image and it would display more of the text (as well as keeping the text link in place).
Can someone show me how I can achieve this?
Here is my example HTML:
<article id="post-5" >
<div class="more-less">
<div class="more-block">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed diam purus, lacinia eget placerat sit amet, bibendum nec nisl. Curabitur a mattis ipsum. Praesent quis nisi in purus malesuada rhoncus. Pellentesque ut quam eget libero congue lobortis. Nunc sed quam ac erat lobortis eleifend. Donec elementum sodales cursus. Aliquam porttitor massa nisi, in laoreet turpis. Sed consequat condimentum lorem ut dignissim. Sed hendrerit mauris ut massa fermentum laoreet. Pellentesque a leo vitae enim dictum lobortis. Praesent commodo feugiat velit iaculis malesuada.</p>
<p>Phasellus id elit ac lacus faucibus ullamcorper. Etiam ullamcorper pretium tellus, ut pharetra ante pulvinar vel. Sed neque diam, semper vel rhoncus non, congue ut sapien. Integer a mi eget libero elementum lobortis. Donec hendrerit egestas ligula sit amet eleifend. Curabitur pharetra venenatis tempor. Quisque pulvinar malesuada justo, ut euismod arcu pharetra vitae. Cras lobortis, ligula id euismod euismod, ipsum risus varius urna, faucibus gravida lectus mi nec nulla. Fusce eleifend fringilla nibh ut vulputate. Vivamus sagittis leo metus. Etiam facilisis convallis lacus adipiscing hendrerit. Duis ultricies euismod libero, nec blandit est semper a. Phasellus sit amet justo sed quam elementum lobortis. Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
</div>
</div>
<p>
<img src="http://placehold.it/300x187" alt="News Item 1" width="300" height="187" />
</p>
</article><!-- #post-## -->
and my jQuery:
$(function(){
// The height of the content block when it's not expanded
var adjustheight = 130;
// The "more" link text
var moreText = "Click to read more...";
// The "less" link text
var lessText = "Click to read less...";
// Sets the .more-block div to the specified height and hides any content that overflows
$(".more-less .more-block").css('height', adjustheight).css('overflow', 'hidden');
// The section added to the bottom of the "more-less" div
$(".more-less").append('<p style="display:block;margin-top:8px"></p>');
$("a.adjust").text(moreText);
$(".adjust").toggle(function() {
$(this).parents("div:first").find(".more-block").css('height', 'auto').css('overflow', 'visible');
// Hide the [...] when expanded
$(this).parents("div:first").find("p.continued").css('display', 'none');
$(this).text(lessText);
}, function() {
$(this).parents("div:first").find(".more-block").css('height', adjustheight).css('overflow', 'hidden');
$(this).parents("div:first").find("p.continued").css('display', 'block');
$(this).text(moreText);
});
});
Thank you :-)
You could just add a click handler to img like this:
DEMO
$(function(){
$('img').click(function(){
$(this).closest('article').find('.adjust').click();
});
});​
You will need to move the logic from the toggle handler to your own implementation, as you have more than one event source.
<article id="post-5" >
<div class="more-less">
<div class="more-block">…</div>
</div>
<p>
…
</p>
</article>
$(function(){
var adjustheight = 130; // The height of the content block when it's not expanded
var texts = {
more: "Click to read more…",
less: "Click to read less…"
};
$("article").each(function() {
var block = $(".more-block", this).css({height:adjustheight, overflow:'hidden'}),
cont = $("p.continue", this),
toggle = $('<a href="#'+this.id+'" class="adjust">').text(texts.more),
open = false;
$(".more-less", this).append($('<p style="display:block;margin-top:8px">').append(link));
$("a.adjust", this).click(function() {
open = !open;
block.css("height", open ? "auto" : adjustheight);
link.text(texts[open ? "less" : "more"]);
cont[open ? "show" : "hide"]();
}
});
});
Simply add the same behaviour of the "Click to read more" element to the image elements.
When you set the toggle handlers like this:
$(".adjust").toggle(function() {
$(this).parents("div:first").find(".more-block").css('height', 'auto').css('overflow', 'visible');
// Hide the [...] when expanded
$(this).parents("div:first").find("p.continued").css('display', 'none');
$(this).text(lessText);
}, function() {
$(this).parents("div:first").find(".more-block").css('height', adjustheight).css('overflow', 'hidden');
$(this).parents("div:first").find("p.continued").css('display', 'block');
$(this).text(moreText);
});
Just use jQuery's multiple selector to select the image elements also, like in this example:
$(".adjust, #img1, #img2").toggle(function() {
$(this).parents("div:first").find(".more-block").css('height', 'auto').css('overflow', 'visible');
// Hide the [...] when expanded
$(this).parents("div:first").find("p.continued").css('display', 'none');
$(this).text(lessText);
}, function() {
$(this).parents("div:first").find(".more-block").css('height', adjustheight).css('overflow', 'hidden');
$(this).parents("div:first").find("p.continued").css('display', 'block');
$(this).text(moreText);
});
Demo
Hope it helps.
var maxLength = 50;
$('.N_DESC').each( function (e) {
const thisVal = $(this).text();
const thisLength = $.trim(thisVal).length;
const noticeStr = thisVal.substring(0, maxLength);
const removedStr = thisVal.substring(maxLength, thisLength);
if(thisLength > maxLength){
$(this).empty().html(noticeStr);
$(this).append('<span class="more-text">'+ removedStr +'</span>');
$(this).append(`Read More..`);
}
});
$(document).on('click', '.read-more', function (e) {
$(this).closest('span').find('.more-text').show();
$(this).addClass('read-less');
$(this).removeClass('read-more');
$(this).html('Read Less..');
});
$(document).on('click', '.read-less', function (e) {
$(this).closest('span').find('.more-text').hide();
$(this).addClass('read-more');
$(this).removeClass('read-less');
$(this).html('Read More..');
});
.N_DESC .more-text{
display: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<span class="N_DESC">Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas porttitor congue massa. Fusce posuere, magna sed pulvinar ultricies, purus lectus malesuada libero, sit amet commodo magna eros quis urna. Nunc viverra imperdiet enim. Fusce est. Vivamus a tellus. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Proin pharetra nonummy pede. Mauris et orci. Aenean nec lorem. In porttitor.</span>
<br>
<span class="N_DESC">Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas porttitor congue massa. Fusce posuere, magna sed pulvinar ultricies, purus lectus malesuada libero, sit amet commodo magna eros quis urna. Nunc viverra imperdiet enim.</span>
<br>
<span class="N_DESC">Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas porttitor congue massa. Fusce posuere, magna sed pulvinar ultricies, purus lectus malesuada libero</span>

Change css property in chain - JavaScript

I'm using MooTools 1.4.5 and I want to change cursor before calling function that takes some time and after finished same function set cursor to default. I was not successful.
After that I made simple example to change background color via plain JavaScript (no jQuery or MooTools plugin) and again I was not successful.
Here is my code.
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
</div>
</form>
</body>
<script type="text/javascript">
<!--
document.body.style.background = 'red';
setTimeout(function () { }, 1250);
document.body.style.background = 'yellow';
//-->
</script>
</html>
First at all I set background color to red, and after delay to yellow. I assumed that the background color will bi set to red and after delay to yellow. It doesn't work. When page is loaded background color is yellow (last line). If I insert alert function in a middle of lines where sets background color everything works fine (background color is red, click to message box, background color is yellow).
Why it works so? Only last changing style is affected. I need something like that to change pointer before calling function that takes 10 seconds and setting cursor to default value after function is done.
setTimeout doesn't mean "wait". It calls the function you give it sometime later. The flow of execution continues immediately:
document.body.style.background = 'red';
setTimeout(function () {
document.body.style.background = 'yellow';
}, 1250);
As such, this works too:
setTimeout(function () {
document.body.style.background = 'yellow';
}, 1250);
document.body.style.background = 'red';
For the case of a cursor, just replace .background = 'red' with .cursor = 'wait' and .background = 'yellow' with .cursor = 'default'.
document.body.style.cursor = 'wait';
setTimeout(function() {
doSomethingExpensive();
document.body.style.cursor = 'default';
}, 10);
The first parameter of setTimeout() is a callback function, which will be called after the delay, you should use this kind of code :
document.body.style.background = 'red';
document.body.style.cursor = 'wait';
setTimeout(function(){
document.body.style.background = 'yellow';
document.body.style.cursor = 'default';
}, 1250);
body {
width: 100%;
height: 100%;
}
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed non risus. Suspendisse lectus tortor, dignissim sit amet, adipiscing nec, ultricies sed, dolor. Cras elementum ultrices diam. Maecenas ligula massa, varius a, semper congue, euismod non, mi. Proin porttitor, orci nec nonummy molestie, enim est eleifend mi, non fermentum diam nisl sit amet erat. Duis semper. Duis arcu massa, scelerisque vitae, consequat in, pretium a, enim. Pellentesque congue. Ut in risus volutpat libero pharetra tempor. Cras vestibulum bibendum augue. Praesent egestas leo in pede. Praesent blandit odio eu enim. Pellentesque sed dui ut augue blandit sodales. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Aliquam nibh. Mauris ac mauris sed pede pellentesque fermentum. Maecenas adipiscing ante non diam sodales hendrerit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed non risus. Suspendisse lectus tortor, dignissim sit amet, adipiscing nec, ultricies sed, dolor. Cras elementum ultrices diam. Maecenas ligula massa, varius a, semper congue, euismod non, mi. Proin porttitor, orci nec nonummy molestie, enim est eleifend mi, non fermentum diam nisl sit amet erat. Duis semper. Duis arcu massa, scelerisque vitae, consequat in, pretium a, enim. Pellentesque congue. Ut in risus volutpat libero pharetra tempor. Cras vestibulum bibendum augue. Praesent egestas leo in pede. Praesent blandit odio eu enim. Pellentesque sed dui ut augue blandit sodales. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Aliquam nibh. Mauris ac mauris sed pede pellentesque fermentum. Maecenas adipiscing ante non diam sodales hendrerit. Lorem ipsum.
See more about setTimeout here

How can I select the first word of every line of a block of text?

I'm trying to select each first word, to wrap it in a specific span.
Lorem ipsum dolor sit amet,
consectetur adipiscing elit. Cras
sagittis nunc non nisi venenatis
auctor. Aliquam consectetur pretium
sapien, eget congue purus egestas nec.
Maecenas sed purus ut turpis varius
dictum. Praesent a nunc ipsum, id
mattis odio. Donec rhoncus posuere
bibendum. Fusce nulla elit, laoreet
non posuere.
If this is the text, the script should select Lorem, Aliquam, varius and nulla.
You can do this, by using JavaScript to wrap every word in the paragraph in its own span, and then walking through the spans finding out what their actual position on the page is, and then applying your style changes to the spans whose Y position is greater than the preceding span. (Best do it beginning-to-end, though, as earlier ones may well affect the wrapping of latter ones.) But it's going to be a lot of work for the browser, and you'll have to repeat it each time the window is resized, so the effect will have to be worth the cost.
Something like this (used jQuery as you've listed the jquery tag on your question):
jQuery(function($) {
var lasty;
var $target = $('#target');
$target.html(
"<span>" +
$target.text().split(/\s/).join("</span> <span>") +
"</span>");
lasty = -1;
$target.find('span').each(function() {
var $this = $(this),
top = $this.position().top;
if (top > lasty) {
$this.css("fontWeight", "bold");
lasty = top;
}
});
});
<div id='target' style='width: 20em'>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras sagittis nunc non nisi venenatis auctor. Aliquam consectetur pretium sapien, eget congue purus egestas nec. Maecenas sed purus ut turpis varius dictum. Praesent a nunc ipsum, id mattis odio. Donec rhoncus posuere bibendum. Fusce nulla elit, laoreet non posuere.</div>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
Naturally that's making a huge set of assumptions (that all whitespace should be replaced with a single space, that there's no markup in the text, probably others). But you get the idea.
Here's a version that handles window resize, 50ms after the last resize event occurs (so we're not doing it interim) and with Gaby's suggestion (below) that we unbold at the start of the resize:
jQuery(function($) {
var resizeTriggerHandle = 0;
// Do it on load
boldFirstWord('#target');
// Do it 100ms after the end of a resize operation,
// because it's *expensive*
$(window).resize(function() {
if (resizeTriggerHandle != 0) {
clearTimeout(resizeTriggerHandle);
}
unboldFirstWord('#target');
resizeTriggerHandle = setTimeout(function() {
resizeTriggerHandle = 0;
boldFirstWord('#target');
}, 50);
});
function boldFirstWord(selector) {
var lasty;
// Break into spans if not already done;
// if already done, remove any previous bold
var $target = $(selector);
if (!$target.data('spanned')) {
$target.html(
"<span>" +
$target.text().split(/\s/).join("</span> <span>") +
"</span>");
$target.data('spanned', true);
}
else {
unboldFirstWord($target);
}
// Apply bold to first span of each new line
lasty = -1;
$target.find('span').each(function() {
var $this = $(this),
top = $this.position().top;
if (top > lasty) {
$this.css("fontWeight", "bold");
lasty = top;
}
});
$target.data('bolded', true);
}
function unboldFirstWord(selector) {
var $target = selector.jquery ? selector : $(selector);
if ($target.data('spanned') && $target.data('bolded')) {
$target.find('span').css("fontWeight", "normal");
$target.data('bolded', false);
}
}
});
<div id='target'>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras sagittis nunc non nisi venenatis auctor. Aliquam consectetur pretium sapien, eget congue purus egestas nec. Maecenas sed purus ut turpis varius dictum. Praesent a nunc ipsum, id mattis odio. Donec rhoncus posuere bibendum. Fusce nulla elit, laoreet non posuere. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras sagittis nunc non nisi venenatis auctor. Aliquam consectetur pretium sapien, eget congue purus egestas nec. Maecenas sed purus ut turpis varius dictum. Praesent a nunc ipsum, id mattis odio. Donec rhoncus posuere bibendum. Fusce nulla elit, laoreet non posuere. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras sagittis nunc non nisi venenatis auctor. Aliquam consectetur pretium sapien, eget congue purus egestas nec. Maecenas sed purus ut turpis varius dictum. Praesent a nunc ipsum, id mattis odio. Donec rhoncus posuere bibendum. Fusce nulla elit, laoreet non posuere. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras sagittis nunc non nisi venenatis auctor. Aliquam consectetur pretium sapien, eget congue purus egestas nec. Maecenas sed purus ut turpis varius dictum. Praesent a nunc ipsum, id mattis odio. Donec rhoncus posuere bibendum. Fusce nulla elit, laoreet non posuere. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras sagittis nunc non nisi venenatis auctor. Aliquam consectetur pretium sapien, eget congue purus egestas nec. Maecenas sed purus ut turpis varius dictum. Praesent a nunc ipsum, id mattis odio. Donec rhoncus posuere bibendum. Fusce nulla elit, laoreet non posuere.</div>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
Try this:
$(function() {
$('p').each(function() {
var text_splited = $(this).text().split(" ");
$(this).html("<strong>"+text_splited.shift()+"</strong> "+text_splited.join(" "));
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js"></script>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras sagittis nunc non nisi venenatis auctor.</p>
<p>Aliquam consectetur pretium sapien, eget congue purus egestas nec. Maecenas sed purus ut turpis varius dictum.</p>
<p>Praesent a nunc ipsum, id mattis odio. Donec rhoncus posuere bibendum. Fusce nulla elit, laoreet non posuere.</p>
To bold every first word of a <p> tag, including whitespace after the initial <p>, use some regular expressions:
$('p').each(function(){
var me = $(this);
me.html( me.text().replace(/(^\w+|\s+\w+)/,'<strong>$1</strong>') );
});

Categories

Resources