O'Reilly

dwImageProtector Plugin for jQuery

By on  

I've always been curious about the jQuery JavaScript library. jQuery has captured the hearts of web designers and developers everywhere and I've always wondered why. I've been told it's easy, which is probably why designers were so quick to adopt it NOT that designers aren't intelligent, but designers usually have enough design stuff to worry about and if they wanted to be programmers, they would've become programmers. jQuery being easy didn't convince me to try jQuery because Moo came pretty easy to me.

Last weekend I decided I needed to try jQuery. It would make me a more well-rounded developer and it might suit particular projects better than Moo. And there's nothing wrong with knowing both, right? I decided the first step would be porting over and existing MooTools class I'd written. What would be better than my much-misunderstood image protector class? Here it is, now in jQuery plugin format.

The jQuery Plugin JavaScript

jQuery.fn.protectImage = function(settings) {
	settings = jQuery.extend({
		image: 'blank.gif',
		zIndex: 10
	}, settings);
	return this.each(function() {
		var position = $(this).position();
		var height = $(this).height();
		var width = $(this).width();
		$('<img />').attr({
			width: width,
			height: height,
			src: settings.image
		}).css({
			border: '1px solid #f00',
			top: position.top,
			left: position.left,
			position: 'absolute',
			zIndex: settings.zIndex
		}).appendTo('body')
	});
};

The plugin accepts two parameters: the zIndex and the image you'd like to use as the protector.

The jQuery Usage

$(window).bind('load', function() {
	$('img.protect').protectImage();
});

It's important to run the plugin during the page's "load" event so that the dimensions are correct.

This plugin requires the jQuery Dimensions plugin. Click here to download the blank.gif overlay file.

Don't bother commenting about how you know 20 ways to get around this. Many non-technical persons will be fooled.

Look forward to reading my impressions of my first jQuery project tomorrow!

Track.js Error Reporting

Upcoming Events

Recent Features

  • Responsive Images: The Ultimate Guide

    Chances are that any Web designers using our Ghostlab browser testing app, which allows seamless testing across all devices simultaneously, will have worked with responsive design in some shape or form. And as today’s websites and devices become ever more varied, a plethora of responsive images...

  • Animated 3D Flipping Menu with CSS

    CSS animations aren't just for basic fades or sliding elements anymore -- CSS animations are capable of much more.  I've showed you how you can create an exploding logo (applied with JavaScript, but all animation is CSS), an animated Photo Stack, a sweet...

Incredible Demos

  • Create a Context Menu with Dojo and Dijit

    Context menus, used in the right type of web application, can be invaluable.  They provide shortcut methods to different functionality within the application and, with just a right click, they are readily available.  Dojo's Dijit frameworks provides an easy way to create stylish, flexible context...

  • MooTools, mediaboxAdvanced, and Mexico

    The lightbox is probably one of my favorite parts of the Web 2.0 revolution. No more having to open new windows (which can bog down your computer quite a bit) to see a larger image, video, etc. Instead, the item loads right into the...

Discussion

  1. The jQuery Dimensions plugin is now integrated in the latest version of jQuery, so adding this is no longer necessary. Thanks for this useful plugin!

  2. Thanks!

    I dabble in Mootools but JQuery is my library of choice.

  3. Anonymous Coward

    ZOMG!!!!

    You cant protect images. I just use FireBugz and bam your img’s are belong to me.

    (joke :)

    thx for the post. :)

  4. @Steven: Thank you for that. I still consider myself a noob! :)

    @Anon: Thank you for being light-hearted!

  5. Hi,

    I’m using Firefox 3 and the image is not protected at all, I can right click on the image abd I haven’t got any messages from jquery???
    Just use Web developper toolbar/Images Informations the protection goes away …

    Is there anything I missed?

    Thx for the post

  6. Miko

    Hilarious

  7. @Stef G: If you were to right-click and choose “Save Image As…”, you’d be downloading an image but the image would be the overlaying blank.gif file.

  8. Hey, great idea but sometimes the body isn’t the only relative container of the image. I won’t post here the code to fix it I made but the point is:
    – Instead of appending the new to the body, I cache it into a variable and append it after the protect image.

  9. Hey dude. Thanks for the awrsome plugin. This was exactly what I was looking for!

    As of jQuery 1.2.x the position() function is replaced with offset(), so you need to update that in your code.

    var position = $(this).offset();
    

    Simple enough.

    The issue I have to figure out now is i used onhover events on the images getting replaced and now they don’t work anymore =( I’ll have to tie those events onto the replaced blank.gif onhovers.

    I’ll post code when I figure it out.

    Cheers,
    Jordan of http://CubicleCollective.com

  10. I fixed the issue with onhover and other things.

    Problem with this plugin is that if you have an image you want to protect and it’s wrapped around an anchor tag…you essentially lose the anchor tag.

    <a href="/gohere"><img class="protect" src="iamprotected.jpg" /></a>
    

    Also you had to rebind certain events which I was using, particularly .hover() which I had to rebind to “mouseenter” and “mouseleave” as .hover() is a convenience function.

    Here’s the code snippet. or you can view my working demo at https://civil.workcube.com/content/burning-bridges

    return this.each(function() {
      var position = $(this).offset();
      var height = $(this).height();
      var width = $(this).width();
      var srcimg = this;
    
      var protect = $('<img />').attr({
         width: width,
         height: height,
         src: settings.image
      }).css({
         /*border: '1px solid #f00',*/
         top: position.top,
         left: position.left,
         position: 'absolute',
         zIndex: settings.zIndex
      }).bind(
         'mouseenter', function() {
         if($(srcimg).hasClass('imagecache-product_list')) { 
            $(srcimg).toggleClass('hovering');
         }
         $(srcimg).trigger("mouseenter");
      }).bind(
         'mouseleave', function() {
         if($(srcimg).hasClass('imagecache-product_list')) { 
            $(srcimg).toggleClass('hovering');
         }
         $(srcimg).trigger("mouseleave");
      });
    
      if($(srcimg).parent().get(0).tagName == "A") { 
         link = $(srcimg).parent().clone();
         link.html(protect);
         link.appendTo('body');
      }
      else {
         $(protect).appendTo('body');
      }
    });
    

    Thanks again for the code,
    Jordan

  11. Oops, I guess I should post the proper links to websites instead of posting my internal domains.

    The project I used image protector on is live and you can see it here:
    http://civilcitizen.com/catalog/2

    As for Michael, I do not believe my modified solution fails in IE7 (i think i tested it in that browser at least), so pop over and take a look at the jQuery there.

  12. we can download the image, by just clicking the image before its downloaded completed. means click the image before it is downloaded full.

  13. There is just one way to protect image: don’t publish them ;)

    I use the web developper bar for Firefox and with it, I can download the image with no problem. Thanks anyway: I love jQuery

  14. I used J0rd’s example above, and it’s working great. Thanks!

  15. Erwan

    Hi. It’s a very nice plugin you made there.

    Only one thing misses for my use, and I don’t manage to set it (noob at javasctipts).
    I’d like to copy the title & alt properties of my protected image on the blank image.
    Would you (or anyone) explain me how to do it ?

    (Thx)

  16. rich

    I like this a bunch, but was thinking that it would also be a nice touch to have a watermark added to the image if it is downloaded. That is, when you view it on the site, there is no watermark, but if someone decides to right-click and save it, it would then overlay, say a trasnparent gif in the center of the image and merge the two. Is that possible?

    Rich

  17. @Rich: Sure — you could customize the class and inject an additional watermark element positioned to where you’d like it to be.

  18. rich

    Thanks for the quick reply Dave. Is there any way you could point me in the right direction?..I only have a working knowledge of jQuery, and javascript for that matter. But I can more often than not work through an issue with a little nudge. — thanks.

  19. I’ve just tried this bit of jQuery code, and I love it. It was an almost perfect solution delivered to me in no time. However, I am still trying to overcome an issue with Firefox, when protecting images inside tags, the protected images are no longer clickable. I remove the protection and the ‘image links’ work again. This problem doesn’t arise in IE. I will post again when I have solved this.

  20. i did a little change to code. since i want the protection only on mouseover and remove the protection as mouse leaves.

    jQuery.fn.protectImage = function(settings) {
    settings = jQuery.extend({
        image: 'blank.gif',
        zIndex: 10
    }, settings);
    return this.each(function() {
        var position = $(this).offset();
        var height = $(this).height();
        var width = $(this).width();
        var protect = $('<img />').attr({
            width: width,
            height: height,
            src: settings.image
        }).css({
            border: '1px solid #f00',
            top: position.top,
            left: position.left,
            position: 'absolute',
            zIndex: settings.zIndex
        }).bind('mouseleave', function() { protect.remove() });
    
        $(protect).appendTo('body');
    });
    };
    

    And i will append the event using

    $('img.priceChartImage').bind('mouseenter',function(){
              $(this).protectImage();
    })
    

    what do you guys think about this one?

    Also thanks for initial code david.
    Cheers Team!!!

  21. Even i replaced blank.gif with :) . My usecase was to block images dragged to html editor. if i use blank.gif it was getting dragged to html editor. Though we cannot view blank.gif it was making the html content dirty. So i changed my code to use div. Following is the code i used.

    var protect = $('<div>').css({
            border: '1px solid #f00',
            top: position.top,
            left: position.left,
            position: 'absolute',
            zIndex: settings.zIndex,
            width:$(this).width(),
            height:$(this).height()
        }).bind('mouseleave', function() { protect.remove() });
    

    Any comments???

    Cheers :)

  22. Amazing code..Thanks alot for it :-)

  23. Dave

    Um, I just tried the demo (in Safari 4) and this method simply doesn’t work. I right-clicked on the image and opened it in a new tab… I also simply dragged it off onto the desktop.

  24. Nick

    with Google chrome you can simply drag the image from the browser to the desktop, but right clicking and saving the image will save the blank.gif image.

  25. Great idea but with Firefox 3.5.7 if you simply resize the webpage the blank.gif does not keep focused over the real image.

  26. nick

    uhh, you know this is a total FAIL right? in chrome i can drag the image to the desktop, and it’s the actual image, i can also right click and save the image, and i’m not downloading a transparent image, it’s the actual image. maybe better luck next time.

  27. @nick: Chief, you see this article is close to 2 years old, correct?

    • @david: would you have an update on this that can be used for current sets of browsers? thanks great site.. and great insite.. love it.. take care and more power!

  28. nick

    @David Walsh:
    awww dude i’m a total FAIL.
    that’d be neat if it still worked. oh well.

  29. Renaliza Deang Enriquez

    what about “save as page issue”

  30. valery

    Hello,

    I’m not abble to use your script however it seems simple to use.
    Could you provide a minimal html web page using this plugin ?
    (the demo is a php page and saving it provide a complex code)

    Thanks

  31. alencyp

    http://davidwalsh.name/dw-content/preload-images/6.jpg – the demo image is here. Do you really think it protects your images from copy?

  32. Darlington

    Hi, I tried the demo and i was able to drag the image onto my desktop

  33. Stéphane Houle

    In your test above, juste resize the window and you’ll see your red frame didn’t follow the image, than juste click the image out of red frame, and you will be able to save the picture !!! =)

  34. Andreas

    As an exercise it’s okay but in the real world it doesn’t work.
    The only solution to avoid image stolen is discussed here:
    http://www.webresourcesdepot.com/10-ways-to-protect-images-from-being-stolen/comment-page-2/#comment-223617

  35. David, great script. I modified it slightly to work better for different kinds of CSS layouts. Specifically, I changed the append bit to the following: .appendTo($(this).parent())

  36. but i still find original image in your source, can you give me tutorial to change the source code or dissable it. it is your image : http://davidwalsh.name/dw-content/preload-images/6.jpg

  37. David,

    I’m sorry to bring up ancient history, but I’m having a minor issue that I can’t seem to fathom.

    All of the js is injected properly and I see the blank.gif with adjusted dimensions to the desired image and the red border on my page. However, this is sitting within the top left hand side of the screen and not over the desired image that’s calling the ‘protect’ class. This obviously screams to add ‘position: relative;’ to the parent image but that doesn’t do a thing.

    Can you tell me where I’m going wrong? Again, sorry to bring this post back from the dead.

    Steve.

  38. right

    Hi, if I try to save the image, the script works fine, but if I try to copy and past the same image in photoshop, the script doesn’t work. Anyone can help me?

  39. sacha bess

    Great, by drag and drop, it’s possible to save image !

  40. kinoko

    Thank you for a wonderful script.
    I have a question.
    Are you able to be the link of the image?

Wrap your code in <pre class="{language}"></pre> tags, link to a GitHub gist, JSFiddle fiddle, or CodePen pen to embed!

Recently on David Walsh Blog

  • Free Download: Font Bundle Featuring 17 Incredible Typefaces

    The only thing we love more than a good font, is a good free font. So we’ve combed the Web for some of our favorite free fonts, and gathered them here in a single download. You’ll find a variety of useful typefaces, from highly geometric designs...

  • OâReilly Velocity Conference â Amsterdam

    My favorite front-end conference has always been O'Reilly's Velocity Conference because the conference series has focused on one of the most undervalued parts of client side coding:  speed.  So often we're so excited that our JavaScript works that we forget that speed, efficiency, and performance are just as important. The next Velocity...

  • CanIUse Command Line

    Every front-end developer should be well acquainted with CanIUse, the website that lets you view browser support for browser features.  When people criticize my blog posts for not detailing browser support for features within the post, I tell them to check CanIUse:  always up to date, unlike...

  • Generating Alternative Stylesheets for Browsers Without @media

    If your CSS code is built with a mobile-first approach, it probably contains all the rules that make up the "desktop" view inside @media statements. That's great, but browsers that don't support media queries (IE 8 and below) will simply ignore them, ending up getting the...

  • Serve a Directory with PHP

    Many developers have a giggle at PHP, even looking down at the language, but let's be honest:  most of our blogs are powered by it (WordPress) and it's a great language to dabble around with.  I cut my teeth on PHP, though I prefer to avoid PHP these days. But...