Automatically change image-url by 1 for next div? - css

I'm making a bunch of stacked divs that will expand when moused-over to show an image, but I have a lot of images.
Is there a way in CSS or JS (I don't really know anything about JS) to have each div automatically use the next image in a folder? ex: the images are named map1.jpg, map2.jpg ... map91.jpg. and be able to use the same background-image:url but have something telling it to add 1 to the next image for each new div so I don't have to manually specify 90+ different images.
I hope I was able to explain that well enough. Thanks =)

In CSS this is impossible, cause you can't concatenate the url path for background-image.
in javascript this is pretty simple, using jQuery you can simply load all div you need when body is ready:
// on page load
$(document).ready(function(){
// 10 images to div #image-board
for(var i=0; i<10; i++){
// create a div with image #i
$('#image-board').append('<div><img src="my/collection/folder/Image'+i+'.jpg"></div>');
}
});
don't forget to create in your HTML page a <div id="image-board"></div> where all images will be listed to

I'll try to include lots of detail since you say you're unfamiliar with JavaScript. When you say stacked divs, I assume you mean one inside another. Start with a div with appropriate id and background in your html <div id="div0" style="background-image:url('map0.jpg')"></div> Here's some Javascript using jQuery (a very common javascript library you can include with a script tag) that will add a new div inside your first div with the updated url name.
for (var i = 0; i < number_of_images - 1; i++) {
var oldId = '#div' + i;
var newId = 'div' + (i + 1);
var newUrl = 'map'+(i+1)+'.jpg';
var newdiv = '<div id="' + newId + '" style="background-image:url('+newUrl+')></div>';
$(oldId).append(newdiv);
}
The for loop will go over every image, then a string is created in a series of concatenations that becomes your updated div. The '$' searches for the DOM element with that id, then adds the new div inside it. If by stacked you meant a new div underneath but not contained by the previous div, use .insertAfter instead of .append. Assuming your webpage can reach all of the images, this should work. Also notice I've 0 indexed this (the standard in Javascript) but your question referred to map1 as the first map. If you have already named these maps, you may need to re-index the for loop to 1.

Related

Dots in the middle of the row by CSS or JavaScript

Could you please help me to achieve layout as in this example?
Sample items in this list loads dynamically into view and length can be various. And it seems like the count of dots should change according to this. I try to use <table> element but it only I can set is dotted border to bottom and this is not my case because I need it in the middle of the row.
You could make the dots a vertically centered background for the TD. The content itself has a white background, so that the dots are hidden under the text.
Example here:
http://jsfiddle.net/willemvb/QkEzr/
Here is what you could do in a quick and easy way with just CSS. Just create three blocks(div's). And give a bottom border to the middle div. Then move it's position a bit higher(margin-top with a negative value). I guess that's what you needed.
If you're using table, then no problem. Just add another div inside the second column. And add the bottom border as I said above. And move the div upper. Simple.
Here's a javascript solution. The idea is to set the font to monospace, and then place dots depending on the number of characters in a given row relative to the max number of characters in the samples column.
var samplePts = new Array( new Array("Sample",23), new Array("Longer Sample",9), new Array("Much Londer Sample",125) );
var maxSampleLen = 0;
for (var i=0; i<samplePts.length; i++){
var currLen = samplePts[i][0].length;
if (currLen > maxSampleLen){
maxSampleLen = currLen;
}
}
for (var i=0; i<samplePts.length; i++){
var outputStr = "<div style='font-family: monospace;'>"+samplePts[i][0];
for (var n=0; n<maxSampleLen-samplePts[i][0].length+5; n++){
outputStr += "ยท";
}
outputStr += samplePts[i][1]+"</div>";
document.write(outputStr);
}

Last line of a paragraph contains a single word only [duplicate]

This question already has answers here:
Widow/Orphan Control with JavaScript?
(7 answers)
Closed 8 years ago.
A common problem when working with typography in HTML/CSS is something we call "horunge" in Swedish ("widow" in english).
What it is:
Let's say you have a box with a width of 200px and with the text "I love typograpy very much". Now the text breaks and becomes:
I love typography very
much
As a designer I don't want a word bastard (single word / row). If this was a document/PDF etc. I would break the word before very and look like this:
I love typography
very much
which looks much better.
Can I solve this with a CSS rule or with a javascript? The rule should be to never let a word stand empty on a row.
I know it can be solved by adding a <br /> but that's not a solution that works with dynamic widths, feed content, different translations, browser font rendering issues etc.
Update (solution)
I solved my problem with this jquery plugin: http://matthewlein.com/widowfix/
A simple jQuery / regrex solution could look like the following, if you add the class "noWidows" to the tag of any element that contains text you are worried about.
Such as:
<p class="noWidows">This is a very important body of text.</p>
And then use this script:
$('.noWidows').each(function(i,d){
$(d).html( $(d).text().replace(/\s(?=[^\s]*$)/g, " ") )
});
This uses regex to find and replace the last space in the string with a non-breaking character. Which means the last two words will be forced onto the same line. It's a good solution if you have space around the end of the line because this could cause the text to run outside of an element with a fixed width, or if not fixed, cause the element to become larger.
Just wanted to add to this page as it helped me a lot.
If you have (widows) actually should be orphans as widows are single words that land on the next page and not single words on a new line.
Working with postcodes like "N12 5GG" will result in the full postcode being on a new line together but still classed as an orphan so a work around is this. (changed the class to "noWidow2" so you can use both versions.
123 Some_road, Some_town, N12 5GG
$('.noWidows2').each(function(i,d){
var value=" "
$(d).html($(d).text().replace(/\s(?=[^\s]*$)/g, value).replace(/\s(?=[^\s]*$)/g, value));
});
This will result is the last 3 white spaces being on a new line together making the postcode issue work.
End Result
123 Some_road,
Some_town, N12 5GG
I made a little script here, with the help of this function to find line height.
It's just an approach, it may or may not work, didn't have time to test throughly.
As of now, text_element must be a jQuery object.
function avoidBastardWord( text_element )
{
var string = text_element.text();
var parent = text_element.parent();
var parent_width = parent.width();
var parent_height = parent.height();
// determine how many lines the text is split into
var lines = parent_height / getLineHeight(text_element.parent()[0]);
// if the text element width is less than the parent width,
// there may be a widow
if ( text_element.width() < parent_width )
{
// find the last word of the entire text
var last_word = text_element.text().split(' ').pop();
// remove it from our text, creating a temporary string
var temp_string = string.substring( 0, string.length - last_word.length - 1);
// set the new one-word-less text string into our element
text_element.text( temp_string );
// check lines again with this new text with one word less
var new_lines = parent.height() / getLineHeight(text_element.parent()[0]);
// if now there are less lines, it means that word was a widow
if ( new_lines != lines )
{
// separate each word
temp_string = string.split(' ');
// put a space before the second word from the last
// (the one before the widow word)
temp_string[ temp_string.length - 2 ] = '<br>' + temp_string[ temp_string.length - 2 ] ;
// recreate the string again
temp_string = temp_string.join(' ');
// our element html becomes the string
text_element.html( temp_string );
}
else
{
// put back the original text into the element
text_element.text( string );
}
}
}
Different browsers have different font settings. Try to play a little to see the differences. I tested it on IE8 and Opera, modifying the string every time and it seemed to work ok.
I would like to hear some feedback and improve because I think it may come in handy anyway.
Just play with it! :)
There are also CSS widows and orphans properties: see the about.com article.
Not sure about browser support...
EDIT: more information about WebKit implementation here: https://bugs.webkit.org/buglist.cgi?quicksearch=orphans.
Manually, you could replace the space in between with
I've been looking for ways to dynamically add it in. I found a few, but haven't been able to make it work myself.
$('span').each(function() {
var w = this.textContent.split(" ");
if (w.length > 1) {
w[w.length - 2] += " " + w[w.length - 1];
w.pop();
this.innerHTML = (w.join(" "));
}
});
#foo {
width: 124px;
border: 1px solid #ccc;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="foo">
<span class="orphan">hello there I am a string really really long, I wonder how many lines I have</span>
</div>

CSS: overflow-y: scroll; overflow-x: visible

See the following post for a picture highlighting my question and a potential solution:
CSS overflow-y:visible, overflow-x:scroll
However, this strategy breaks when you actually move the scrollbar. In the suggested implementation (position: fixed;), the tooltips display next to child div in its position pre-scroll. So, as you scroll new child-divs into view, the tooltips begin falling off the bottom of the page.
See here for a demo of the bug: http://jsfiddle.net/narcV/4/
Any ideas how I can make the tooltips display next to the child div at all times?
I ended up implementing this using javascript, using the getPos function from this question.
The end product looks like:
var scrollPanel = ...;
var tooltip = ...;
function nodeHovered(e) {
var hovered = e.srcElement;
var pos = getPos(hovered);
pos.x += hovered.offsetWidth;
pos.y -= scrollPanel.scrollTop;
tooltip.style.setProperty('left', pos.x);
tooltip.style.setProperty('top', pos.y);
}
Basically, I calculate where on the page the node is currently displayed (taking into account the scrollbar position), and manually place the tooltip in the right spot on the page.
Too bad there's no elegant/CSS way to do this, but at least this works.

is it even possible to expand a (horizontal) list's background with ajax?

I've got a list with list-style-none which needs to be able to add new items to itself via Ajax and have the background expand appropriately when it does. Adding via Ajax is easy, but every solution I try for the background fails me. I don't know if it's even possible; is it? I'm using a grid like this one:
http://jqueryui.com/demos/sortable/#display-grid
Both WebKit and Firebug are showing me skinny, empty bars when I hover over the enclosing divs and/or the enclosing ul tag. It appears that the minute you set a list loose with list-style-none and float:wherever, you give up control over its background. But that can't be right.
This is something I've run into a number of times. The problem is that floated elements aren't part of the normal box model, so they don't cause their parent elements to expand unless their parent elements are also floated. So if possible, float the ul or containing div.
Edit:
See quirksmode for another css-only workaround.
Could you provide a sample of your code? Also, why does the list have display:none set?
For instance, should be as simple as this:
HTML:
<ul id="dest"></ul>
JS:
// Simplified example, most likely wrapped in $.ajax
// This is the AJAX response function
function(data, response) {
var items = json.parse(data);
$.each(items, function() {
// Assumes item has a name property
$('#dest').append($('<li>' + this.name + '</li>'));
});
}
Should be just that simple. You shouldn't need the hide the list initially, as you can simply append list items and have the display update appropriately.
Hope that helps.
You need to explicitly set the width and height for the area.
Check out this link for Horizontal Scrolling: http://valums.com/scroll-menu-jquery/
Here is the script:
$(function(){
//Get our elements for faster access and set overlay width
var div = $('div.sc_menu'),
ul = $('ul.sc_menu'),
// unordered list's left margin
ulPadding = 15;
//Get menu width
var divWidth = div.width();
//Remove scrollbars
div.css({overflow: 'hidden'});
//Find last image container
var lastLi = ul.find('li:last-child');
//When user move mouse over menu
div.mousemove(function(e){
//As images are loaded ul width increases,
//so we recalculate it each time
var ulWidth = lastLi[0].offsetLeft + lastLi.outerWidth() + ulPadding;
var left = (e.pageX - div.offset().left) * (ulWidth-divWidth) / divWidth;
div.scrollLeft(left);
});
});
Basically, you need to update the ulWidth and divWidth when you add the new item.
Then just set the background image to repeat horizontally and you should be set.
ul.sc_menu {background:transparent url(image.png) repeat scroll 0 0;height:100px}
Note: You will need to set the height; otherwise you will not see the background because the li are floated.
For dealing with the float element, maybe you should know it's characteristic, gotcha, and how to deal with it.
See the links below, it also have demo, so you can understand the concept:
http://www.smashingmagazine.com/2009/10/19/the-mystery-of-css-float-property/
http://www.smashingmagazine.com/2007/05/01/css-float-theory-things-you-should-know/
http://aloestudios.com/2009/12/goodbye-overflow-clearing-hack/
and
http://aloestudios.com/misc/overflow/

Autosize Text Area (Multiline asp:TextBox)

I have a MultiLine asp:Textbox (a standard html textarea for those non-asp people) that I want to be auto-sized to fit all it's content only through css. The reason for this is that I want it to be of a specified height in the web browser, with scrolling enabled.
I have implemented a print style sheet however and want all text located in the textarea to be displayed when printed with no overflow hidden.
I can manually specify the height of the textarea in the print.css file problem with this being that the fields are optional and a 350px blank box is not optimal and there is always the possibility of a larger amount of text than this...
I have tried using :
height: auto;
height: 100%;
In IE and Firefox respectively yet these seem to be overridden by the presence of a specified number of rows in the html mark-up for the form which must be generated by .NET when you do not specify a height on the asp:Textbox tag, this seems to only accept numercial measurements such as px em etc...
Any ideas?
What you are asking for (a css solution) is not possible.
The content of the textarea is not html elements, so it can not be used by css to calculate the size of the textarea.
The only thing that could work would be Javascript, e.g. reading the scrollHeight property and use that to set the height of the element. Still the scrollHeight property is non-standard, so it might not work in all browsers.
jQuery or a javascript function to find and make textboxes bigger might be the best solution - at least thats what i found
we use this set of functions and call clean form after the page is loaded (i know this isnt the best solution right here and am working to transfer to a jQuery solution that is more elegant) - one note make sure your textareas have rows and cols specified or it doesnt work right.
function countLines(strtocount, cols)
{
var hard_lines = 1;
var last = 0;
while (true)
{
last = strtocount.indexOf("\n", last + 1);
hard_lines++;
if (last == -1) break;
}
var soft_lines = Math.round(strtocount.length / (cols - 1));
var hard = eval("hard_lines " + unescape("%3e") + "soft_lines;");
if (hard) soft_lines = hard_lines; return soft_lines;
}
function cleanForm()
{
var the_form = document.forms[0];
for (var i = 0, il = the_form.length; i < il; i++)
{
if (!the_form[i]) continue;
if (typeof the_form[i].rows != "number") continue;
the_form[i].rows = countLines(the_form[i].value, the_form[i].cols) + 1;
}
setTimeout("cleanForm();", 3000);
}
If you set rows to be a ridiculously high number the CSS height rule should override it on the screen.
Then in the print stylesheet just set height to auto. This might result in some big blank space where all the available rows haven't been filled up, but at least all text will be visible.
give jQuery's autogrow() a go #
http://plugins.jquery.com/project/autogrow

Resources