Disabling "Save image" (for noobs) - javascript

I know disabling right-click on images won't stop technical-minded people from downloading images. Using them as CSS backgrounds is not an option.
Ideally, I'd like to ONLY remove image-saving options and not the whole context menu. I have found 3 solutions. What do people recommend and why? Is there any specific part of the include file in which I should put this?
Many thanks :)
#1
$("body").on("contextmenu", "img", function(e) {
return false;
});
#2
$('img').bind('contextmenu', function(e) {
return false;
});
121 upvotes, src: Disabling right click on images using jquery
#3
$(document).ready(function() {
$("img").on("contextmenu", function() {
return false;
});
});
76 upvotes, src: How to prevent Right Click option using jquery

(2) uses a deprecated method: bind, so I won't recommend it.
(1) and (3) will do the same thing, the only difference is that in (3) the listener is added after the page is fully loaded.
There is no way to disable particular menu items from the default context menu. You may however write your own context menu for "img" elements which doesn't include save options, but I suspect for your purpose its not worth the trouble.

Related

Hiding jQueryUI tooltip when clicking on target="_blank" link

I'm using jQuery to show tooltips on every link on my page that has a 'details' attribute
$(function() {
$tooltip = $(document).tooltip({
show: false,
track: true,
items: "a[data-details]",
content: function() {
return $( this ).data('details');
}
});
});
This works very well. However, when the user clicks one of those links, the URL is opened in a new tab (using target="_blank"). The problem is that the tooltip is still open when the user gets back on the first tab.
Here's what I tried so far:
$('a[data-details]').on('click mousedown mouseup', function() { // this might be overkill
$(document).tooltip("close"); // Doesn't work at all
$('div[class^="ui-tooltip"]').remove(); // removes the tooltip onclick, but gets it back opened when returning on the tab
});
Is there a way to keep the tooltips closed when the new page is opened?
Thank you for your help.
Here's a fiddle illustrating the problem: https://jsfiddle.net/su4v757a/
Note: I'm using jQuery 1.12.4 with jQueryUI 1.12.1
This is probably a bug.
As far as I can tell this must be a bug.
And you could let them know over at https://bugs.jqueryui.com/report/10?P=tooltip
I notice that the .tooltip("close") doesn't work in the fiddle. However the tooltip listens to the "mouseleave"-event to close, and we can force that by $('a[data-details]').trigger("mouseleave");
If you try this out you will see that it do close, but pops up again:
$('a[data-details]').on('click mousedown mouseup', function() { // this might be overkill
$(this).trigger("mouseleave");
});
Hover and click the "me":
Coming back to the page notice that the tooltip has closed and come back again:
Workaround - possible solution
Since .hide()-ing an element triggers the "mouseleave"-event you could do something funky like hiding the link on click, and showing it just a moment later.
$('a[data-details]').click(function() {
var $this = $(this);
$this.hide();
setTimeout(function() {
$this.show()
}, 1);
});
Setting the timeout to 1 ms would not create any flickering of the link, making the hide/show unnoticeable for the user.
Works in Chrome. Try it here: https://jsfiddle.net/cyx6528e/1/
Good luck!
tooltip usually works on hover functionality, can you provide js fiddle for your problem

How to add a "pin it" button dynamically?

I'm trying to optimize my Wordpress install - and one of the culprits I'm seeing, is the "Pin It" button widget for Pinterest. I'm now trying to find a way to dynamically load the JS code (when they initially hover over the button), and then apply it to the page. So far I've only managed to get this far:
jQuery(document).on("mouseenter click",'.pinItSidebar', function() {
jQuery.getScript("http://assets.pinterest.com/js/pinit_main.js", function() {
// do something here?
});
});
I can't seem to find a function that I can call (as a callback, after the JS is loaded). Obviously I will only do this once per page load (the above is just a very basic version at the moment)
Does anyone have any suggestions on how I can achieve this? The end game of how I want it to function, is with:
Working solution:
Here is a working solution I've now got, which will allow you to load the pinterest stuff ONLY when they click the button (and then trigger the opener as well). The idea behind this, is that it saves a ton of Pinterest JS/CSS / onload calls, which were slowing the page down.
jQuery(document).on("click",'.pinItSidebar', function() {
if (typeof PinUtils == "undefined") {
jQuery.getScript("http://assets.pinterest.com/js/pinit_main.js", function() {
PinUtils.build();
PinUtils.pinAny();
});
} else {
PinUtils.pinAny();
}
});
...and just call with:
foo
Hopefully this helps save someone else some time :)
Extra tweak: I'm just playing around, to see if I can make this even more awesome :) Basically, I want to be able to decide which images are pinnable. Below this will do that for you:
jQuery("img").each(function() {
if (jQuery(this).data('pin-do')) {
// its ok, lets pin
} else {
jQuery(this).attr('nopin',"1");
}
});
All you need to do to make an image pinnable, is have the data-pin-do="1" param set the images you want to allow them to share :)

Preventing everything but a specific element

I have a page which has a droppable element a1, as well as a specific element a2 which is sortable. Files dropped into a1 are read and deposited into a sortable list in a2. The upload and sortable scripts are not included in my code below as they are not relevant to the issue.
The problem is that if any file is dropped anywhere into other than a1, the browser will attempt to open the file for display in the browser. This is quite evident with image files..
I have tried to disable everything but a1 with the following code, but this still does not appear to have worked, I'm still getting the unwanted redirect...
I've Googled my butt off here, but it seems there's a lot about adding drag and drop, but very little with respect to preventing drag and drop...
Can someone please tell me what I am doing wrong here with the following code?
<div id="a1"></div>
<div id="a2"></div>
<script>
drop = $("not(#a1)");
drop.droppable("option",{disabled:true, tolerance:"pointer"});
drop.droppable("disable");
drop.on("drop",function(e){
e.preventDefault();
}
</script>
Many thanks in advance!
I created a simple JsFiddle to make it work. Basically you can cancel the event with a handler on the document itself, without worrying about where the file was dropped:
$("#a1").on('drop', function() {
// your logic here
alert('dropped on a1!');
});
$(document).on('drop dragover', function(e) {
e.preventDefault();
});
If you are using an older version of jQuery, you might have to replace the on function with live.
You have used wrong jQuery selector for not.
Try this
drop = $("div").not("#a1");
After enough tinkering I managed to come up with a more suitable solution...
Seeing I'm only really focusing on the prevention of files being dropped into sortable area, I decided to focus on determining the nature of the item being dropped...
drop = $(".all-slides");
drop.on('dragover', function(e){
e.preventDefault();
});
drop.on('dragenter', function(e){
e.preventDefault();
});
drop.on('drop', function(e){
e.preventDefault();
dt = e.originalEvent.dataTransfer;
if(dt.types != null && (dt.types.indexOf ? dt.types.indexOf('Files') != -1 : dt.types.contains('application/x-moz-file'))) {
alert('You cannot upload images here. \nIf you wish to upload files, \nclick on the "Upload Images" button.');
}
});
Put simply, the drop event listens for any possibility of data transfer, and if there is no data transfer possible, we know it's a DOM element... Otherwise we know it's a file, and we throw the alert...

NivoSlider - Disable Right Click

I have been asked to put in place disabling of the right clicks on a website, I've informed them there is so many ways that people can still download the images via Google Images, Cache, Firebug etc etc, but none the less my arguments have gone ignored and they insist this must be done.
Any, I've put in the footer some code that disables right clicking on all elements using <IMG src=""> this fails to work on NivoSlider, I did change the script to use window load on disabling the right click which works but after slide1 it stops working and I assume this is something to do with changes to the DOM.
JavaScript is by far my weakest point and I'm hoping that someone without to much trouble can either give me a full working solution or something to go on. Thanks in Advance.
They are using NivoSlider with the following trigger:
<script type="text/javascript">
(function($) {
$(window).load(function() {
$('#slider').nivoSlider();
});
})(jQuery);
</script>
And this is the code that I've placed in the footer that fails to work on slide2+
<script>
$(window).load(function() {
$('img').bind('contextmenu', function(e) {
return false;
});
});
</script>
You're absolutely right with the DOM changes. You need to delegate the event to a parent element.
Try something like this:
$('#slider').delegate('img', 'contextmenu', function(e) {
return false;
});
Or this if using jQuery > 1.7:
$('#slider').on('contextmenu', 'img', function(e) {
return false;
});
You might be able to do it by preventing the default behaviour of a right click on the image.
See this answer: How to distinguish between left and right mouse click with jQuery

How does one disable Caching in jQuery Mobile UI

Tried...
<div data-role="page" data-cache="30">
<div data-role="page" data-cache="never">
<div data-role="page" data-cache="false">
<div data-role="page" cache="false">
Nothing seemes to work... so at the moment I'm fixing the problem on the server-side via...
.'?x='.rand()
.'&x='.rand()
I don't want to disable the AJAX just the caching. There has to be a better way though... am I missing something?
Thanks,
Serhiy
Thank you for the answers guys, and even though they didn't quite work for me they did point me in the direction to find the code I was looking for.
This is the code that I found on this gentleman's Github Gist.
https://gist.github.com/921920
jQuery('div').live('pagehide', function(event, ui){
var page = jQuery(event.target);
if(page.attr('data-cache') == 'never'){
page.remove();
};
});
There is also a back button code in that Gist, but I don't seem to need it really as my back button seems to work just fine...
Page caching is now off by default in jQM RC1. See the extract below from the jQM website about page caching: http://jquerymobile.com/demos/1.0rc1/docs/pages/page-cache.html
If you prefer, you can tell jQuery Mobile to keep previously-visited pages in the DOM instead of removing them. This lets you cache pages so that they're available instantly if the user returns to them.
To keep all previously-visited pages in the DOM, set the domCache option on the page plugin to true, like this:
$.mobile.page.prototype.options.domCache = true;
Alternatively, to cache just a particular page, you can add the data-dom-cache="true" attribute to the page's container:
<div data-role="page" id="cacheMe" data-dom-cache="true">
You can also cache a page programmatically like this:
pageContainerElement.page({ domCache: true });
The drawback of DOM caching is that the DOM can get very large, resulting in slowdowns and memory issues on some devices. If you enable DOM caching, take care to manage the DOM yourself and test thoroughly on a range of devices.
Have you tried to overwrite the default value ?
$(document).bind("mobileinit", function(){
$.mobile.page.prototype.options.domCache = false;
});
This works for me
Method 1
This disables AJAX
Read
http://jquerymobile.com/demos/1.0a2/#docs/api/globalconfig.html
Set ajaxLinksEnabled to false and it will not load and cache those pages, just work as normal links.
Method 2
Second idea is to remove cached elements. You can bind to pagehide event and make it remove the page instead. If not present in DOM, the page will be loaded again.
It can be done with this code as a proof of concept:
$('.ui-page').live('pagehide',function(){ $(this).remove(); });
But it needs a little work. The above code breaks the history. It prooves that you will only be able to use it with pages you intend to be leaves in your sitemap tree. Therefore you have to create a special selector for them or bind it to only certain pages.
Also you can bind to a button's click or mousedown event, get its href, generate page id out of it and find the div by id to remove it before jqm tries to look for it.
I have found no advised way of disabling the cache or forcing loading.
Martin's answer should be the right one in my opinion but jQuery Mobile cache the first page no matter what. https://github.com/jquery/jquery-mobile/issues/3249
I've opted to "patch" the behaviour of $.mobile.page.prototype.options.domCache = false and data-dom-cache="true"
$(document).on('pagehide', function (e) {
var page = $(e.target);
if (!$.mobile.page.prototype.options.domCache
&& (!page.attr('data-dom-cache')
|| page.attr('data-dom-cache') == "false")
) {
page.remove();
}
});
Here's my working solution:
$('.selector').live( 'pagebeforecreate', function () {
$.mobile.urlHistory.stack = [];
$.mobile.urlstack = [];
$( '.ui-page' ).not( '.ui-page-active' ).remove();
});
I wrote an (original in German) article about that topic, maybe that helps.
Link to google translated article

Categories

Resources