Object-Fit Polyfill

Hello I have a polyfill for the object-fit for the IE browser
and I currently have class of ‘cover’ on my images to target
the js but it is not working. Site (open in a IE browser)

HTML:

 <img class="cover" src="images/pd_main.jpg" alt="mainbanner">

JS:

   <script>
		$(function() {
			$('.contain').objectFit('contain');
			$('.cover').objectFit({ type: 'cover', hideOverflow: true});
		});
	</script>

MOREJS:

// jquery.object-fit.js
// ====================
//
// Originally by Simon Schmid https://github.com/schmidsi
// Re-worked by Steve Workman https://github.com/steveworkman
// Polyfill for Object-fit property in CSS3 Images http://www.w3.org/TR/2012/CR-css3-images-20120417/#object-fit
//
// usage:
// ------
// ```
// $('.selector').objectFit({type: 'contain', hideOverflow: true});
// ```
//
// implemented types:
// 'contain' (default)
// 'cover'

(function($, window, document) {

	var resizeTimer, toResize = [];

	var testForObjectFit = function() {
		// Borrowed from Modernizr
    	var mStyle = document.createElement('modernizr').style,
		prop = 'objectFit', 
		omPrefixes = 'Webkit Moz O ms',
		cssomPrefixes = omPrefixes.split(' '),
		ucProp  = prop.charAt(0).toUpperCase() + prop.slice(1),
		props   = (prop + ' ' + cssomPrefixes.join(ucProp + ' ') + ucProp).split(' ');

		for ( var i in props ) {
	        var prop = props[i];
	        if ( !!~('' + prop).indexOf("-") && mStyle[prop] !== undefined ) {
	            return prefixed == 'pfx' ? prop : true;
	        }
	    }
	    return false;
	};
	
	var doObjectFit = function(type) {
		// default type is "contain"
		var type = type || 'contain';
		var supportsObjectFit = testForObjectFit();
		
		return this.each(function() {
			if (supportsObjectFit) {
				$(this).css('object-fit', type);
			}
			else {
				doResize(this, type);
			}
			
		});
	};

	var doResize = function(elem, params) {
		var type = typeof(params) === 'string' ? params : params.type,
			hideOverflow = params.hideOverflow === undefined ? true : params.hideOverflow;

		// Cache the resize request
		toResize.push({elem: elem, params: {type:type, hideOverflow: hideOverflow}});
		// Find the first block level element, as we need the containing element, not just the next one up
		function findParentRatio(jqObject) {
			var p = jqObject.parent(),
				displayType = p.css('display');
			
			if (displayType == 'block' || displayType == '-webkit-box' && p.width() > 0) {
				return { obj: p, width: p.width(), height: p.height(), ratio: (p.width() / p.height()) };
			} else {
				return findParentRatio(p);
			}
		}

		var $this = $(elem),
				ratio = $this.data('ratio'),
				parent = findParentRatio($this), // The parent element may not have any width or height, so find one that does
				pic_real_width,
				pic_real_height;

		var image = $("<img/>") // Make in memory copy of image to avoid css issues
			.load(function() {
				pic_real_width = this.width;   // Note: $(this).width() will not
				pic_real_height = this.height; // work for in memory images.

				// set the ratio of the object. we assume, that the ratio of the object never changes.
				if (ratio === undefined) {
					ratio = pic_real_width / pic_real_height;
					$this.data('ratio', ratio);
				}

				// Set the width/height
				if (type === 'contain') {
					if (parent.ratio > ratio) {
						$this.width(parent.height * ratio);
					} else {
						$this.height(parent.width / ratio).width('100%');
					}
				}
				else if (type === 'cover') {
					// At least one dimension is smaller, so cover needs to size the image
					if (parent.width > pic_real_width || parent.height > pic_real_height) {
						if (parent.ratio > ratio) {
							$this.width(parent.width).height(parent.height * ratio);
						} else {
							$this.height(parent.height).width(parent.width * ratio);
						}
					}
					if (hideOverflow) {
						// Apply overflow-hidden, or it looks ugly
						parent.obj.css('overflow', 'hidden');
					}
				}
			});
		image.attr("src", $this.attr("src")); // Has to be done outside of assignment for IE
	};

	$.fn.objectFit = doObjectFit;

	$(window).resize(function() {
		clearTimeout(resizeTimer);
		for(var i=0, len = toResize.length; i<len; i++) {
			var a = toResize[i];
			resizeTimer = setTimeout(function() { doResize(a.elem, a.params);}, 100);
		}
	});


})(jQuery, window, document);

That’s not working very well in Chrome or Firefox either as the image squishes when the slide is active and then pops back into position when the slide has stopped.

Why don’t you use background images instead and avoid the need for the script with IE at the same time.

e.g. Do This.

.img1{background:url(http://impactograph.com/preferreddentist/images/pd_main.jpg) no-repeat 50% 50%}
.img2{background:url(http://impactograph.com/preferreddentist/images/pd_dentist_slide.png) no-repeat 50% 50%}
.img3{background:url(http://impactograph.com/preferreddentist/images/fallbanner.png) no-repeat 50% 50%}
.imgReplace {
    position:absolute;
    left:0;
    top:0;
    right:0;
    bottom:0;
    background-size:cover;    
}    

Then replace the images with a div.

<div class="item active"> 
        <!-- <img class="cover" src="http://impactograph.com/preferreddentist/images/pd_main.jpg" alt="mainbanner">-->
        <div class="imgReplace img1"></div>
        <div class="carousel-caption">
                <div class="row caption-box">
                        <div class="col-lg-8">
                                <p class="caption-title"><em>Preferred</em> Dentist assists in finding you the best dentist. <a href="contactus.html">
                                        <button type="button" class="btn btn-primary btn-lg home-btn"><span class="glyphicon glyphicon-pencil" aria-hidden="true"></span>Schedule An Appointment</button>
                                        </a></p>
                        </div>
                </div>
        </div>
</div>
<div class="item"> 
        <!--  <img class="cover" src="http://impactograph.com/preferreddentist/images/pd_dentist_slide.png" alt="...">-->
        <div class="imgReplace img2"></div>
        <div class="carousel-caption">
                <div class="row caption-box">
                        <div class="col-lg-8">
                                <p class="caption-title">Are You a Dentist? <a href="yourpractice.html">
                                        <button type="button" class="btn btn-primary btn-lg"><span class="glyphicon glyphicon-briefcase" aria-hidden="true"></span> List You Practice Here</button>
                                        </a></p>
                        </div>
                </div>
        </div>
</div>
<div class="item"> 
        <!--<img class="cover" src="http://impactograph.com/preferreddentist/images/fallbanner.png" alt="...">-->
        <div class="imgReplace img3"></div>
        <div class="carousel-caption">
                <div class="row caption-box">
                        <div class="col-lg-8">
                                <p class="caption-title">Fall In Love with Your Smile <a target="_blank" href="http://www.amazon.com/gp/aag/main?ie=UTF8&asin=&isAmazonFulfilled=1&isCBA=&marketplaceID=ATVPDKIKX0DER&orderID=&protocol=current&seller=A31FG9U13QTNPM&sshmPath=">
                                        <button type="button" class="btn btn-primary btn-lg home-btn"><span class="glyphicon glyphicon-shopping-cart" aria-hidden="true"></span> Order Here</button>
                                        </a></p>
                        </div>
                </div>
        </div>
</div>

You can then remove the polyfill script altogether.

Of course mow that you have fixed the height of the images the small screen display is not very useful as most of the image will be missing (unlike the scaling version that I gave you originally).

Note also that those images are 1200k each!!! They should be a maximum of about 120k or you will kill the web.

You would probably also need to preload those images first also to stop empty slides appearing (there are many pre-load scripts around).

1 Like

ok ill compress them.

ok ill find a script

I found this one but I cant tell if its working or not the images
load normally…

<script type="text/javascript">
		<!--//--><![CDATA[//><!--
			var images = new Array()
			function preload() {
				for (i = 0; i < preload.arguments.length; i++) {
					images[i] = new Image()
					images[i].src = preload.arguments[i]
				}
			}
			preload(
				"http://impactograph.com/preferreddentist/images/pd_main.jpg",
				"http://impactograph.com/preferreddentist/images/pd_dentist_slide.png",
				"http://impactograph.com/preferreddentist/images/fallbanner.png"
			)
		//--><!]]>
	</script>

That looks ok as far as I can tell.

Clear your cache (or use the disable cache feature that comes with some web tools) and then load the page and if the slider images load ok then its working.:smile:

1 Like

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.