jQuery scroll() event doesn't propagate - javascript

I have one wordpress plugin which displays popup on scroll. So I have code like this:
jQuery(window).scroll(function(){
//display popup
});
I have problem with one site. The site has those css rules:
html, body {
overflow: hidden;
}
div#pageWrap {
overflow: scroll;
-webkit-overflow-scrolling: touch;
}
So scroll event is not triggering on window and my popup doesn't work. So in this case I should set scroll event on #pageWrap div instead on window because scroll event doesn't propagate:
jQuery("#pageWrap").scroll(function(){
//display popup
});
My question is can I handle this dinamicaly. I cannot change code of my plugin for each site where I have this problem. Is possible to do something like make scroll event to propagate or to set some failback. Any idea about this will be helpful.

I can't promise that this will accommodate all edge cases, but it should take care of most of them.
JS:
jQuery.fn['any'] = function() {
return (this.length > 0);
};
if (jQuery("html").css('overflow') == 'hidden') {
if (jQuery("body").css('overflow') == 'hidden') {
var scrollElement = jQuery('*').filter(function() { return jQuery(this).css('overflow') == 'scroll'; });
if (!scrollElement.any()) {
var scrollElement = jQuery('*').filter(function() { return jQuery(this).css('overflow-y') == 'scroll'; });
jQuery(scrollElement[0]).scroll(function(){
//display popup
});
}
else {
jQuery(scrollElement[0]).scroll(function(){
//display popup
});
}
}
else {
jQuery("body").scroll(function(){
//display popup
});
}
}
else {
jQuery(window).scroll(function(){
//display popup
});
}
https://jsfiddle.net/hopkins_matt/d0gtqkat/

I don't think there's a global solution for this issue, but maybe you'll find some close solutions.
The close solution in my mind is to find the div element that has (overflow='scroll') and it's width and height are very close to the width and height of the window.
if you found more than one div like that then you need to deal with the deepest div in the DOM.
if you haven't found any div like that, then you deal with jQuery(window) instead.

Related

Hide div when iframe gets to certain height automatically

My users book an appointment on our website which changes the height of an iframe when the iframe has changed height I want to hide the above the iframe automatically. This is what I have so far the limitation is it only works on the following events but I want it to hide the dynamically rather than on page re-size or scroll as these events dont take place
$(window).on('load resize scroll', function() {
if ($(".remove-text").height() >= 582) {
$("#execphp-30, #execphp-47, #execphp-48").hide();
} else {
$("#execphp-30, #execphp-47, #execphp-48").show();
};
});
I use the iframeresizer js plugin to detect dynamically update the height of the iframe
<script>
jQuery(function($) {
$(window).on('DOMSubtreeModified', function() {
if ($(".remove-text").height() >= 582) {
$("#execphp-30, #execphp-47, #execphp-48").hide();
} else {
$("#execphp-30, #execphp-47, #execphp-48").show();
};
});
});
</script>

jQuery .scroll() trigger with window height

I'm trying to trigger a function when the mouse wheel is spun, however the div is the height of the window, therefor isn't scrollable and isn't triggering my function. This is the code I am using to test if it works;
jQuery(document).ready(function($) {
$( document ).scroll(function () {
console.log('it works!');
});
});
You can see the full fiddle here; https://jsfiddle.net/8wr8p4ub/1/
If I change the height to an exact value, it triggers, however how can I achieve this when the element isn't scrollable?
You have to check with mousewheel event here and not document scroll. Since in your case document is not scrolling.
$(window).bind('mousewheel DOMMouseScroll', function(event){
if (event.originalEvent.wheelDelta > 0 || event.originalEvent.detail < 0) {
// scroll up
console.log("scroll up");
}
else {
// scroll down
console.log("scroll down");
}
});
* {
padding: 0;
margin: 0;
}
.hi {
height: 100vh; // Change to 1200px and see the output in the console.
width: auto;
background: #222;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="hi"></div>
You don't need to bother yourself about the scroll once the page content is not so long to bring it out. But from what i saw there, your code is fine, and it will work whenever the content exceeds the minimum page scroll
Better still, you can make use of the mousewheel event in JS
You need to use mousewheel event handler:
$('div').on('mousewheel', function(event){
if(event.originalEvent.wheelDelta / 120 > 0) {
console.log('scrolled up');
} else {
console.log('scrolled down');
}
});

Iphone 5 jquery modal dialog

I have a prob that i think is common on iPhone devices. I have a jquery modal dialog popup and when i scroll on this modal and touch on a select element after touching the done button is scrolls me to the top. By default my modal position is fixed. I found an article that says if you change it to position absolute it will be fixed but actually it does not. Please find below my code and give some help guys. Thanks
j('.modal input[type=text], .modal select').each(function () {
if ('ontouchstart' in document.documentElement) {
var osVar = new UAParser().getOS();
var verticalPos = "";
if (osVar == "iOS") {
j(this).on('focus', function (e) {
verticalPos = j(this).offset().top;
j('.modal').css("position", "absolute");
});
j(this).on('blur', function (e) {
j('.modal').css("position", "fixed");
j(this).scrollTop(verticalPos);
});
}
}
});

jQuery .bind method not activating the second time?

I have an element, which fills the screen. Under that I have another element which does NOT fill the screen but is hidden. So you can't manually scroll to that.
The first element which is filling the screen has the following CSS properties:
header {
position: relative;
height: 100vh;
background-color: green;
}
And the second element has these CSS properties:
#content {
display: none;
position: relative;
height: 1500px;
width: 100%;
background-color: yellow;
}
I use this code to trace the scrolling:
$('header').bind("DOMMouseScroll mousewheel", function(e) {
...
});
Inside this method I check which panel is activated (by a self created boolean) and which direction I'm scrolling to, by doing this:
$('header').bind("DOMMouseScroll mousewheel", function(e) {
var wheelDelta = e.originalEvent.wheelDelta;
if (active === header && wheelDelta <= 0) {
...
}
});
Inside that if statement I give call a method that displays the #content element below it and smoothly scrolls to it, and when its done scrolling it hides the element where we have scrolled from (header). I'm using this piece of code for that:
$('body').bind("DOMMouseScroll mousewheel", function (e) {
event.preventDefault();
var wheelDelta = e.originalEvent.wheelDelta;
$('header').unbind("DOMMouseScroll mousewheel");
if (active === header && wheelDelta <= 0) {
showScrollHide(500, content, 1000, header, 250, function () {
_window.scrollTop(0);
_scrollBackBtn.fadeIn();
active = content;
});
}
});
This works perfectly, whenever I scroll down on the header element while its active. It smoothly scrolls down to the #content element under it.
There I have a button which scrolls back up the page, I have this code for it:
_scrollBackBtn.on('click', function() {
if (active === content) {
active = header;
scrollBackHide(header, content, 500, 250, function() {
window.location = '#';
});
}
});
Which also works perfectly, it scrolls back to the top of the page.
But whenever I try to scroll down again, it doesn't do anything. How does this come?
I had to add $('header').unbind("DOMMouseScroll mousewheel"); to the code, otherwise it looked very ugly in the end result.
Whenever I added $('header').stop(); in the same section, it didn't make any difference.
So my question is. How can this .bind method be used again for the same thing?
Here's a demo if you don't understand what I mean. Whenever you scroll down on the header element, and scroll back up via the button. Its not doing the same again.
You are unbinding your mousewheel handlers when they run once and then never re-binding them, so there are no event handlers in place to react to mousewheel events after you click the button. Re-binding that event handler when you click the button does the trick.
Here is a fiddle that does that and should point you in the right direction.
I pulled your mousewheel handler out into a function so we can reuse it whenever we need to bind those events:
var handleMouseWheel = function(e){
e.preventDefault();
var wheelDelta = e.originalEvent.wheelDelta;
if (active === header && wheelDelta <= 0) {
$('body').unbind("DOMMouseScroll mousewheel");
showScrollHide(500, content, 1000, header, 250, function () {
_window.scrollTop(0);
_scrollBackBtn.fadeIn();
active = content;
});
}
};
and use that to reattach an event handler when the button is clicked:
_scrollBackBtn.on('click', function () {
if (active === content) {
scrollBackHide(header, content, 500, 250, function () {
window.location = '#';
active = header;
});
$('body').bind("DOMMouseScroll mousewheel", handleMouseWheel);
}
});

Remove JS function at certain screen width

I am trying to remove certain functionality when the screen is at certain widths. I was wondering if you could tell me why this doesn't work?
http://jsbin.com/ALAYOru/1/edit
I remove the 'has-sub-menu' class when the screen goes below 700px but it still executes the mouseover event.
Thanks!
Or this.
function isWindowSmall()
{
if(window.innerWidth < 700px) return true;
else return false;
}
$(".some-btn").on('click',function()
{
if(isWindowSmall()){
//do something for small windows
}
else{
//do something else for big windows
}
});
That is becauase what this is doing is.
$(".has-sub-menu").mouseenter(function(){
$(this).css('background-color','red');
}).mouseleave(function(){
$(this).css('background-color','transparent');
});
This goes and finds all of the elements with the class of .has-sub-menu and then it attaches the event listener, so this listener will be applied forever, what you could do is something like this.
$("body").on({
mouseenter: function(){
$(this).css('background-color','red');
},
mouseleave: function(){
$(this).css('background-color','transparent');
}
}, '.has-sub-menu');
This will check to see if the element has the class every time it is clicked
Demo: http://jsbin.com/ALAYOru/6/edit
Note: in the demo, you might have to make the output window bigger than 720px and then refresh to see the proper effect.
You can add a function to check the screen size and remove the onmouseover event listener.
function check_screen() {
if(window.innerWidth < 700px)
{
whateveryourelementiscalled.removeEventListner('onmouseover', //whatever your mouseover function was);
}
}
try this.
window.onresize = function () {
if(window.innerWidth < 700) {
// your code here
}
}

Categories