Can't remove whitespaces (after splitting div up with lettering.js) - javascript

So I got some divs, which I split up with lettering.js. What this does is just splitting up an element into <span>s containing the single characters.
When I got a string with multiple words like "Hello World!", lettering.js will create a separate span for the space between the words. That span won't have a width, since its "empty" → there's no space between the words.
So theoretically I should be able to select those "empty" spans with span:blank (and manually setting a width for the space) since :blank selects whitespace aswell.
That didn't work tho.
So I tried using JavaScript, but even that failed.
I tried several methods:
$("span[class^='char']").each(function(){
// method 1:
this.innerHTML.trim();
// method 2:
$(this).text().trim();
// method 3:
$(this).text().replace(/\s/g, '');
// method 4:
$(this).text().replace(' ', '');
});
But all of those methods failed.
The selector isn't the problem. It selects every span I want it to.
Another method would just be to set a min-width for every span, which is pretty shabby tho and isn't always working nicely.
Anyone got an idea how I can get those "empty" <span>s to show as spaces?
Here's a link with a live example of the problem if you want to check it out.
Update: Removing display:inline-block from the span elements makes the space show up. I can't remove it tho, since the transform animation stops working properly without it.

You can use the :empty pseudo selector and add a space via content in CSS;
span:empty{
content:' ';
display: inline-block;
}
<span>A</span>
<span></span>
<span>B</span>

You can use letter-spacing to remove white space between the text.
<!DOCTYPE html>
<html>
<head>
<style>
div.a {
width: auto;
border: 1px solid black;
letter-spacing:0px
}
div.b {
width: 150px;
border: 1px solid black;
}
div.c {
width: 50%;
border: 1px solid black;
}
</style>
</head>
<body>
<h1>The width Property</h1>
<h2>width: auto (default)</h2>
<div class="a">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam semper diam at erat pulvinar, at pulvinar felis blandit. Vestibulum volutpat tellus diam, consequat gravida libero rhoncus ut. Maecenas imperdiet felis nisi, fringilla luctus felis hendrerit sit amet. Pellentesque interdum, nisl nec interdum maximus, augue diam porttitor lorem, et sollicitudin felis neque sit amet erat.</div>
</body>
</html>

Related

Injecting text into a div

I'm trying to inject the ➕ emoji (acting as a button) next to each message on a website. Example:
This is what I'm currently doing:
contentscript.js:
document.getElementsByClassName("className").innerHTML = "➕";
This isn't showing anything. I also presume it won't show to the complete left; how can I do this?
If there is only one item in the DOM with the class name you want to add the item to you could do this
document.getElementsByClassName("className")[0].innerHTML += "➕";
Using the += operator will append the new value to the current value of the innerHTML
Otherwise you would have to loop over the collection of elements returned (see #Alex K comment above)
document.getElementsByClassName("className")[0].innerHTML += "<span class='icon'>➕</span>";
document.getElementsByClassName("icon")[0].addEventListener("click", clickFunction);
function clickFunction(){
alert("Clicked"+ this);
}
/* add whatever styles you need here */
.className {
position: relative;
padding-left: 20px;
}
.icon {
color: red;
position: absolute;
top: 0;
left: 0;
}
<div class="className">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam iaculis non quam non tristique. Cras ut imperdiet quam, pellentesque finibus nisl. Sed egestas dapibus turpis a rhoncus.</div>

Add a title property to elements with text-overflow: ellipsis

I am not sure if this is easily possible, but I thought I would ask just in case:
I am using the following CSS rules on a list of text:
{
width: 100px;
overflow: hidden;
text-overflow: ellipsis;
}
As expected, any text that goes outside the list will be truncated and have an ellipsis placed on the end.
I want to have an active title property for only those list items that trigger the text-overflow rule on the list. So you can hover the mouse over any text that is truncated and see a tooltip of its full text.
Something tells me this is difficult, if not impossible, to do. However I would love to be proven wrong. I am preferably looking for a solution that uses as little JavaScript as possible.
We use a similar, more generic ellipsify, which works perfectly for most cases. We also apply the title attribute (for all elements). Only applying the title if the element ellipsifies, is indeed difficult. The example below assumes that, if the element has the same width as the parent, we should set the title. Without the if statement it would always apply the title.
document.querySelectorAll('.ellipsify').forEach(function (elem) {
if (parseFloat(window.getComputedStyle(elem).width) === parseFloat(window.getComputedStyle(elem.parentElement).width)) {
elem.setAttribute('title', elem.textContent);
}
});
.ellipsify {
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
max-width: 100%;
display: inline-block;
}
div {
width: 100px;
}
<div>
<span class="ellipsify">dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna</span>
<span class="ellipsify">dolor sit amet</span>
</div>
This is how i approached the solution.
If you don't want to use java-script.
Here is a Link to fiddle: https://jsfiddle.net/fryc4j52/1/
SNIPPET:
.ellipse{
width: 100px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
margin:0;
padding:0;
}
.content li{
margin:0;
padding:0;
overflow:hidden;
}
.ellipse:hover{
width: auto;
border: 2px solid #eee;
box-shadow: 0px 3px 10px 0px black;
padding:2px;
white-space: normal;
word-break: break-word;
z-index:5;
}
<ul class="content">
<li class="ellipse">A very looooooooooooooooooooooooooooooooooooooong line.</li>
<li> Other text</li>
<li class="ellipse">A veryvvvvvvvvvvvvvvvvvvvvvvverrrrryyyyyyyyy looooooooooooooooooooooooooooooooooooooong line.</li>
</ul>
document.querySelectorAll('.ellipsis').forEach(function (e) {
if (e.offsetWidth < e.scrollWidth) {
e.setAttribute('title', e.textContent);
} else{
e.removeAttribute('title');
}
});
.ellipsis {
text-overflow: ellipsis;
display: inline-block;
max-width: 100%;
overflow: hidden;
white-space: nowrap;
}
You can measure for the presence of overflow with a little JavaScript and only add the title attribute if it the element would have overflowed (had it not been truncated).
Constrain the content with a style.
Copy the content into a hidden test element with the same width.
Don't limit wrapping on the test element, allowing it to overflow.
Compare the heights.
$(".smart-overflow").each(function() {
var elementToTest = $(this),
contentToTest = $(this).text(),
testElement = $("<div/>").css({
position: "absolute",
left: "-10000px",
width: elementToTest.width() + "px"
}).appendTo("body").text(contentToTest);
if (testElement.height() > elementToTest.height()) {
elementToTest.attr("title", contentToTest);
}
});
.smart-overflow {
width: 100px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="smart-overflow">
short text
</div>
<div class="smart-overflow">
short text
</div>
<div class="smart-overflow">
Longer text; there should be a tooltip here.
</div>
<div class="smart-overflow">
More long text. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum vestibulum lorem eget justo tempus posuere. Integer ac sagittis nisi. Phasellus eu malesuada sapien. Aliquam erat volutpat. Nunc aliquet neque sagittis eros ullamcorper,
blandit facilisis magna gravida. Nulla a euismod turpis.
</div>
<div class="smart-overflow">
More long text. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum vestibulum lorem eget justo tempus posuere. Integer ac sagittis nisi. Phasellus eu malesuada sapien. Aliquam erat volutpat. Nunc aliquet neque sagittis eros ullamcorper,
blandit facilisis magna gravida. Nulla a euismod turpis.
</div>
<div class="smart-overflow">
short text
</div>
<div class="smart-overflow">
short text
</div>
jQuery used here for conciseness, but certainly not required.

only first FAQ element expands on click - jquery

I'm trying to create an FAQ list. The answer displays fine on first click but I want to be able to click on another question and have that answer expand and the other close. Here's the javascript:
$(document).ready(function() {
// hide all the answers
$('.faq li div').hide();
$('.faq li').click(function(){
var question = $(this);
var answer = $(this).find('div');
// if the faq isn't active
if(!$('.faq li').hasClass('active')) {
answer.slideDown();
$(this).siblings('div').slideUp();
question.addClass('active');
}
else {
answer.slideUp();
question.removeClass('active');
}
});
});
The CSS:
ul.faq {
list-style:none;
cursor:pointer;
z-index:1;
}
ul.faq li h3 {
background:#0A5C75 url(../images/faq-inactive.png) right no-repeat;
color:#fff;
padding:20px 50px 20px 10px;
margin-bottom:10px;
border:1px solid #fff;
}
ul.faq li.active h3 {
background:#0A5C75 url(../images/faq-active.png) right no-repeat;
}
ul.faq li div {
background:#FFFFFF;
margin:0px 10px 10px 10px;
padding:20px;
overflow:hidden;
/* added fixed width to stop the jerkyness*/
width:522px;
position:relative;
top:-10px;
box-shadow: inset 0px 4px 4px 0px rgba(63, 70, 76, 0.15), 0px 4px 4px rgba(63, 70, 76, 0.15);
}
and the HTML
<ul class="faq">
<li>
<h3>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut arcu magna, sodales vel dignissim pharetra, adipiscing sed orci?</a></h3>
<div>Vivamus rutrum arcu sit amet dolor pulvinar dictum. Etiam porttitor leo eget velit volutpat quis ultricies urna ornare. Quisque ac ultrices est. Ut lobortis malesuada justo, sed blandit sapien bibendum et. Donec vel ante eu orci pellentesque dictum. Phasellus molestie egestas du</div>
</li>
<li>
<h3>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut arcu magna, sodales vel dignissim pharetra, adipiscing sed orci?</a></h3>
<div>This is the answer to question 2</div></li>
<li>
<h3>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut arcu magna, sodales vel dignissim pharetra, adipiscing sed orci?</a></h3>
<div>This is the answer to question 3</div>
</li>
</ul>
I think I could improve on your code a bit and produce the behavior and also shorten the code by a fair bit.
Notice, I skipped using your active class in order to show how it could be achieved.
Here's a tinker.io for demo I tested it in FF13 and Chrome
$('.faq li div').hide();
$('.faq li').click(function(event) {
var clickedQuestion = event.target;
var answer = $(clickedQuestion).siblings('div');
if($('ul.faq').find('div').is(':visible')){
$('ul.faq').find('div').slideUp();
}
answer.slideDown();
});
Working demo http://jsfiddle.net/e3Bec/ OR http://jsfiddle.net/XGJXM/
Your code is fine only thing is use ==> if (!$(this).hasClass('active')) { instead of if(!$('.faq li').hasClass('active')) { :) Also you don't need this in your first conditional check question.addClass('active');
Rest code should help, :)
code
$(document).ready(function() {
// hide all the answers
$('.faq li div').hide();
$('.faq li').click(function() {
$('div').slideUp();
var question = $(this);
var answer = $(this).find('div');
// if the faq isn't active
if (!$(this).hasClass('active')) {
answer.slideDown();
$(this).siblings('div').slideUp();
//question.addClass('active');
}
else {
answer.slideUp();
question.removeClass('active');
}
});
});​
I like that you are not sliding up the element if it is already visible.
Maybe move the .hide into css "display:none", no point waiting for the dom to load to hide them.
$(document).ready(function() {
$('.faq li').click(function(event){
$(this).find('div').not(":visible").slideDown();
$('.faq li div:visible').not($(this).find('div')).slideUp();
});
});
Why not use a Accordion. http://jqueryui.com/demos/accordion/

jquery - setting dynamic equal height of a floated div

I have 2 div containers, one navigation on the left, one content right to that:
#leftnav_static
{
padding:5px;
margin-top: 5px;
margin-left: 5px;
height: 1000px;
width: 195px;
font-size: 1.35em;
float:left;
background-image: url('pagenav.jpg');
}
#content_dynamic
{
margin-top: 5px;
margin-left: 215px;
height: auto;
width: 700px;
padding: 5px;
background-image: url('pagenav.jpg');
font-size: 1em;
line-height:1.6em;
white-space:nowrap;
}
Now I want to set leftnav to the same height as content (no faux columns if possible):
$('#leftnav_static').height($("#content_dynamic").height());
or
$('#leftnav_static').innerHeight($("#content_dynamic").innerHeight());
dont seem to work.
any suggestions as to why that is?
It does work. See this jsfiddle.
Are you running the code in a jQuery ready block? Also, if you want to maintain this height relationship through text size changes from browser 'zooms', you will need to respond to resize events. If at some point you make your content_dynamic div have a width of auto, you will also need to resize the sidebar div when the height of the content_dynamic div changes (again, by responding to a resize event).
jQuery only allows you to attach to a resize event at the window level, but there are plugins that ease translating that to a div level resize event.
HTML:
<div id="leftnav_static"></div>
<div id="content_dynamic">Lorem ipsum dolor sit amet,
consectetur adipiscing elit. Etiam iaculis ornare
sapien sit amet condimentum. Aliquam a diam vel eros
tristique fermentum vitae at turpis. Etiam fringilla,
enim nec viverra interdum, metus tortor vehicula mauris,
in luctus felis massa ut nulla. Proin et leo vel nunc ornare
pulvinar. Vestibulum quis lectus vel arcu tristique aliquet.
Fusce malesuada nisi non ante egestas semper.
</div>
CSS:
#leftnav_static {
padding:5px;
margin-top: 5px;
margin-left: 5px;
height: 1000px;
width: 195px;
font-size: 1.35em;
float:left;
background-color: blue;
}
#content_dynamic {
margin-top: 5px;
margin-left: 215px;
height: auto;
width: 700px;
padding: 5px;
background-color: red;
font-size: 1em;
line-height:1.6em;
//white-space:nowrap; //This makes the content div only one line,
//I commented this out to make the sizing clear.
}
JavaScript: (Assuming that the jQuery library is already loaded)
$(function() {
$('#leftnav_static').height($("#content_dynamic").height());
});
Note: The benefit of a faux columns or other pure CSS approaches is that you don't need to worry about zooming or resizes as much--and your site would work for people that have JavaScript turned off.
You have to understand that you are manipulating CSS attributes.
var myHeight = $("#content_dynamic").css("height");
$('#leftnav_static').css({"height": myHeight});
should do the trick.
Add display block to #leftnav_static
#leftnav_static
{
display: block;
}
...and this will work
$(document).ready(function() {
$('#leftnav_static').height( $('#content_dynamic').height() );
});
See my example; http://jsfiddle.net/D3gTy/

JavaScript animate resizing div

I'm trying to put a small animation on a page. I've got 2 divs side by side, the second of which has its content called via Ajax, so the div height varies without page refresh.
<div id="number1" style="float:left; padding-bottom:140px">Static content, 200px or so</div>
<div id="number2" style="float:left">AJAX content here</div>
<div style="clear:left"></div>
<img src="image" margin-top:-140px" />
This basically gives me a 2 column layout, and the image nests up underneath the left hand column no matter what the height. All good!
The thing I'm trying to do though is animate the transition of the image when the page height changes thanks to incoming Ajax content. At present the image jerks around up and down, I'd quite like to have it smoothly glide down the page.
Is this possible? I'm not really into my JavaScript, so I'm not sure how to do this. I'm using the jQuery library on the site, so could that be a way forward?
OK, I've just put together a very quick and dirty example.
Here's the HTML:
<body>
Add content
<div id="outerContainer">
<div id="left" class="col">
<p>Static content</p>
<img src="images/innovation.gif" width="111px" height="20px">
</div>
<div id="right" class="col">
<p>Ajax content</p>
</div>
</div>
</body>
The jQuery used is here
jQuery(function($){
var addedHTML = "<p class='added'>Lorem ipsum dolor sit amet, Nunc consectetur, magna quis auctor mattis, lorem neque lobortis massa, ac commodo massa sem sed nunc. Maecenas consequat consectetur dignissim. Aliquam placerat ullamcorper tristique. Sed cursus libero vel magna bibendum luctus. Nam eleifend volutpat neque, sed tincidunt odio blandit luctus. Morbi sit amet metus elit. Curabitur mollis rhoncus bibendum. Phasellus eget metus eget mi porttitor lacinia ac et augue. Nulla facilisi. Nam magna turpis, auctor vel vehicula vitae, tincidunt eget nisl. Duis posuere diam lacus.</p>";
$("#addContent").click(function(e){
$("#right").append(addedHTML);
var rightHeight = $("#right").height();
//Animate the left column to this height
$("#left").animate({
height: rightHeight
}, 1500);
});});
And CSS:
#outerContainer {
position: relative;
border: 1px solid red;
margin: 20px auto 0;
overflow: hidden;
width: 400px;}
.col {
width: 180px;
display: inline;
padding: 0 0 40px;}
#left {
float: left;
border: 1px solid cyan;
position: relative;}
#left img {
position: absolute;
bottom: 0;
left: 0;}
#right {
position: absolute;
top: 0;
left: 180px;
border: 1px solid green;}
#addContent {
text-align: center;
width: 100px;
margin: 20px auto 0;
display: block;}
I have added a button just to add some 'Ajax' content. When you do this it grabs the new height of the div and animates to that height. You could add some easing to the animation / change the speed to make it a little more polished.
I hope this helps.
Maybe you could use a container around the content divs (with overflow hidden) and resize that one according to the height of the contents, thus achieving what you're trying to do?
I agree with the answer above. You could apply the image as a background image to the container then animate the container. That way the background image will move down with the container (assuming you anchor it to the bottom that is!)

Categories

Resources