I've been using http://www.dillerdesign.com/experiment/DD_belatedPNG/ for a while now and it has solved most of my IE6 png headaches.
I wonder though, whether there is a way of automating it so that I don't have litter my code with class="png" or adding the ids of html elements using background images to a JS file. - I don't care really that this would slow IE6 down - It's easier to explain to a client that the website is slow due to their browser than it is to explain why everything has a grey background!
I'm not really a JS expert but I guess grabbing the src attribute and adding the file name to the class isn't difficult. - Somehow parsing the CSS and and adding the id of the containing element sounds difficult if not impossible though??
This isn't tested but here is my jQuery solution which should work. It basically checks all img elements for a .png extension then checks all elements except img for a background image with a .png extension
You may need to add in extra code to check for CSS background property as well as background-image. With the body * selector I would imagine a lot of overhead on pages with lots of elements but I'm with you, I don't care how long it takes IE6 users to load the page if they don't care about updating their browser
$(function() {
$('img').each(function() {
if(this.src.split('.').pop() == 'png') {
DD_belatedPNG.fixPng(this)
}
});
$('body *:not(img)').each(function() {
if($(this).css('background-image').split('.').pop().replace(/("|\')\)/,'') == 'png') {
DD_belatedPNG.fixPng(this);
}
});
});
EDIT: I found this quite an interesting challenge so wrote up a pure JavaScript solution. It needs to be run when the DOM is ready though, so if you really don't want to use jQuery or another framework with a DOM ready function you'll have to use Dean Edwards' method, like so:
document.write('<script type="text/javascript" id="domready" defer="defer" src="javascript:void(0)"><\/script>');
document.getElementById("domready").onreadystatechange = function() {
if (this.readyState == "complete") {
var imgs = document.getElementsByTagName('img')
for(i=0; i < imgs.length; i++) {
if(imgs[i].src.toLowerCase().search(/\.png$/) != -1) {
DD_belatedPNG.fixPng(imgs[i]);
}
}
var children = document.body.getElementsByTagName('*');
for(i=0; i < children.length; i++) {
var bg = children[i].currentStyle.backgroundImage;
if(bg != 'none' && bg.toLowerCase().search(/\.png("|\')?\)$/) != -1) {
DD_belatedPNG.fixPng(children[i]);
}
}
}
}
Related
I have jQuery loading data for my web app. Being a web app, all my code is being compiled into one file. It's reused often. Filesize and inefficiencies could seriously slow down my website performance and load time.
My question is: Does jQuery have built-in handlers for redundancies?
My example concerns the .fadeIn() function. I don't want $('.search-output') to "fade in" every single time a key is pressed, however, I don't want to add unneeded code that jQuery already handles on its own.
I'm assuming that jQuery does handle these redundancies on its own because no animation is present when running this without my 'if visible' statement. Still, it might run other code that slows down my web app. Is it better/efficient coding practice to code in my own handlers for everything or to let jQuery handle it on its own?
I know I could look at the jQuery code but you guys might have more valuable input than just a yes or a no.
$this.find('.search-input input').keyup(function() {
if ($(this).val() == '') {
$(this).parent().parent().parent().parent().find('.search-output').fadeOut(150)
} else {
if (!$(this).parent().parent().parent().parent().find('.search-output').is(':visible')) {
$(this).parent().parent().parent().parent().find('.search-output').fadeIn(150)
}
formData.append('request', 'req_search_users')
formData.append('searchString', $(this).val())
xhr_request(formData, open)
function open($status, $_rtn) {
if ($status == 200) {
$output = $this.find('.search-output')
$_rtn = $_rtn.split('|,')
if (parseInt($_rtn[0]) > 0) {
$output.append($_rtn[1]).ready(function() {
link_user_click($(this))
})
}
if (parseInt($_rtn[0]) < 3) {
$this.addClass('eof')
$this.find('.auto-loader').hide();
}
} else {
console.log('XHR POST: 404 Error')
}
}
}
})
This is the specific section of code we are looking at:
if (!$(this).parent().parent().parent().parent().find('.search-output').is(':visible')) {
$(this).parent().parent().parent().parent().find('.search-output').fadeIn(150)
}
This is my first stack-overflow post. Thanks for any input you can provide!
The answer is yes. jQuery does apply fade-in animation to all visible elements (elements with the CSS property display not equal to hidden). All jQuery methods which animates visibility are an "extension" of the <collection>.toggle() method, which automatically switches between hidden and inline states, see https://api.jquery.com/toggle/
I have groups of related images that I would like to be able to change (but position in the same div) by clicking on different radio buttons.
Currently I am using arrays to handle the html,
var marketingImages = [image1HTML, image2HTML, image3HTML, image4HTML];
var salaryImages = [image1HTML, image2HTML, image3HTML, image4HTML];
And when a relevant radio button is clicked, a function runs to clear the html in the div (of possible previous images), and load the new images using .append.
$(document).ready(function() {
$("#marketing, #salary").click(leed);
function leed() {
$("#portfolio-images").html("");
if ($("#marketing").is(':checked')) {
var portfolioArray = marketingImages;
} else if ($("#salary").is(':checked')) {
var portfolioArray = salaryImages;
}
for (var i=0; i<portfolioArray.length; i++) {
$("#portfolio-images").append(portfolioArray[i]);
}
...
}
It seems to work well, but being a noob though I have to wonder if there's a better way to handle this. Technically these images are just thumbnails (that can be clicked on to load larger Lightbox versions), but I'm unsure of how well that would "really" load for someone.
Does somebody know if there's a better way to handle loading groups of images? Thanks.
I use CKEDITOR 4 and I want to filter a HTML content to insert the style directly in the HTML Elements like MailChimp with its CSS inliner (http://beaker.mailchimp.com/inline-css). But I have to do in Javascript must, someone an idea?
I can use jQuery and PrototypeJs.
I can't use an external API.
My test jsFiddle with CKEditor (on paste) : http://jsfiddle.net/EpokK/utW8K/7/
In :
<style>
.test {
outline: 1px solid red;
}
</style>
<div class="test">Hello</div>
Out :
<div style="outline: 1px solid red;">Hello</div>
I find this solution : http://tikku.com/scripts/websites/tikku/css_inline_transformer_simplified.js
but this trick opens a tab and it is blocked by default in Firefox ...
API solution : http://premailer.dialect.ca/
Edit: Cleaning up my GH account from unfinished PoCs I removed the tool mentioned below, so the link leads to a 404. There's someone else's project, though, which may interest you: http://styliner.slaks.net/
I created simple CSS styles inliner - styliner.
It works on Firefox and Chrome. May also work on IE9+ and Safari 6, but I haven't tested it yet. This version does not need a new window - it uses iframe (so it may not work on IE - it always needs some tricks to make iframes work :).
It lacks support for CSS specificity, so at least for now, to use it, you would have to sort rules manually. But maybe I'll find some time to add this feature soon.
I'm not sure if this will help but I found this nice little jQuery/javascript method that can be embedded into a page - http://devintorr.es/blog/2010/05/26/turn-css-rules-into-inline-style-attributes-using-jquery/
I've edited it a little to support IE and also to support a page with multiple CSS files attached applying the styles in the correct order. The if(rules[idx].selectorText.indexOf("hover") == -1) line is necessary because jQuery (as of 1.8) can't use the :hover selector anymore apparently.
$(document).ready(function ($) {
var rules;
for(var i = document.styleSheets.length - 1; i >= 0; i--){
if(document.styleSheets[i].cssRules)
rules = document.styleSheets[i].cssRules;
else if(document.styleSheets[i].rules)
rules = document.styleSheets[i].rules;
for (var idx = 0, len = rules.length; idx < len; idx++) {
if(rules[idx].selectorText.indexOf("hover") == -1) {
$(rules[idx].selectorText).each(function (i, elem) {
elem.style.cssText = rules[idx].style.cssText + elem.style.cssText;
});
}
}
$('style').remove();
$('script').remove();
$('link').remove();
}
});
The page can then be copy/pasted into the email body.
Quite a simple question, yet it has been bugging me all week!
Firstly, I do not expect someone to write me this huge piece of code, then me take it away and claim it for my own. Would prefer someone to actually help me write this :)
I am attempting to show a playlist on my website as a png image.
I have 2 playlists that must be shown.
The playlist will change on an image press.
I have 4 button images, 'CD1up', 'CD1down', 'CD2up' and 'CD2down'.
I would like to have these buttons changing what current playlist is being shown, but also showing the buttons correct state. For example, is playlist1 is being shown, then 'CD1up' must be shown, and 'CD2down' shown.
I would post my current code here, but I basically scrapped it all and decided to start from scratch since I'm terrible with web javascript.
All help is greatly appreciated!
I can basically fluent in HTML and CSS, but horrible at web javascript.
Some notes:
If you give each image an id attribute, you can use document.getElementById to get a reference to that element once the page is loaded.
Then you can set the src property on that element to a new URL to change the image.
Make sure your script tag is after the elements in the HTML (just before the closing </body> works) so that the elements exist when you want them.
You can add a click event handler to any element on the page. Most browsers support addEventListener but some older versions of IE still require you to use attachEvent to hook up the handler. So you see people with functions that look something like this:
function hookEvent(element, eventName, handler) {
if (element.addEventListener) {
element.addEventListener(eventName, handler, false);
}
else if (element.attachEvent) {
element.attachEvent("on" + eventName, handler);
}
else {
element["on" + eventName] = function(event) {
return handler.call(this, event || window.event);
};
}
}
So for example, if you have this img:
<img id="myImage" src="/path/to/img.png">
This cycles through four images on click:
<!-- This must be AFTER the `img` above in the HTML,
just before your closing /body tag is good -->
<script>
(function() {
var myImage = document.getElementById("myImage"),
images = [
"/path/to/img1.png",
"/path/to/img2.png",
"/path/to/img3.png",
"/path/to/img4.png"
],
index = -1;
hookEvent(myImage, "click", imageClick);
function imageClick() {
++index;
if (index >= images.length) {
index = 0;
}
myImage.src = images[index];
}
})();
</script>
You can get a lot of utility functionality and smooth over browser differences using a decent library like jQuery, YUI, Closure, or any of several others, although if all you want to do on the page is change the images sometimes and handle a click or two, that might be overkill.
I currently have a preloading image javascript script:
function MM_preloadImages() {
var d = document;
if(d.images){
if(!d.MM_p )
d.MM_p=new Array();
var i,j=d.MM_p.length,a=MM_preloadImages.arguments;
for(i=0; i<a.length; i++){
if (a[i].indexOf("#")!=0){
d.MM_p[j]=new Image;
d.MM_p[j++].src= '/img' + a[i];
}
}
}
}
The problem is that i have to manually update the array when images are added deleted etc.
Is there anyway of automating this or is there a library.
Most of the image urls are element hrefs.
Obviously I could write something server side but I want to check if there is something out there already.
Here is someone who did what you are trying to do with jQuery:
http://www.filamentgroup.com/lab/update_automatically_preload_images_from_css_with_jquery/
Edit: Actually this is not quite what you are looking for as this preloads images from CSS files - I am going to leave this here in case this is still helpful.
The trouble is by the time the elements are available in the DOM for JS to inspect the images are already being loaded anyway.
AFAIK there is no way to do this (the CSS based inspection works because that's loaded before the body content), but a superior solution for the problem in general is CSS spriting.