execute a jQuery slideUp event when screen width exceeds a certain value - javascript

I am making a responsive site in which I add event listeners to blocks to slide down. If I resize my browser window to become wider I want to execute a slideUp to this blocks so that they're all neatly slided up. Does anyone know how to achieve this?
My jquery function:
function mobileFunctions(){
if($(window).width() < 600){
$(".replace-url").attr('href', '#');
$(".list-categories li").removeClass('click');
categoryActive();
}
}
function categoryActive(){
$(".title-click").click(function(){
var e = $(this).parent("li");
var i = ".list-categories li";
var c = "active";
var d = ".content-category";
if(!$(e).hasClass(c)){
$(i).removeClass(c);
$(i).children(d).slideUp("slow");
}
$(e).children(d).slideDown("slow");
$(e).addClass(c);
});

I believe you are looking for this?
$('window').resize(function() {
var someValue = 1024;
if ($('window').width() > someValue) {
// function here...
}
});

Related

Remove event listener and reset classList toggle on resize

I would like to remove a click event listener on a certain screen size, while resizing browser.
The problem is that the code below works where I refresh the page and desired result is there. However, while resizing the browser, it stays in the state of either being clickable if under the wanted width or being non clickable over the wanted width.
let viewPort = window.innerWidth || document.documentElement.clientWidth;
let dropToggle = document.querySelectorAll(".someparent");
let dropMenu = document.querySelectorAll(".somechild");
for (let i = 0; i < dropToggle.length; i++) {
dropToggle[i].addEventListener('click', function a(event) {
if (viewPort < 786) {
dropMenu[i].classList.toggle("drop");
if (event.dropToggle == 2);
event.stopPropagation();
}
else {
dropToggle.removeEventListener('click', a);
/*update*/
dropMenu[i].classList.remove("drop");
}
/*update*/
window.addEventListener("resize", function() {
viewPort = window.innerWidth || document.documentElement.clientWidth;
}, true);
});
}
So basically, I would need the function to kick in when the browser is being resized without refreshing the page. Any help would be appreciated.
EDIT updated code with partial solution.
New problem: The toggle classList.toggle "drop" remains open if not closed on the smaller width. Adding a classList.remove to the "drop" within the else condition does not work either, this actually removes the function entirely on resize. Is there a way to reset the classList.toggle on resize?
You need to update the value of viewPort every time you resize your window. At the moment viewPort is initialized when you load your page but is never reinitialized again. To do this you can add a resize event listener to your window:
window.addEventListener("resize", function() {
viewPort = window.innerWidth || document.documentElement.clientWidth;
}, true);
You need to define your event listener call outside of your for loop
& pass the callback as a reference in add/remove event listener method.
Also you need to add window.resize event listener (As shown below)
This code should work fine for you
let dropToggle = document.querySelectorAll(".someparent");
let dropMenu = document.querySelectorAll(".somechild");
function a(event) {
dropMenu[i].classList.toggle("drop");
if (event.dropToggle == 2);
event.stopPropagation();
}
for (let i = 0; i < dropToggle.length; i++) {
window.addEventListener("resize", function() {
viewPort = window.innerWidth || document.documentElement.clientWidth;
if (viewPort < 786) {
dropToggle[i].addEventListener("click", a);
} else {
dropToggle[i].removeEventListener("click", a);
}
});
}
Matchmedia can handle this - and allow javascript functions when the media (window) matches the criteria.
References can be found here (https://developer.mozilla.org/en-US/docs/Web/API/Window/matchMedia) and here (https://www.sitepoint.com/javascript-media-queries/)
Effectively its media queries for javascript. And the syntax is essentially the same as for CSS media queries.
// media query event handler
if (matchMedia) {
const mq = window.matchMedia("(min-width: 768px)");
mq.addListener(WidthChange);
WidthChange(mq);
}
// media query change
function WidthChange(mq) {
if (mq.matches) {
// do what you want when window width is at least 768px
} else {
// do what you want when window width is less than 768px
}
}

Javascript doesn't work in firefox and IE/edge

I have a piece of code, that's changing my div background on mousescroll and it's working fine in Chrome and Opera, but it doesn't in Firefox and IE/Edge.
I have two divs, the inner one has a background image that is changing on scroll down, the outer one is simply bigger so there is space to scroll.
In Firefox and IE/Edge, the scroll or doesn't work either skips an image, sometimes even doesn't purceed to scrolling the rest of the content on the website.
http://jsfiddle.net/s6qrfo9n/1/
Any ideas why?
Here it is (and I know it's poorly written, but I'm new to javascript and it does the job):
$(document).ready(function(){
var numberofscroll = 0;
var lastScrollTop = 0;
$("#home").scroll(function(){
var st = $(this).scrollTop();
(st > lastScrollTop) ? numberofscroll++ : numberofscroll--;
console.log(numberofscroll);
console.log(lastScrollTop);
console.log(st);
if (numberofscroll<2){
change_background2(numberofscroll);
}
else if (numberofscroll<3){
change_background3(numberofscroll);
}
else if (numberofscroll<4){
change_background4(numberofscroll);
}
lastScrollTop = st;
});
function change_background2(numberofscroll){
var i;
for (i = 2; i <= 2; i++) {
$("#home").css("background-image","url('images/movie_" + i + ".jpg')");
}
}
function change_background3(numberofscroll){
var i;
for (i = 3; i <= 3; i++) {
$("#home").css("background-image","url('images/movie_" + i + ".jpg')");
}
}
function change_background4(numberofscroll){
var i;
for (i = 4; i <= 4; i++) {
$("#home").css("background-image","url('images/movie_" + i + ".jpg')");
}
}
});
The problem lies in the smooth scrolling feature of firefox and ie (see this question). This causes the jQuery scroll event to fire multiple times every time you scroll, thus the 'missing' images--they are being put in, but then they're replaced so fast you can't see them.
Unfortunately, since you can't disable the smooth scrolling feature on people's browsers, there isn't really a perfect solution to this. The best solution is to debounce your scroll event handler. There are many ways to implement a debounce (google it for some ideas). A simple one would be just toggling a boolean after a timeout and checking it every time you run the function:
var dontHandle = false;
$("#home").scroll(function () {
if (dontHandle) return; // Debounce this function.
dontHandle = true;
window.setTimeout(function() {
dontHandle = false;
}, 400); // Debounce!--don't let this function run again for 400 milliseconds.
});
Here's your updated JSFiddle. You may need to play with the debounce time. Best of luck.
I'd say your code is working as intended but I have a couple thoughts about the scroll event.
The scroll event will only be fired if scrolling actually takes place. Nothing will happen if your div doesn't scroll. You could get around that by using another library, check out this stackoverflow answer for some suggested libraries. Also, keep in mind that the scroll event is extremely sensitive, so the "skipping" of images may simply be a result of scrolling too fast.
I cleaned up your code to make better use of the change_background function.
var numberofscroll = 0;
var lastScrollTop = 0;
$(document).ready(function(){
$("#home").scroll(function(e) {
var st = $(this).scrollTop();
console.log(numberofscroll, lastScrollTop, st);
(st > lastScrollTop) ? numberofscroll++ : numberofscroll--;
//make sure numberofscroll stays in range
if(numberofscroll <= 0) {
numberofscroll = 1;
} else if(numberofscroll > 4) {
numberofscroll = 4;
}
change_background(numberofscroll);
lastScrollTop = st;
});
function change_background(numberofscroll) {
$("#home").css("background-image","url('http://coverjunction.s3.amazonaws.com/manual/low/colorful" + numberofscroll + ".jpg')");
}
});
Your change_background functions have been rolled into one function and numberofscroll will stay within a certain range to ensure the image you want actually exists.
Hope that helps!

How can I set my browser window's scrollbar or a div scrollbar to scroll in increments using animate and scrollTop?

The general idea to the site i am designing is to scroll through a set of menu items horizontally and incrementally underneath a static div that will magnify(increase dimensions and pt size) the contents of a menu items. I don't really need help with the magnify portion because i think it's as simple as adding a mag class to any of the menuItem divs that go underneath the static div. I have been messing with this for a few weeks and the code I have for incrementally scrolling, so far, is this:
$(document).ready(function () {
currentScrollPos = $('#scrollableDiv').scrollTop(120); //sets default scroll pos
/*The incrementScroll function is passed arguments currentScrollPos and UserScroll which are variables that i have initiated earlier in the program, and then initiates a for loop.
-The first statement sets up the variables: nextScrollPos as equal to the currentScrollPos(which by default is 120px) plus 240px(the distance to next menuItem), prevScrollPos as equal to the currentScrollPos(which by default is 120px) minus 240px(the distance to next menuItem).
-The second Statement checks to see if the user has scrolled using var userScroll
-The third statement sets: var CurrentScroll equal to the new scroll position and var userScroll to false*/
function incrementScroll(currentScrollPos, userScroll) {
for (var nextScrollPos = parseInt(currentScrollPos + 240, 10),
prevScrollPos = parseInt(currentScrollPos - 240, 10); //end first statement
userScroll == 'true'; console.log('dude'), //end second statement and begining of third
currentScrollPos = scrollTop(), userScroll = 'false') {
if (scrollTop() < currentScrollPos) {
$('#scrollableDiv').animate({
scrollTop: (parseInt(prevScrollPos, 10))
}, 200);
console.log('scrolln up')
} else if (scrollTop() > currentScrollPos) {
$('#scrollableDiv').animate({
scrollTop: (parseInt(nextScrollPos, 10))
}, 200);
console.log('scrolln down')//fire when
}
}
}
$('#scrollableDiv').scroll(function () {
userScroll = 'true';
_.debounce(incrementScroll, 200); //controls the amount of times the incrementScroll function is called
console.log('straight scrolln')
});
});
I have found a variety of solutions that are nigh close: such as a plugin that snaps to the next or previous div horizontally demo, another solution that also snaps and is based on setTimeout demo, but nothing that nails incrementally scrolling through divs. I also found a way to control the rate at which a user may scroll through the menuItems using debounce which is included in the above code.
The console.logs inside the loop do not fire when I demo the code in jsfiddle which leads me to believe the problem lies within the loop. I'm a noob though so it could be in syntax or anywhere else in the code for that matter. Also in the second demo, i have provided the css for the horizontal static div, but the moment I put it in my html it keeps the js from working.
I would like to write the code instead of using a plugin and any help would be appreciated! Also, thank you ahead of time!
Try this fiddle. Menu container height is 960px to show 4 menu items. "Zoom" div is positioned absolutely at top. When you scroll mouse over this div, menu items shifts to top/bottom. I had to add additional div to bottom to be able to scroll to last 3 menu items. JS code:
jQuery(document).ready(function($){
var current = 0;
var menu = $('.menu-container').scrollTop(0);
var items = menu.find('.menu-item');
var zoom = $('.zoom');
function isVerticalScroll(event){
var e = event.originalEvent;
if (e.axis && e.axis === e.HORIZONTAL_AXIS)
return false;
if (e.wheelDeltaX)
return false;
return true;
}
function handleMouseScroll(event){
if(isVerticalScroll(event)){
var delta = event.originalEvent.wheelDelta * -1 || event.originalEvent.detail;
current += (delta > 0 ? 1 : -1);
if(current < 0)
current = 0;
if(current >= items.length){
current = items.length - 1;
}
menu.stop().animate({
"scrollTop": current * 240
}, 300);
items.removeClass('current').eq(current).addClass('current');
event && event.preventDefault();
return false;
}
}
zoom.on({
"MozMousePixelScroll": handleMouseScroll,
"mousewheel": handleMouseScroll
});
});
Hope it will help.

Menu that fit to the buttom/top of the screen

I saw a cool style/js function (I can tell what it is) that implemented on a side menu.
You know the situation when you have a long center page and one of / both of you sides ends and that leave a blank space? Well this site implemented this thing that just when the user scrool to the place where the side menu end - the menu get absolute postion and doesnt move.
How can I do this?
If you want to see an example you can look here (just scroll and look on the sides)
I believe you can achieve similar effect using this: http://www.wduffy.co.uk/blog/keep-element-in-view-while-scrolling-using-jquery/comment-page-1/ (just making it move with 0 as speed parameter instead of slow, as in the example) and adding conditions about whether the current position fits within the box it is displayed (you can take height of the box - menu being moved on page or box that contains the menu - by using .height() jQuery function).
EDIT:
The page you referenced uses the following JavaScript code to support what you try to accomplish:
<script type="text/javascript">
$(function(){
var seoHeight = $$('dvIndexSeoMaster').height();
seoHeight = (seoHeight > 0) ? seoHeight : 0;
var documentHeight = $(document.body).height() - 120 - seoHeight;
var fixedMode = false;
var hasFixedClass = false;
var leftColElm = $sc('dvFixed');
var leftColPos = leftColElm.offset().top;
var leftColHeight = leftColElm.height();
var rightColElm = $$('dvIndexMasterRightCol');
var rightColPos = rightColElm.offset().top;
var rightColHeight = rightColElm.height();
function scrollElm(elmPos,elmHeight,objElm, cssClass){
var fixedMode = false;
var hasFixedClass = false;
var windowTop = $(window).scrollTop();
(windowTop >= elmPos && (windowTop + elmHeight) < documentHeight) ? fixedMode = true : fixedMode = false;
if( fixedMode){
$(objElm).addClass(cssClass);
hasFixedClass = true;
}else if( (fixedMode == false)){
$(objElm).removeClass(cssClass);
hasFixedClass = false;
}
};
$(window).scroll(function(){
scrollElm(leftColPos,leftColHeight,leftColElm,'make-fixed');
scrollElm(rightColPos,rightColHeight,rightColElm, 'make-fixed');
});
});
</script>
And the make-fixed CSS class has the following definition:
.make-fixed {
position: fixed;
top: 0;
z-index: 200;
}
You can make an element stay in the same place, even as the user scrolls, with the CSS position:fixed property: http://www.w3.org/TR/CSS2/visuren.html#fixed-positioning

Mouseover - mouseout - Javascript

what i'm trying to do:
When a user hovers over an image, a little x (image) should appear in the top right corner. If the user clicks on this little x the image should be deleted and when the user does a mouseout the little x should dissapear. I've tried several things:
html structure is an ul with li's and an image in it
Javascript:
//On all the li's in the ul
$("li",$flickrKeyUlPreview).mouseover(addExternalImage);
var addExternalImage = function(){
//Get the offset of the image the user is hovering over
var offset = $(this).offset();
//Move the little x button to the image
$flickrDetailButton.offset(offset);
//Set it visible
$flickrDetailButton.css("visibility","visible");
//Bind the event for the mouseout
$flickrDetailButton.mouseout(removeExternalButton);
};
var removeExternalButton = function(){
//Hide the little x
$flickrDetailButton.css("visibility","hidden");
};
The reason this doesn't work: When the user hovers over the little image the mouseover is triggered.
I've also tried:
$("li",$flickrKeyUlPreview).mouseover(addExternalImage);
var addExternalImage = function(){
$(this).unbind('mouseover');
var emptyObject = {};
$(this).append($.TemplateRenderer($flickrDetailButton,emptyObject));
$flickrDetailButton = $('#flickr_detail_button',rootel);
$(this).mouseout(removeExternalButton);
};
var removeExternalButton = function(){
$(this).unbind('mouseout');
$flickrDetailButton = $('#flickr_detail_button',rootel);
if ($($flickrDetailButton, $(this))) {
$($flickrDetailButton, $(this)).remove();
}
$(this).mouseover(addDelBtn);
};
This doesn't work that well, the little x starts flickering.
Tried this too:
$("li",$flickrKeyUlPreview).mouseenter(addExternalImage);
var removeExternalButton = function(){
$flickrDetailButton = $('#flickr_detail_button', rootel);
if ($($flickrDetailButton, $(this))) {
$($flickrDetailButton, $(this)).remove();
}
$(this).mouseenter(addExternalImage);
};
var addExternalImage = function(){
var emptyObject = {};
$(this).append($.TemplateRenderer($flickrDetailButtonTemplate,emptyObject));
$flickrDetailButton = $('#flickr_detail_button',rootel);
$(this).mouseout(removeExternalButton);
$flickrDetailButton.mouseleave(removeExternalButton);
};
This gave the same effect, it was still flickering
Does anyone have another idea how to do this (don't need specific codes, concepts are appreciated too ;) ) ?
$('selector').hover(addExternalImage, removeExternalButton);
Replace mouseover and mouseout with mouseenter and mouseleave.

Categories