Why do I have so much lag? - javascript

I have been working on this new website but the "buttons" I am using are causing a ton of lag, I would like to remove the lag if possible.
The website is here: http://lano-project.org/
The troubled code is here:
<td>
<a href="templink-info.html">
<img style="display: none" src="images/icons/hover-info.png"/>
<img src="images/icons/info.png"
onmouseover="this.src='images/icons/hover-info.png';
document.getElementById('home_text').style.display = 'none';
document.getElementById('info_text').style.display = 'block';"
onmouseout="this.src='images/icons/info.png';
document.getElementById('home_text').style.display = 'block';
document.getElementById('info_text').style.display = 'none';"
onclick=""/>
</a>
<h3>Info</h3>
</td>
with relevant css:
#icon tr td img{
width: 100px;
height: 100px;}
#icon tr td p{
margin: 0px;}
#icon tr td{
text-align: center;
width: 150px;}
#icon{
margin-left: auto;
margin-right: auto;}

https://css-tricks.com/snippets/css/basic-link-rollover-as-css-sprite/
You can boost your responsiveness by creating only one image with both states of your button that is twice as large as the button itself. Then, on mouseover, just change the background-position property using css instead of loading a new image every time. This effectively "slides" the image so that the correct part of it shows "through" the button. This operation is very fast, and I think you'll see a big difference.

Compress your images and it the website will load a bit faster.
Post it on jsFiddle and specify the problem, because for now, I don't understand what do you want, because your website loads normally without any lag.
If you want to create an attribute with image, you can change the background of attribute or just use JS for.. some cool stuff you're trying to do.
EDIT: I've done in the past, my solution is to use background-image and change it on :hover
http://puu.sh/qc98m/a828b9ae4e.png like that.

The mouseover is only slow when hovering the images for the first time. What's happening behind the scenes, is that the new (hover) images weren't loaded into the browser's cache when the page loaded, have to be loaded on first mouseover, and hence cause the (visual) delay. Subsequent cursor passes are as fast as would normally be expected.
One possible solution would be to preload images (which would obviously happen in the background) immediately when the page loads. From a similar question:
function preloadImage(url)
{
var img=new Image();
img.src=url;
}
preloadImage('images/icons/hover-info.png');

Related

Hovering over an image in one div container to have an img or background appear in or over top of a different container

So I'm fairly new as far as coding goes, just so everyone knows.
I'm trying to accomplish two simultaneous things
1. The first is, I would like be able to hover over an image in one container and have another image in a different container appear. Even if that means having an image that technically overlaps the container and just happens to have the same dimensions (which are width: 350px and height: 205px, by the way). If another solution is to have the initial image be a clickable link to open the second image, that would be fine too. In fact, that'd be preferable.
2. I need to do this multiple times, each with different initial and secondary images, with float:right or a similar css function involving setting the sets of initial images being wrapped to the right of my first div container.
3. I need to maintain the set of initial images (buttons), in two rows, with overlap-y: hidden and overlap-x: scroll.
My css for the button images is this, and must either stay this way or have a similar effect:
div.img {
margin: 10px;
**padding: 5px;**
**height: 38px;**
**width: 38px;**
float: right;
display:inline;}
div.img img {
**height: 38px**
**width: 38px**
display: inline;
float:right;
margin: 10px;
**border: 12px solid #ffffff;**
**border-radius: 8px;**
**box-shadow: 3px 3px 1px #888888;**
I put all the key points of the css that I need to keep (or display in a similar fashion) in bold. The part in question is the display: inline function. I need my set of images to be in two rows, wrapping to the right side of the container (or at least scrolling horizontally), but instead they are displaying as two rows of three, then one vertical column that is no longer aligned with the two rows of three.
To see the type of solution I'm looking for, here's the page: http://hellothisismelody.tumblr.com/codeconstruction/
As you can see, it's set up like a Nintendo 3DS. I'm looking to make functioning buttons on the bottom screen that make an image appear in the top screen, and looking to have those images set up like the home screen of a Nintendo 3DS, which looks like this:
Click for Nintendo 3DS Homescreen
Thank you for you time.
Regarding your first question, you can use this:
<div class=container1>
<img src='blah1.png'>
</div>
<div class=container2>
<img src='blah2.png'>
</div>
$('.container1 img').hover(function() {
$('.container2 img').get(0).src = 'blah3.png';
});

Mouseover image lags

On the site I am currently building, I have 5 external links, with mouseovers, linking to social sites such as facebook, twitter, youtube, etc. These links have a small image (15px x 15px) of the social networks logo in white, and then text in white of the name. I am using javascript to change the img src, to the coloured version of the logo, and change the colour of the text to a light blue. The text changes colour immediately, but the images have a slight lag on them, especially the facebook logo.
My code in javascript for the mouseovers is:
function FacebookMO(Type) {
if (Type == "Off") document.getElementById('Facebook').style.color = "#FFF", document.getElementById("FacebookLogo").src = "Images/Social/Facebook Logo W.png";
if (Type == "Over") document.getElementById('Facebook').style.color = "#3B5998", document.getElementById("FacebookLogo").src = "Images/Social/Facebook Logo B.png";
if (Type == "Clicked") document.getElementById('Facebook').style.color = "#141e33"; }
The code for the other 4 links is the same except facebook has been changed for the relevant link/text/img.
here is all the relevant code for the html;
<a href="http://www.facebook.com/WrecRecords" class="bar3" id="Facebook"
onmouseout="FacebookMO('Off')" onmouseover="FacebookMO('Over')" onmousedown="FacebookMO('Clicked')"
onmouseup="FacebookMO('Over')" style="padding-left:10px;"><img class="padr5" id="FacebookLogo"
src="Images/Social/Facebook Logo W.png" style="height:15px; width:15px;"/>Facebook</a>
and the css too;
a.bar3 {
font-family:"Bebas Neue", sans-serif;
font-size:20px;
color:#FFF;
padding:0px 20px;
text-decoration:none;
}
I've tried preloading the image via different methods including visibility:hidden; display:none; and loading the image into the webpage as a 1x1px img at the bottom, but I still have the lag.
The delay is significantly worse online than when just using the whole site locally. If anybody can offer any help I would really appreciate it, as i'm really stumped as to how to prevent this lag from happening. Thanks.
Edit: just tested this on a few different browsers.
On firefox I have no lag and it works flawlessly when tested from the local files. yay! :) however on the web, there is a slight delay of about 3 seconds when you first hover over it, and then works flawlessly afterwards. (Think I just need to load the images immediately when the page loads).
Chrome, which is what I was testing on initially, still having this slight lag issue, although i have absolutely no idea why still.
I tried testing on internet explorer, but no scripts are running on there at all atm.
The trick with this one is not to use separate images but a so called spritemap. You image is 15x15px, now you make a 30x15px image which contains the normal and hover state next to each other. Instead of replacing the image, you change the background-position of the background image.
Example from http://css-tricks.com/snippets/css/basic-link-rollover-as-css-sprite/
a {
display: block;
background: url(sprite.png) no-repeat;
height: 30px;
width: 250px;
}
a:hover {
background-position: 0 -30px;
}

Fixed div as background on mobile devices

I want to use a div as a background for a website.
If I use position:fixed and set the width & size to the viewport size the design breaks on mobile devices/tablets as they do not support the fixed position.
What's the best way to set a div as a static background, so that it works on mobile devices too?
I'm not entirely sure how you intend to use the background, but I created a loose way to do this here. The tacky background is applied to a div the size of the screen, and it will not move (as long as you're careful with what you put inside it). However, the same effect could be done just by direct styles on the body - I'm not sure what exactly you need the div for, so I can't guarantee this technique will work for your use case.
How it Works
With disclaimers out of the way, here are a few details on how it works. All content will have to appear within two divs: one outer one that has the background, and an inner one to hold all of the content. The outer one is set to the size of the page and can have the background applied to it. The inner one then is set to the size of the parent, and all overflow is set to scroll. Since the outer one has no scrollbar, any interior content that exceeds the size of the background tag will cause a scrollbar to appear as though it were on the whole page, not just on a section of it. In effect, this then recreates what the body is on the average web page within the "content" div.
If you have any specific question on the styles, let me know and I'll flesh out the mechanics in more detail.
With jQuery
I suppose there's still one remaining option: use similar style rules, but absent the ability to nest everything within the background, instead prepend it, and change it's position whenever the user scrolls, like so.
Then, just inject this code:
<style>
#bg {
width: 100%;
height: 100%;
position: absolute;
top: 0px;
background-image: url(http://cdn6.staztic.com/cdn/logos/comsanzenpattern-2.png:w48h48);
margin: 0px;
padding: 0px;
overflow: hidden;
}
</style>
<script>
$("body").prepend("<div id='bg'></div>");
$(document).on("scroll", function () {
$("#bg").css("top", $(document).scrollTop())
.css("left", $(document).scrollLeft());
});
</script>
modifying the style rules for the background div accordingly, and you should be good. It will not have a good framerate since this will always appear after the scroll paint, but you're running low on options if you have so little control over the rest of the document structure and style.
You don't have to use jquery. I was able to get this effect with just CSS.
You set the div just below the initial tag. Then apply the image to the html within the div. Give the div and id attribute as well (#background_wrap in this case).
...I tried this without applying the actual image link within the html and it never worked properly because you still have to use "background-image:" attribute when applying the image to the background within css. The trick to getting this to work on the mobile device is not using any background image settings. These values were specific for my project but it worked perfectly for my fixed background image to remain centered and responsive for mobile as well as larger computer viewports. Might have to tweak the values a bit for your specific project, but its worth a try! I hope this helps.
<body>
<div id="background_wrap"><img src="~/images/yourimage.png"/></div>
</body>
Then apply these settings in the CSS.
#background_wrap {
margin-left: auto;
margin-right: auto;
}
#background_wrap img {
z-index: -1;
position: fixed;
padding-top: 4.7em;
padding-left: 10%;
width: 90%;
}

unitPngFix prevents changing "display" of hidden "div"

I have almost solved a huge problem with png files and transparency in IE browsers on my website.
The problem is that only in IE6, this wont work.
I have this code called unitpngfix.js which displays transparent PNG images correctly on my website in IE browsers.
I have a DIV with a png image inside it like this:
<div id="pop" class="pop_komm">
<img src="Graphics/komm.png">
</div>
css:
.pop_komm {
position: absolute;
z-index: 20;
height: 52px;
width: 208px;
left: 760px;
top: 239px;
display:none;
zoom:1;
}
And I have a very basic js code for making the container visible:
document.getElementById("pop").style.display='block';
//This triggers on a drop list change event, so this DIV shows when I change a drop list value
This wont work however. Nothing shows up in IE6. If I remove the unitPngFix completely, then the DIV shows with the PNG file, but the transparency wont work.
Also, if I reverse the js function and "HIDE" the DIV instead of showing it:
display='none';
Then it works fine!
In other words, when the DIV is hidden, then the unitPngFix prevents the PNG file to be shown. I am suspecting a bug here!?
Any help?
Here is UnitPngFix website
Thanks
PS: I will tag JQuery also, as I might have to use it to fix this, but I would prefer plain js as the website is currently only built using that.
Instead of hiding it, set a huge left offset and the PNG fix should apply. Then to show it, set the left to a visible legit value.
left:-9999em then to show it, left:760px

Don't load hidden images

I have a bunch of hidden images on my website. Their container DIVs have style="display: none". Depending on the user's actions, some images may be revealed via javascript. The problem is that all my images are loaded upon opening the page. I would like to put less strain on the server by only loading images that eventually become visible. I was wondering if there was a pure CSS way to do this. Here are two hacky/complicated ways I am currently doing it. As you can see, it's not clean code.
<div id="hiddenDiv">
<img src="spacer.gif" />
</div>
.reveal .img {
background-image: url(flower.png);
}
$('hiddenDiv').addClassName('reveal');
Here is method 2:
<img id="flower" fakeSrc="flower.png" />
function revealImage(id) {
$('id').writeAttribute(
'src',
$('id').readAttribute('fakeSrc')
);
}
revealImage('flower');
The browser will load any images that has a src attribute set, so what you want to do is to use data-src in the markup and use JavaScript to set the src attribute when you want it to load.
<img class="hidden" data-src="url/to/image.jpg" />
I created this tiny plugin that will take care of the problem:
(function($){
// Bind the function to global jQuery object.
$.fn.reveal = function(){
// Arguments is a variable which is available within all functions
// and returns an object which holds the arguments passed.
// It is not really an array, so by calling Array.prototype
// he is actually casting it into an array.
var args = Array.prototype.slice.call(arguments);
// For each elements that matches the selector:
return this.each(function(){
// this is the dom element, so encapsulate the element with jQuery.
var img = $(this),
src = img.data("src");
// If there is a data-src attribute, set the attribute
// src to make load the image and bind an onload event.
src && img.attr("src", src).load(function(){
// Call the first argument passed (like fadeIn, slideIn, default is 'show').
// This piece is like doing img.fadeIn(1000) but in a more dynamic way.
img[args[0]||"show"].apply(img, args.splice(1));
});
});
}
}(jQuery));
Execute .reveal on the image(s) you want to load/show:
$("img.hidden").reveal("fadeIn", 1000);
See test case on jsFiddle.
Here's a jQuery solution:
$(function () {
$("img").not(":visible").each(function () {
$(this).data("src", this.src);
this.src = "";
});
var reveal = function (selector) {
var img = $(selector);
img[0].src = img.data("src");
}
});
It's similar to your solution, except it doesn't use the fakeSrc attribute in the markup. It clears the src attribute to stop it from loading and stores it elsewhere. Once you are ready to show the image, you use the reveal function much like you do in your solution. I apologize if you do not use jQuery, but the process should be transferable to whichever framework (if any) that you use.
Note: This code specifically must be ran before the window has fired the load event but after the DOM has been loaded.
Weirdly, there's no answer about native lazy loading which is implemented in the majority of the browsers already.
you can do it by adding loading="lazy" attribute to your image.
Addy Osmani wrote a great article about it. You can read more about lazy loading here: https://addyosmani.com/blog/lazy-loading/
It partially depends on how your images must be placed in your code. Are you able to display the images as the background of a <div>, or are you required to use the <img> tag? If you need the <img> tag, you may be screwed depending on the browser being used. Some browsers are smart enough to recognize when an image is inside of a hidden object or in an object of 0 width/height and not load it since it's essentially invisible, anyway. For this reason many people will suggest putting an image in a 1x1 pixel <span> if you want the image to be pre-loaded but not visible.
If you don't require the <img> tag, most browsers won't load images referenced by CSS until the element in question becomes visible.
Mind you that short of using AJAX to download the image there's no way to be 100% sure the browser won't pre-load the image anyway. It's not unbelievable that a browser would want to pre-load anything it assumes may be used later in order to "speed up" the average load times.
Using CSS to put the image an unused class, then adding that class to an element with javascript is going to be your best bet. If you don't use image tags at all, this solution becomes a bit more obvious.
Though, for perspective, most people have the opposite problem where they want to preload an image so it shows up instantly when it's told to be shown.
If you are okay relying on scripting, there is the background image method and the image src method. Put simply, set all your hidden images to some very small image (reduce strain on server) or one that does not exist at all (who cares? The visitor cannot see the image-missing [X] anyway, the div is hidden) then change it with script...
<img src="I_do_not_exist.jpg" id="my_image" />
<input type="button" onclick="document.getElementById('my_image').src='I_exist.jpg';" Value="change image" />
<br /><br /><br />
<div id="mydiv" style="width:40px; height:40px; border:2px solid blue"></div>
<input type="button" onclick="document.getElementById('my_div').style.width='455px';document.getElementById('my_div').style.height='75px';document.getElementById('my_div').style.backgroundImage='url(I_exist.jpg)';" Value="change background image" />
I left a width on the above example to show that nothing is in the div image wise until you ask it to load.
If you make the image a background-image of a div in CSS, when that div is set to 'display: none', the image will not load.
You can do the following for a pure CSS solution, it also makes the img box actually behave like an img box in a responsive design setting (that's what the transparent png is for), which is especially useful if your design uses responsive-dynamically-resizing images.
<img style="display: none; height: auto; width:100%; background-image:
url('img/1078x501_1.jpg'); background-size: cover;" class="center-block
visible-lg-block" src="img/400x186_trans.png" alt="pic 1">
The image will only be loaded when the media query tied to visible-lg-block is triggered and display:none is changed to display:block. The transparent png is used to allow the browser to set appropriate height:width ratios for your <img> block (and thus the background-image) in a fluid design (height: auto; width: 100%).
1078/501 = ~2.15 (large screen)
400/186 = ~2.15 (small screen)
So you end up with something like the following, for 3 different viewports:
<img style="display: none; height: auto; width:100%; background-image: url('img/1078x501_1.jpg'); background-size: cover;" class="center-block visible-lg-block" src="img/400x186_trans.png" alt="pic 1">
<img style="display: none; height: auto; width:100%; background-image: url('img/517x240_1.jpg'); background-size: cover;" class="center-block visible-md-block" src="img/400x186_trans.png" alt="pic 1">
<img style="display: none; height: auto; width:100%; background-image: url('img/400x186_1.jpg'); background-size: cover;" class="center-block visible-sm-block" src="img/400x186_trans.png" alt="pic 1">
And only your default media viewport size images load during the initial load, then afterwards, depending on your viewport, images will dynamically load.
And no javascript!

Categories