I am trying to move an image across the page using a random number that will affect how much the image will move. I got the random number to display so I know the number is generating but my image won't move at all.
Below is the html, javascript, and css that I have used:
http://jsbin.com/bodajisihu/1/edit?html,css,js,output
http://jsbin.com/begafabuya/1/edit?html,css,js,output
Please check this edited JSBin.
I made following changes:
1. You were trying to get left value as car1.style.left, which doesn't work for an image if you have defined left in external style. You needed to make it inline.
2. Now, you can use car1.style.left, but still it returns a string with 'px' appended to it, so I replaced that using .replace("px", ""). But I think parseInt alone could take care of truncating that bit, so this point may not matter
Please note here that car1 is reference to the car element i.e. var car1 = document.getElementById('car1');.
You misspelled the function name. There's an "s" in "moveCars"
Related
My JavaScript slider worked fine in the beginning and then it get corrupted after time, sometimes it takes one minutes, sometimes it takes five.
Actually I don't know if it is a conflict or what, could you please help me guys?
you can check it out here: http://test-code.bugs3.com/
When looking at the code it seems you do not yet have much web development skills. That is fine, and thereby I will go through each step of improving your webpage, as I want you to become a great developer too.
First, lets start with some CSS things. Instead of setting the padding for every side, you can also set it on all sides without needing four lines. Simply using padding:0; is enough in this case. For the margin, when you want the left and right sides to be auto, and the top and bottom 0px, you can 'chain' them in one property: margin:top right bottom left;, like a clock. Even shorter is margin:top&bottom left&right;, which in your case is margin:0 auto; <-- the top and bottom have 0 margin and the sides have auto margin. (btw if something is 0 you don't need to add a unit to it).
For a border I found this:
border: solid;
border-width: thick;
border-color: #E6E6E6;
You can also put that together by using border:thick solid #E6E6E6;
Now for the javascript. The problem that it is slow is because it uses a lot of timers and intervals to do things, and the timers do not get cleared well. My opacity is currently at -850. Instead of improving the code I suggest we rewrite it. You have written the same code over and over again for every picture, where only some variable names differ. What if we just write that code once? Would be a lot faster. And we could add as many pictures as we want.
To be able to instantly get a list of all the picture elements, I add a class to them: class="sliderPicture". Now when I want the list I can call document.getElementsByClassName('sliderPicture'); and there we have our array (I removed the ID's as we won't need em). We also need a variable to keep track of at which picture we are right now. I will elaborate on this later.
As we do not want the animation to be done by using javascript but just by using CSS, we are going to add some css code to the sliderPicture class:
.sliderPicture {
opacity:0; /*We want all images to be transparent, as we override this value when we want to display the picture*/
position:absolute; /*this puts all the pictures in the same place behind eachother, so that we do not need to display:none; and display:block; them*/
transition:2s opacity; /*this means, every time the opacity of the element changes, do not directly set it to that opacity but fade to it in 2 seconds*/
}
Now we create a class which will show the images. The script then only needs to add/remove the class:
.showPicture{
opacity:1;
}
Now on to the javascript code. It is pretty short, and I hope the comments explain good enough:
var images = document.getElementsByClassName('sliderPicture'); //this contains an array of all the images.
var imageTime = 3000; //the time in ms for when the pictures should change
var i = 0; //the picture we are at
setInterval(function(){
if(images[i].classList.contains('showPicture')) images[i].classList.remove('showPicture'); //if the element contains the class showPicture, remove it. (we first check for it to not generate errors when removing something that might not be there (it should, but never create any room for errors))
i++; //increment the image where we are at
if(i >= images.length) i=0; //if we are at the end of our array. Picture 2 of the array is the last picture, so, as we increment it above, our i value should be 3 then. The length of our array is also 3, so when i=length of the array we set it back to 0 to display the image
images[i].classList.add('showPicture'); //here we add the class so the element gets opacity 1
}, imageTime);
as we want the first picture to directly show up we just add showPicture to its class.
I also see nice buttons on the bottom. I think you want them to automatically switch to the picture. I can help you with automatically generating buttons to not have to bother about adding them manually.
Furthermore, if this slider is to display many different images, you can also write a little script to add the images from an array containing the url's. Then you don't need to add <img class="sliderPicture" src="..." /> every time, but let the javascript generate that for you (including generating the buttons.
All this code is combined in this jsfiddle.
If you have a question, any at all, feel free to ask them. I hope you enjoyed reading this answer and have a better understanding on how to combine css and javacript to generate nice webpages.
old:
this looks like a problem with all the intervals and clearing of things. your code does even look like it can be made much simpeler, as you are using timers to fade things, instead of css. For this fading you can use transitions. For the condition code, you'd better use an array and take the next item from it (or 0 if there is no next item).
I have an UIWebView with a huge book in it. I'm changing it's font size via javascript, using "document.getElementsByTagName('body')[0].style.webkitTextSizeAdjust='150%';
Html-page gets larger, but the scroll position remains the same, causing text to shift out of a users sight.
The only idea that I have, is really weird and inefficient:
Wrap every word in <span> tags;
find the first onscreen <span> and remember it's id;
resize font;
scroll to span, that I've found in step 2.
Is there a better way to preserve the position, that user was reading?
Finally I've found an acceptable way:
Before changing font size I use a little javascript to find and store a position of a first letter on a page:
var range = document.caretRangeFromPoint(0,0); // get a range of a first onscreen letter
var textContainer = range.startContainer.parentNode;// get an element to which it belongs
var path = getElementXPath(textContainer); // get an XPath for that element (this function is not biult in, but you can find it in some other question)
path+='|'+range.startOffset; // stick XPath and index of the letter together
After that I change the font size, find needed element by XPath, insert invisible <a> right before my letter, scroll to that invisible <a>, don't forget to remove it.
Done. That is not a stragihtforward idea, but at least it works and does not consume to much of CPU or RAM, like the idea that I'have explained in original question.
Here is the place to get getElementXPath() function
edit:
The problem seems to be that the font size isnt explicitly set and is set by the css class only. so style.fontSize always returns an empty string
if there another way to return the font size?
var allMainFrameElems = parent.main.document.getElementsByTagName('*');
for (i=0; i < allMainFrameElems.length; i++){
if(allMainFrameElems[i].style.fontSize != null){
alert(llMainFrameElems[i].style.fontSize);
}
}
If the fontSize style in not explicitly set on an element (e.g. <p style="font-size:12pt;">...</p>), you won't be able to get it from anywhere. Font-sizes are most often set in your CSS classes, which are not reachable from your element's properties, and the elements do not have any font-size related properties.
In order to even come close to doing this you will need to do some tricks and will not be able to definatively determine font size. Basically you will have to manipulate the page a great deal on every element (not good) just to determine this.
See this fiddle page, especially the pixelPerEm function I tossed together very quickly. http://jsfiddle.net/MarkSchultheiss/vc8Zy/
It is not very clean at the moment and IF I get time I might try to make it better but it might give you something to start with even if it is NOT very pretty.
EDIT: basic explanation is to utilize the em css, inject an element with a known setting, calculate the pixel offset on the injection and then remove the injected element. None of that is pretty and all of it is error/bug prone or has potential for issues.
I want to, using JavaScript, chop the given text to fit the object in which the text resides and add "..." at the end.
For example:
JavaScript got data from 3rd party web service and needs to put the text into 200 x 300 px div. Text's length vary, so let's say it will take much more space than provided.
How to determine at which point text will break through the border and prevent that by chopping text and adding "..." at the end?
There are several jQuery plugins that can do this.
If you don't mind using the canvas element, it can be used to measure the width of the text. Here's an example:
http://uupaa-js-spinoff.googlecode.com/svn/trunk/uupaa-excanvas.js/demo/8_2_canvas_measureText.html
ruzee.com has a solution that uses prototype.js and a small bit of code [MIT licensed] to do what you want; demo
You may also want to look into the CSS 3 property text-overflow which also does this.
http://www.w3.org/TR/2001/WD-css3-text-20010517/#text-overflow-props
It's possible to check if the browser supports it, so you always can add a JavaScript fall back.
if (!'textOverflow' in document.createElement('div').style) {
// Use JavaScript solution here
}
I have a table column that needs to be limited to a certain width - say 100 pixels. At times the text in that column is wider than this and contains no spaces. For example:
a_really_long_string_of_text_like_this_with_no_line_breaks_makes_the_table_unhappy
I would like to calculate the width of text server-side and add an ellipsis after the correct number of characters. The problem is that I don't have data about the rendered size of the text.
For example, assuming the browser was Firefox 3 and the font was 12px Arial. What would be the width of the letter "a", the width of the letter "b", etc.?
Do you have data showing the pixel width of each character? Or a program to generate it?
I think a clever one-time javascript script could do the trick. But I don't want to spend time re-inventing the wheel if someone else has already done this. I am surely not the first person to come up against this problem.
How about overflow: scroll?
Ext JS has a module to do just that
TextMetrics
Provides precise pixel measurements
for blocks of text so that you can
determine exactly how high and wide,
in pixels, a given block of text will
be.
I am sure that there are other libraries available out there that do it as well.
This would not only be impossible to do server-side, it would also not make sense. You don't what browser your client will be using, and you don't know what font settings on the client side will override whatever styling information you assign to a piece of HTML. You might think that you're using absolute positioning pixels in your style properties, but the client could simply be ignoring those or using some plugin to zoom everything because the client uses a high-dpi screen.
Using fixed widths is generally a bad idea.
Very very hard to do server-side. You can never know what fonts users have installed, and there are many things that affect the display of text.
Try this instead:
table-layout: fixed;
That'll make sure the table is never larger than the size you specified.
Here is my client-side solution that I came up with. It is pretty specific to my application but I am sharing it here in case someone else comes across the same problem.
It works a bit more quickly than I had expected. And it assumes the contents of the cells are text only - any HTML will formatting will be erased in the shortening process.
It requires jQuery.
function fixFatColumns() {
$('table#MyTable td').each(function() {
var defined_width = $(this).attr('width');
if (defined_width) {
var actual_width = $(this).width();
var contents = $(this).html();
if (contents.length) {
var working_div = $('#ATempDiv');
if (working_div.is('*')) {
working_div.html(contents);
} else {
$('body').append('<div id="ATempDiv" style="position:absolute;top:-100px;left:-500px;font-size:13px;font-family:Arial">'+contents+'</div>');
working_div = $('#ATempDiv');
}
if (working_div.width() > defined_width) {
contents = working_div.text();
working_div.text(contents);
while (working_div.width() + 8 > defined_width) {
// shorten the contents of the columns
var working_text = working_div.text();
if (working_text.length > 1) working_text = working_text.substr(0,working_text.length-1);
working_div.text(working_text);
}
$(this).html(working_text+'...')
}
working_div.empty();
}
}
});
}
This is essentially impossible to do on the server side. In addition to the problem of people having different fonts installed, you also have kerning (the letter "f" will take up a different amount of space depending on what is next to it) and font rendering options (is cleartype on? "large fonts"?).
There's nothing you can do server-side to calculate it. All you have to work with is the browser identification string, which may or may not tell you the user's operating system and browser accurately. You can also "ask" (via a font tag or CSS) for a certain font to be used to display the text but there's no guarantee that the user has that font installed. Beyond that the user could have a different DPI setting at the operating system level, or could have made the text bigger or smaller with the browser zoom function, or could be using their own stylesheet altogether.
You could put the text into an invisible span and read that spans width, but basicly this looks like someone trying to sabotage your site, and therefore I would recommend banning posts with words longer than a certain lenth, for example 30 characters without spaces (allowing links to be longer !-)
-- but the simple approach is to put a block-element inside the table-cell:
<td><div style="width:100px;overflow:hidden">a_really_long_string_of_text_like_this_with_no_line_breaks_makes_the_ta ... </div></td>
This will effectively stop the table-cluttering !o]
If you're ok with this not working for FireFox, why not just use CSS? Have the table with table-layout:fixed, have the column in question have overflow:hidden;text-overflow:ellipsis; white-space:nowrap.
http://www.css3.info/preview/text-overflow/
This is a new function of css3.
Some users have larger or smaller default font settings. You can't do this on the server. You can only measure it once the browser has rendered the page.
Since font size can be easily changed on the browser side, your server-side calculation is made invalid very easily.
A quick client side fix would be to style your cells with an overflow attribute:
td
{
overflow: scroll; /* or overflow: hidden; etc. */
}
A better alternative is to truncate your strings server side and provide a simple javascript tooltip that can display the longer version. An "expand" button may also help that could display the result in an overlay div.
What you want is the <wbr> tag. This is a special HTML tag that tells the browser that it is acceptable to break a word here if a wrap is necessary. I would not inject the into the text for persistent storage because then you are coupling your data with where/how you will display that data. However, it is perfectly acceptable to inject the tags server side in code that is view-centric (like with a JSP tag or possibly in the controller). That's how I would do it. Just use some regular expression to find words that are longer than X characters and inject this tag every X characters into such words.
Update: I was doing some looking around and it looks like wbr is not supported on all browsers. Most notably, IE8. I haven't tested this myself though. Perhaps you could use overflow:hidden as a backup or something like that.