Switch click and hover events based on width - javascript

I want to toggle events based on width. for mobile only click event should work. for desktop hover event should work. while page loading my code working properly when resize my code is not working.
please help me why my code is not working. Thanks in advance
$(document).ready(function(){
function forDesktop(){
$(".popover-controls div").off('click');
$(".popover-controls div").on('hover');
$(".popover-controls div ").hover(function(e){
//popup show code
});
}
function forMobile(){
console.log("mobile");
$(".popover-controls div").off('hover');
$(".popover-controls div").on('click');
$(".popover-controls div").click(function(e){
//popop show
});
}
function process(){
$(window).width() > 600?forDesktop():forMobile();
}
$(window).resize(function(){
process()
});
process();
});

Its very simple, 1st you cant write this much of code for every event. We have to come up with very simple solution, here is how it works
1st check the width of the Page in JS and assign Desktop/Mobile Class on body :
function process(){
if( $(window).width() > 600){
$("body").removeClass("mobile").addClass("desktop");
}else{
$("body").removeClass("desktop").addClass("mobile");
}
}
$(window).resize(function(){
process()
});
Now, you have execute the command for hover and click:
$(document).on('mouseover', 'body.mobile .popover-controls div',function(e){
alert("hover");
});
$(document).on('click', 'body.desktop .popover-controls div',function(e){
alert("click");
console.log("click");
});
I Hope this will work for you. :)
Check the Js fiddle Example: http://jsfiddle.net/asadalikanwal/xcj8p590/
I have just created for you, also i have modified my code

You could use a JavaScript Media Query to determine the width of the screen as detailed here.
var mq = window.matchMedia( "(min-width: 500px)" );
The matches property returns true or false depending on the query result, e.g.
if (mq.matches) {
// window width is at least 500px
} else {
// window width is less than 500px
}

First Detect the Mobiles/Tablets Touch Event:
function is_touch_device() {
return 'ontouchstart' in window // works on most browsers
|| 'onmsgesturechange' in window; // works on ie10
};
Then Try like this:
function eventFire() {
var _element = $(".popover-controls div");
// True in Touch Enabled Devices
if( is_touch_device() ) {
_element.click(function(e) { .... });
}
else {
// apply Hover Event
_element.hover();
}
}
No need to detect width of devices ;)
There is one more solution with third party and Most popular library is Modernizr

This worked for me. It's a combination of the matchMedia() functionality #Ḟḹáḿíṅḡ Ⱬỏḿƀíé shared as well setTimeout() functionality #Jeff Lemay shared at TeamTreeHouse.com
The primary thing I contributed to was the use of the .unbind() functionality. It took me quite a while to figure out that this was necessary so the .hover() and .click() functions don't cross wires.
//Add/remove classes, in nav to show/hide elements
function navClassHandler(){
if($(this).hasClass('active')){
$('.dropdown').removeClass('active');
}else{
$('.dropdown').removeClass('active');
$(this).addClass('active');
}
}
function handleNav() {
//instantanteous check to see if the document matches the media query.
const mqM = window.matchMedia('(max-width: 1025px)');
const mqD = window.matchMedia('(min-width: 1025px)');
$('.dropdown').unbind(); //necessary to remove previous hover/click event handler
if (mqM.matches) {
console.log("Handling mobile");
$('.dropdown').click(navClassHandler);
} else {
console.log("Handling desktop");
$('.dropdown').hover(navClassHandler);
}
}
// we set an empty variable here that will be used to clearTimeout
let id;
/* this tells the page to wait half a second before making any changes,
we call our handleNav function here but our actual actions/adjustments are in handleNav */
$(window).resize(function() {
clearTimeout(id);
id = setTimeout(handleNav, 500);
});
//As soon as the document loads, run handleNav to set nav behavior
$(document).ready(handleNav);

Related

jQuery Scroll function for a web page is not working out?

I am trying to set scroll for a web page but it's not working out properly.
What I want is that when someone scroll to the middle of the or at least a little up before the footer element so I want to trigger scroll event and then wait for like 10 to 15 seconds as on triggering the scroll event the data is loaded through ajax which takes time and then each time to do so when someone goes down again to the footer so again the scroll function should get triggered.
What I am working now with is as follows but I want to enhance it to the above requirements :
$(document).on('scroll', function() {
if($(this).scrollTop()>=$('footer').position().top){
$('div#load_more').click();
}
});
Use $(window) instead of $(document)
// helper function does exactly what it says
function sleep (time) {
return new Promise((resolve) => setTimeout(resolve, time));
}
var $canfetch = true;
$(window).on('scroll', function(e) {
var scrollHeight = $(window).scrollTop();
var scrollPosition = $(".highlight")[0].offsetTop;
// if user has reached bottom of page the sleep function for next scroll event will be fired.
if (scrollPosition-scrollHeight <= 0) {
if($canfetch) {
console.log("ajax call here");
}
$canfetch = false;
// sleep function usage
sleep(15000).then(() => {
alert("15 seconds have passed");
// return to top of page
$(window).scrollTop(0);
$canfetch = true;
});
}
});
.ok {
height:500px;
}
.highlight{
height:20px;
text-align:center;
background-color:yellow;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="ok"></div>
<div class="highlight">Reference Point</div>
<div class="ok"></div>
I just did a jsfiddle test of your code and had following observations:
a. Assuming the footer is in a div
if you are using class='footer' then you have to use
$('.footer').position().top
If you are using id='footer' then you have to use $('#footer').position().top
b. I added console.log($(this).scrollTop() + '~~footer positon top is '+ $('.footer').position().top); and found that the condition is never met.
1671~~footer positon top is 1868 when I scrolled all the way down.
Hope this helps a bit.
Side Note: You might want to consider a cool plugin called ajax load more to achieve similar feature.
Use the below function use $(window) instead of $(document):
$(window).on('scroll', function(e) {
alert("Scrolled");
});

.delay() not working on my .show() JQuery

I'm trying to make my footer disappear when on a mobile device and only when the keyboard is open. Which I have working perfectly, however the issue is that the footer reappears before the keyboard has time to close. Which is because I'm using the event from the textbox having focus not the keyboard being open. So I thought the best way to resolve this is with a .delay() however, this isn't working at all. Anyone have any ideas here?
<script>
var isMobileView = false; //global variable
$(document).ready(function () {
function setScreenWidthFlag() {
var newWindowWidth = $(window).width();
if ( $(window).width() > 600) {
isMobileView = false;
}
else {
isMobileView = true;
}
}
$(".tbinputArea").focus(function() {
if(isMobileView)
$("#footer").hide();
});
$(".tbinputArea").focusout(function() {
if(isMobileView)
$("#footer").delay(500).show();
});
setScreenWidthFlag();
$(window).on("resize", function (e) {
setScreenWidthFlag();
});
});
</script>
$("#footer").delay(500).show(0);
Try this.
refer this explanation precisely explained the reasons for it http://www.mattlunn.me.uk/blog/2012/06/jquery-delay-not-working-for-you/
Delay is just for queue delay not any event delay so try to add some events within like fadeIn or similar.

Firing multiple Events on JQuery Resize

I have been using the JQuery Code below to handle a little bit of responsiveness for a menu on a Drupal site. In the two commented lines in the resize function, I am essentially trying to enable and disable the opposite events dependent on the screen size. My first question would be since this handler triggering would be in the resize function, would it cause any kind of significant performance hit to attempt something like this? My second question would be how? I've been trying to use the on and off functions to enable/disable those handlers as needed, but I don't think I'm getting the overall syntax correct. I figure it would be best to break the existing event handlers into functions, but have left them as is for the code example.
jQuery(document).ready(function($) {
$('.nav-toggle').click(function() {
$('#main-menu div ul:first-child').slideToggle(250);
return false;
});
if( ($(window).width() > 600) || ($(document).width() > 600) ) {
$('#main-menu li').mouseenter(function() {
$(this).children('ul').css('display', 'none').stop(true,
true).slideToggle(1).css('display',
'block').children('ul').css('display', 'none');
});
$('#main-menu li').mouseleave(function() {
$(this).children('ul').stop(true, true).fadeOut(1).css('display', 'block');
})
}
else {
$('.drop-down-toggle').click(function() {
$(this).parent().children('ul').slideToggle(500);
});
}
$(window).resize(function() {
if($(window).width() > 600) {
$('div.menu-navigation-container ul.menu').css('display','block');
$('div.menu-navigation-container ul.menu ul.menu').hide();
//**Disable dropdown click and enable mouse enter and mouse leave**
}
else{
$('div.menu-navigation-container ul.menu').hide();
//**Disable mouse enter and mouse leave but enable dropdown click**
}
});
});
Use a throttle function
function throttle (callback, limit) {
var wait = false; // Initially, we're not waiting
return function () { // We return a throttled function
if (!wait) { // If we're not waiting
callback.call(); // Execute users function
wait = true; // Prevent future invocations
setTimeout(function () { // After a period of time
wait = false; // And allow future invocations
}, limit);
}
}
}
$(window).on('resize', throttle(yourResizeFunction, 200))
Read why here: http://www.paulirish.com/2009/throttled-smartresize-jquery-event-handler/
As I said, move your event binding outside of the resize function as binding event handlers within resize/scroll is not a good idea at all as you'd bind the same event over and over for every pixel resized!.
An example would look like this:
$(document) // or you can even use 'div.menu-navigation-container' as opposed to document
.on("click", ".click", function() {})
.on("mouseenter", ".hover", function() {})
.on("mouseleave", ".hover", function() {});
$(window).resize(function() {
//A bit of breathing time when the resize event pauses. Remember, the statements within the resize will trigger for every pixel resize, otherwise.
setTimeout(function() {
if( $(window).width() > 600 ) {
$('div.menu-navigation-container ul.menu').css('display','block');
$('div.menu-navigation-container ul.menu ul.menu').hide();
//I am assuming your selector on which the events are bound to be '.menu-trigger' as you did not post any HTML. Replace this with the appropriate selector.
$(".menu-trigger").removeClass("click").addClass("hover");
}
else{
$('div.menu-navigation-container ul.menu').hide();
//I am assuming your selector on which the events are bound to be '.menu-trigger' as you did not post any HTML. Replace this with the appropriate selector.
$(".menu-trigger").removeClass("hover").addClass("click");
}
}, 250);
});
Hope that helps.

Two javascript functions won't work at the same time

I have one script that shows a tooltip on click and the other script shows a menu after a certain point in the page.
If the menu doesn't load, then I can click on the buttons to show the tooltips just fine. But when the menu does show up, the tooltips script doesn't show anymore.
<script>
$(document).ready(function() {
$('#left-tooltip').click(function() {
$('#lollefttooltip').toggle();
});
});
$(document).ready(function() {
$('#right-tooltip').click(function() {
$('.right-tooltip').toggle();
});
});
</script>
<script>
$(function() {
$(window).scroll(function() {
if ($(this).scrollTop() > 650) {
$("#nav-block:hidden").css('visibility', 'visible');
$("#nav-block:hidden").fadeIn('650');
$("#nav-wrap:hidden").css('visibility', 'visible');
$("#nav-wrap:hidden").fadeIn('650');
$("#header-wrap:hidden").css('visibility', 'visible');
$("#header-wrap:hidden").fadeIn('650');
} else {
$("#nav-block:visible").fadeOut("650");
$("#nav-wrap:visible").fadeOut("650");
$("#header-wrap:visible").fadeOut("650");
}
});
});
</script>
Thanks in advance for the help!
update: Here is all the code I have for this. http://jsfiddle.net/parachutepenny/82J6G/11/
I'm sorry in advance for any beginner errors that I may have all over the place. I'm still learning how to code.
This doesn't answer your question, but there are some great opportunities to optimize here. Aside from best practice, they may also sort out the bugginess. Something like:
$(document).ready(function() { // combine doc.ready
var win = window, // store window as a variable
$bod = $('body');
$('#left-tooltip').click(function() {
$('#lollefttooltip').toggle();
});
$('#right-tooltip').click(function() {
$('.right-tooltip').toggle();
});
$(win).scroll(function() {
if (win.scrollY > 650) { // use scrollY from window variable so you're not retrieving from the DOM
$bod.addClass('navVisible'); // use classes on body to trigger CSS transitions on the children
} else {
$bod.removeClass('navHidden');
}
});
});
Put your multiple click function into single ready function.It may cause readability problem.
Follow this link.
Multiple document.ready() function

Resize script appends object, does it over and over again

I have the following code in a JavaScript file:
$(document).ready(function() {
detectscreen();
});
$(window).resize(function(){
detectscreen();
});
function windowWidth() {
if(!window.innerWidth) {
// user is being a git, using ie
return document.documentElement.clientWidth;
} else {
return window.innerWidth;
}}
function detectscreen() {
if (windowWidth()>1280) {
$('body').append('<div id="gearsfloat"></div>');
}}
Basically, what it does is append an object to the end of the document if the width is less than 1280 pixels, however what this does is append it every single time the page is resized.
I don't think I can use the once function because it would only run it once and then the next time it is resized, it's dead. Anything I can do?
NOTE: I, in fact, DO want it to be checked on the resize of the page, but the effect is that it happens over and over again.
if (windowWidth()>1280 && !$('gearsfloat')) {
$('body').append('<div id="gearsfloat"></div>');
}
The above (by Jason) works does not work but then it won't delete it when it gets less than 1280. Is there anything I can do?
Keep track of whether the element exists or not, and add/remove it when the condition changes. That way you will only add it once, it will be removed when it shouldn't be there, and you don't do any unneccesary adding or removing:
var gearsExists = false;
function detectscreen() {
var shouldExist = windowWidth() > 1280;
if (shouldExist != gearsExists) {
if (shouldExist) {
$('body').append('<div id="gearsfloat"></div>');
} else {
$('#gearsfloat').remove();
}
gearsExists = shouldExist;
}
}
if (windowWidth()>1280 && !$('gearsfloat')) {
$('body').append('<div id="gearsfloat"></div>');
}
Check if the element already exists first?
if you dont want the function to be called when the window is resized, then why are you binding the resize function?
wont the document ready function always be called before the resize function anyway, so you are guaranteed to have your element appended?

Categories

Resources