I am having trouble with jQuery and Safari on an iOS 5 and below devices...
I have a button that onClick toggles a menu, in Safari on iOS 5 and below the menu shows on the first click then closes on the second.. great.. However after that is requires 3 clicks to show the menu again. This does not happen on iOS 6 or on desktop browsers.
I have tried replacing the jQuery toggle() function with the following, but this has not helped.
pull.data('menuState','closed');
$(pull).on('click', function (e) {
if (pull.data('menuState') === 'closed') {
pull.data('menuState', 'open');
currentMenu.show();
} else {
pull.data('menuState', 'closed');
currentMenu.hide();
}
return false;
});
pull and currentMenu are defined higher in my code. The site is built on bootstrap if that is any help.
Turns out iOS 5 was triggering the window.resize function later in my code, not 100% its the best approach but I detected the version number to code around it.
function iOSversion() {
if (/iP(hone|od|ad)/.test(navigator.platform)) {
var v = (navigator.appVersion).match(/OS (\d+)_(\d+)_?(\d+)?/);
return [parseInt(v[1], 10), parseInt(v[2], 10), parseInt(v[3] || 0, 10)];
}
}
Here is what I made to replace toggle function, it seems to work well. just put your needs in function odd and even:
// place this before all of your code, outside of document ready.
$.fn.ToggleFix = function(odd, even) {
return this.each(function() {
var Toggled = false;
$(this).on("click", function() {
if (Toggled) {
Toggled = false;
return odd.apply(this, arguments);
}
Toggled = true;
return even.apply(this, arguments);
});
});
};
//what do you want each toggle to do
function odd() {
$(this).animate({"left": "+=50px"}, "slow");//EXAMPLE
}
function even() {
$(this).animate({"left": "-=50px"}, "slow");//EXAMPLE
}
//call your toggle method like this after creating the function you want above
$(function(){
$("YOUR ELEMENT").ToggleFix(even, odd);
});
jsFIDDLE
Related
I want to create a responsive menu for my website, however, I have a problem : I have two devices (desktop & mpbile phone) with the same HTML but two different JS. I share my problem in few line of code.
eventDesktop = function() {
$('header').click(function() {
console.log('Desktop');
});
};
eventPhone = function() {
$('header').click(function() {
console.log('Phone');
});
};
eventWitch = function() {
if (window.innerWidth > 480) {
eventDesktop();
} else {
eventPhone();
}
};
eventWitch();
$(window).resize(function() {
eventWitch();
});
So, after loading that's ok because only one is load, but after resize there are 2 fonctions for the same element, and I want to have only witch one i need. So here, i want to see on the console only 'Desktop' or 'Phone' but not the 2 both, when i click.
Thanks for reading.
If you have question i can specify my ask.
Greet.
You are binding two events on same element on the resize of window. You could try this
$('header').click(function() {
if(window.innerWidth > 480)
console.log('Desktop');
else
console.log('Phone');
});
So, check everytime when user click on header.
It seems like you creating 2 different Event-Handlers, so he is using both in your case.
Try to .unbind() them:
$(window).resize(function() {
$( 'header' ).unbind( 'click' );
eventWitch();
});
So all Click events will be removed, keep that in mind.
There is another method I didn't tried, but maybe it helps: jQuery multiple click event
As andrea.spot wrote: "You need to make your handler function return false.. it prevents the event from bubbling."
Adding this to your code:
eventDesktop = function() {
$('header').click(function() {
console.log('Desktop');
return false;
});
};
eventPhone = function() {
$('header').click(function() {
console.log('Phone');
return false;
});
};
The last solution would be changing the way of thinking. This means do the Click-Handler and THAN check for the Windows Size. Currently you checking for the Window Size and than calling a Click-Handler, this will always lead to multible Click Handlers, but not if you create one handler and than do the statements.
My text to code:
eventWitch = function() {
$( 'header' ).click( function(){
if (window.innerWidth > 480) {
console.log( 'Desktop' );
} else {
console.log( 'Mobile' );
}
}
};
Does one of this solutions works for you?
try this
eventDesktop = function() {
$('header').unbind('click').click(function() {// here it will removes all old click events assigned to this element.
console.log('Desktop');
});
};
eventPhone = function() {
$('header').unbind('click').click(function() {// here it will removes all old click events assigned to this element.
console.log('Phone');
});
};
eventWitch = function() {
if (window.innerWidth > 480) {
eventDesktop();
} else {
eventPhone();
}
};
eventWitch();
$(window).resize(function() {
eventWitch();
});
I have 3 buttons with hover states which makes a little tooltip appear to describe the button. They work fine but on touchs screen they do not disappear after the user clicks on the button.
So I've tried a few js scripts for checking if a device is a touch device or not. They almost work but they also when I test on IE11 it also gets detected as a touch device. Chrome & Firefox do not get mistaken as a touch device.
Any sugestions?
Her is what I've tried
/*****************************
TOUCH DEVICES HOVER FIX START
****************************/
// http://stackoverflow.com/a/4819886/1814446
function isTouchDevice() {
return 'ontouchstart' in window // works on most browsers
|| 'onmsgesturechange' in window; // works on ie10
};
// http://www.stucox.com/blog/you-cant-detect-a-touchscreen/#poke-it
var hasTouch;
window.addEventListener('touchstart', function setHasTouch () {
hasTouch = true;
// Remove event listener once fired, otherwise it'll kill scrolling
// performance
window.removeEventListener('touchstart', setHasTouch);
}, false);
// https://github.com/Modernizr/Modernizr/blob/master/feature-detects/touchevents.js
define(['Modernizr', 'prefixes', 'testStyles'], function( Modernizr, prefixes, testStyles ) {
// Chrome (desktop) used to lie about its support on this, but that has since been rectified: http://crbug.com/36415
Modernizr.addTest('touchevents', function() {
var bool;
if(('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch) {
bool = true;
} else {
var query = ['#media (',prefixes.join('touch-enabled),('),'heartz',')','{#modernizr{top:9px;position:absolute}}'].join('');
testStyles(query, function( node ) {
bool = node.offsetTop === 9;
});
}
return bool;
});
});
if(bool===true) {
console.log('Touch Device'); //your logic for touch device
jQ( "#btn-1, #btn-2, #btn-3" ).click(function() {
jQ("#btn-1 .tooltip").css('opacity', '0');
jQ("#btn-2 .tooltip").css('opacity', '0');
jQ("#btn-3 .tooltip").css('opacity', '0');
});
}
else {
//your logic for non touch device
}
For IE10+ you can utilize "window.navigator.msMaxTouchPoints"
example code
function isIETouch ()
{
return window.navigator.msMaxTouchPoints == undefined ? false : window.navigator.msMaxTouchPoints;
}
Can someone explain me why this snippet can't work ?
I can't use specific features like window.location, submit(), (instead of trigger()), because this function is bound to elements that are very differents.
$('a, button').bind('click', function(oEvent, oData) {
var oButton = $(this);
var bSkip = (oData && oData.skip);
if(true === bSkip) {
return true;
} else {
oEvent.preventDefault();
//oEvent.stopPropagation();
if(confirm('This is a confirm box')) {
$(oButton).trigger('click', { skip: true });
}
}
});
Thanks in advance ! ;)
In your case even though the click event gets fired the default behavior of the links may not be triggered because of the constraints imposed by the browser
If I understand what you are trying to do correctly(if the action s not confirmed then cancel the default behavior), then you can achieve it by the below... there is no need to fire the event again
$('a, button').bind('click', function (oEvent, oData) {
if (confirm('This is a confirm box')) {
return true;
} else {
oEvent.preventDefault();
}
});
Demo: Fiddle
I have a little code like this:
$("input#checkbox").change(changeCheckbox);
function changeCheckbox() {
var inputCheck = $("input#checkbox"),
button = $("input#button");
if (inputCheck.is(":checked")) {
button.hide();
} else {
button.show();
}
}
This work perfect in all modern Browser and IE 8
But when I use this one with event.preventDefault();:
$("input#checkbox").change(changeCheckbox);
function changeCheckbox(event) {
event.preventDefault(); // <-- Here
var inputCheck = $("input#checkbox"),
button = $("input#button");
if (inputCheck.is(":checked")) {
button.hide();
} else {
button.show();
}
}
or I set return false;
$("input#checkbox").change(changeCheckbox);
function changeCheckbox() {
var inputCheck = $("input#checkbox"),
button = $("input#button");
if (inputCheck.is(":checked")) {
button.hide();
} else {
button.show();
}
return false; // <-- Here
}
then the function only works once and I can do nothing more with this in (only) Internet Explorer 8
Can someone explain to me why this happens?
And i have a lot of other functions and use similar codes with event.preventDefault(); and return false; at the end and there are OK...
I use this jQuery Version: jquery_1.10.1.min.js
Thanks in advance!
Can someone explain to me why this happens?
It's a bug in Internet Explorer (what else). The change event is supposed to be not cancelable, in contrast to click events (see Is event.preventDefault cancelling change events?, jQuery/Javascript: Click event on a checkbox and the 'checked' attribute and Why does preventDefault() on a parent element's click 'disable' a checkbox?). IE8 however does prevent the checkbox from being (un)checked when the change event is canceled. Try it here.
How to work around that? Just remove e.preventDefault() (or return false) from your code. I don't see any reason to use it anyway.
What you want to achieve is to show/hide #button based on the value of #checkbox. You can do it this way. Very less lines of code as compared to your code
$('#checkbox').on('change', function() {
$('#button').toggle(this.checked);
});
FIDDLE
You can add this code for IE8:
if (event.preventDefault) event.preventDefault();
else event.returnValue = false;
Since you are using jQuery you can use the built-in cross-browser event fix:
event = $.event.fix(event);
See: http://www.jquerysdk.com/api/jQuery.event.fix
I want to know how to disable right click on images using jQuery.
I know only this:
<script type="text/javascript" language="javascript">
$(document).ready(function() {
$(document).bind("contextmenu",function(e) {
return false;
});
});
</script>
This works:
$('img').bind('contextmenu', function(e) {
return false;
});
Or for newer jQuery:
$('#nearestStaticContainer').on('contextmenu', 'img', function(e){
return false;
});
jsFiddle example
what is your purpose of disabling the right click. problem with any technique is that there is always a way to go around them. the console for firefox (firebug) and chrome allow for unbinding of that event. or if you want the image to be protected one could always just take a look at their temporary cache for the images.
If you want to create your own contextual menu the preventDefault is fine. Just pick your battles here. not even a big JavaScript library like tnyMCE works on all browsers... and that is not because it's not possible ;-).
$(document).bind("contextmenu",function(e){
e.preventDefault()
});
Personally I'm more in for an open internet. Native browser behavior should not be hindered by the pages interactions. I am sure that other ways can be found to interact that are not the right click.
For Disable Right Click Option
<script type="text/javascript">
var message="Function Disabled!";
function clickIE4(){
if (event.button==2){
alert(message);
return false;
}
}
function clickNS4(e){
if (document.layers||document.getElementById&&!document.all){
if (e.which==2||e.which==3){
alert(message);
return false;
}
}
}
if (document.layers){
document.captureEvents(Event.MOUSEDOWN);
document.onmousedown=clickNS4;
}
else if (document.all&&!document.getElementById){
document.onmousedown=clickIE4;
}
document.oncontextmenu=new Function("alert(message);return false")
</script>
In chrome and firefox the methods above didn't work unless I used 'live' instead of 'bind'.
This worked for me:
$('img').live('contextmenu', function(e){
return false;
});
For modern browsers all you need is this CSS:
img {
pointer-events: none;
}
Older browsers will still allow pointer events on the images, but the CSS above will take care of the vast majority of visitors to your site, and used in conjunction with the contextmenu methods should give you a very solid solution.
The better way of doing this without jQuery:
const images = document.getElementsByTagName('img');
for (let i = 0; i < images.length; i++) {
images[i].addEventListener('contextmenu', event => event.preventDefault());
}
Would it be possible to leave the ability to right click and download just when done a separate watermark is placed on the image. Of course this won't prevent screen shots but thought it may be a good middle ground.
You could try this :
var message="Sorry, right-click has been disabled";
function clickIE() {
if (document.all) {
(message);
return false;
}
}
function clickNS(e) {
if (document.layers || (document.getElementById && !document.all)) {
if (e.which == 2||e.which == 3) {
(message);
return false;
}
}
}
if (document.layers) {
document.captureEvents(Event.MOUSEDOWN);
document.onmousedown = clickNS;
} else {
document.onmouseup = clickNS;
document.oncontextmenu = clickIE;
}
document.oncontextmenu = new Function("return false")
Checkout a demo here
A very simple way is to add the image as a background to a DIV then load an empty transparent gif set to the same size as the DIV in the foreground. that keeps the less determined out. They cant get the background without viewing the code and copying the URL and right clicking just downloads the transparent gif.
This should work
$(function(){
$('body').on('contextmenu', 'img', function(e){
return false;
});
});