I am trying to create a slideToggle navigation only on mobile. However, the settings are also affecting the larger browser sizes. On the large browser, the first child is hidden:
#menu-menu-1 li {
display: block;
}
#menu-menu-1 li:first-child {
display: none;
}
And on mobile, it is reversed. The first child is shown, the rest hidden:
#menu-menu-1 li {
display: none;
}
#menu-menu-1 li:first-child {
display: block;
}
And thus, because the first child is now set to display:block, you can use this slideToggle:
$('#menu-menu-1 li:first-child').click(function(e){
e.preventDefault();
$('#menu-menu-1 li:first-child').siblings().slideToggle();
});
This works fine, until you use it to slide the content back up, and change the browser size back. That makes all the siblings set back to display:none, even though the larger browser media queries has them at display:block .
Is there a way as soon as the browser is expanded, the slideToggle settings are ignored?
This is a module I wrote to help with the problem of triggering javascript when I want it on resize and to help with chekcing the size:
jQuery(function($){
//resize window events
//store the reference outside the event handler:
var $window = $(window);
function checkWidth() {
var windowSize = $window.width();
return windowSize;
}
// Execute on load
checkWidth();
// Bind event listener
//remove console.log from production version
$(window).resize(function(){
console.log('checkWidth: ', checkWidth() + 'px' );
if(checkWidth() >= [yourDesiredWidth]){
//do something
}
});
});
Related
I have a responsive website, with some jQuery code, of which some is the following:
<script>
$(document).ready(function(){
$("#D1000C36LPB3").click(function(){$("#D1000C36LPB3_details").show();});
$("#D1200C36LPB3").click(function(){$("#D1200C36LPB3_details").show();});
$("#D1-3CA36LPB3").click(function(){$("#D1-3CA36LPB3_details").show();});
$("#D1-0CA36LPB3").click(function(){$("#D1-0CA36LPB3_details").show();});
$("#D700S36LPB3").click(function(){$("#D700S36LPB3_details").show();});
$("#D700S24LMB3").click(function(){$("#D700S24LMB3_details").show();});
});
</script>
All of the div elements above (#D1000C36LPB3_details, #D1200C36LPB3_details, #D1-3CA36LPB3_details...) have a CSS display property value of none, so by default they aren't visible until you click on one of the div elements above (#D1000C36LPB3, #D1200C36LPB3, #D1-3CA36LPB3...) and then the corresponding div is displayed.
However, when the jQuery script runs, it sets the corresponding div display value to block. When the viewport's/window's width is smaller than say 400 px, I want the script to display them with position: fixed;.
My suggestion
I've figured out I can display them with fixed position using:
$("#corresponding_ID").css("display", "fixed");
But I still have to not let jQuery run the first script (the one using .show()).
Don't set css styles directly this way. As already commented, use e.g. a .visible class and let css media queries decide. Example:
#media screen and (max-width: 399px) {
.visible {
display: fixed;
}
}
#media screen and (min-width: 400px) {
.visible {
display: block;
}
}
Then, in your click handler, go as follows:
$("#D1000C36LPB3").click(function(){$("#D1000C36LPB3_details").addClass('visible');});
Also, if your details containers all follow that naming scheme with affixing _details to the id, it'd be easier to put all ids in an array and iterate over that:
$(document).ready(function(){
var ids = [ "#D1000C36LPB3", "#D1200C36LPB3", "#D1-3CA36LPB3", "#D1-0CA36LPB3", "#D700S36LPB3", "#D700S24LMB3"];
for (var i = 0; i < ids.length; i++) {
$(ids[i]).on('click', function () { $(ids[i]+'_details').addClass('visible'); }
}
};
Easy way to check for browser width with Jquery:
var width = $(window).width();
if (width >= 1024) {
-- Code to execute here --
}else{
-- Other code to execute here --
}
Then you can adjust the width you are looking and update the >= based on what you want to do.
Let me know if this doesn't make sense.
How can I hide the original draggable element once I start drag?
I tried the transform:translateX(-9999px); method but it acts like visibility: hidden; and I need something like display: none; so in the place where original draggable element was will be populated by other element.
What I've tried:
function dragStart(e) {
setTimeout(function(){
e.target.classList.add('block-hide');
},0);
}
function dragOver(e) {
}
function dragEnd(e) {
e.target.classList.remove('block-hide');
}
https://jsfiddle.net/xkcvpf10/1/
Please resize the preview window in order to see 2 blocks in a row.
Changing your class .block-hide to
.block-hide{
display:none;
}
seems to do the trick
https://jsfiddle.net/xkcvpf10/2/ (tested in chrome)
I want to add a class .custom-menu-bg to sticky menu .custom-menu on scroll, while having overflow: hidden on body. Here's my code :
<script type="text/javascript" src="css/jquery-1.7.2.min.js"></script>
<script type="text/javascript">
var _rys = jQuery.noConflict();
_rys("document").ready(function() {
_rys(window).scroll(function() {
if (_rys(this).scrollTop() > 1) {
_rys('.custom-menu').addClass("custom-menu-bg");
} else {
_rys('.custom-menu').removeClass("custom-menu-bg");
}
});
});
</script>
But this code doesn't work with overflow: hidden on body tag
so I tried :
$('html').on('DOMMouseScroll', function(e) {
var delta = e.originalEvent.detail;
if (delta < 0) {
if ($('body').hasClass('section-element-1'))
$('.custom-menu').addClass("custom-menu-bg");
} else if (delta > 0) {
$('.custom-menu').removeClass("custom-menu-bg");
}
});
But this code only works for Mozilla and it's not a solution even, it's just a temp fix or work-around.
What I want is when I scroll down $('.custom-menu').addClass("custom-menu-bg"); i.e. custom-menu-bg class gets added to custom-menu.
And when I scroll up to the top $('.custom-menu').removeClass("custom-menu-bg"); i.e. custom-menu-bg class gets removed from custom-menu.
The top of body,document,window etcetera is always 0.
And top of my div with class custom-menu also has top: 0 always.
I'm looking for a permanent solution which works on all browsers.
I've reproduced the same effect you wanted HERE.
The only change that I've brought in comparison to your code is that I've made a makeshift body div and applied overflow: hidden on it.
Then, using jQuery, you'll be checking for the scroll event triggered by a wrapper inside the body div - which is in charge of holding the content) - and not by itself (or even document).
$('.wrapper').scroll(function () {
if ($(this).scrollTop() > 0) {
$('.custom-menu').addClass("custom-menu-bg");
} else {
$('.custom-menu').removeClass("custom-menu-bg");
}
});
This is because the makeshift body div has an overflow property set to hidden, and therefore won't generate that particular scroll event (maybe it would if you had the handler registered using browser-specific scroll events). Whereas the inner wrapper div will always have it's height property determined by it's content and is therefore scrollable.
NOTE: jQuery's scroll() is cross-browser, and hence a permanent solution.
You can bind on any id or on class also . its on you for now demo i
am using window .
This single event works for both if you have scroll or not. i.e overflow:hidden or overflow:scroll
$(window).bind('mousewheel DOMMouseScroll', function(event){
if (event.originalEvent.wheelDelta > 0 || event.originalEvent.detail < 0) {
// scroll up
$('.custom-menu').removeClass("custom-menu-bg");
}
else {
// scroll down
$('.custom-menu').addClass("custom-menu-bg");
}
});
.custom-menu {
background-color: black;
height: 100px;
width: 100%
}
.custom-menu-bg{
background-color: green;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="custom-menu">
</div>
Or you can also use this jQuery mousewheel plugin https://github.com/brandonaaron/jquery-mousewheel.
//toggled is class when mobile menu is opened
let moveScroll = '';
window.onscroll = function (e) {
const navBar = document.getElementById('id-of-your-navigation-bar');
if (moveScroll > 0 && navBar.classList.contains('toggled')) {
navBar.classList.remove('toggled');
moveScroll = 0;
} else if (navBar.classList.contains('toggled')) {
moveScroll = 1;
}
};
I'm trying to adapt this JSFiddle to make the menu button on my website hide when I'm at the top of the page and show when I start scrolling down.
I modified the JS to match the CSS on my site. Then I placed it in tags in the head of my page
var $scb = $('<div class="toggle-menu-wrap"></div>');
$('.top-header').append($scb);
var $ccol = $('.content');
$ccol.scroll(function(){
$scb.stop(true,true).fadeTo(500, $ccol.scrollTop() > 10 ? 1 : 0);
});
However, it still doesn't work. Am I making a mistake in how I'm modifying the JS to fit my CSS?
You can include the toggle-menu-wrap element in your HTML from the start. There is no need to insert it using JS.
Write the one line of CSS you need, which is to hide the element from the beginning
.toggle-menu-wrap {
display: none;
}
Your version of jQuery uses 'jQuery' instead of '$' to reference itself. I would also re-write your JS like:
jQuery(document).ready(function() {
fadeMenuWrap();
jQuery(window).scroll(fadeMenuWrap);
});
function fadeMenuWrap() {
var scrollPos = window.pageYOffset || document.documentElement.scrollTop;
if (scrollPos > 300) {
jQuery('.toggle-menu-wrap').fadeIn(300);
} else {
jQuery('.toggle-menu-wrap').fadeOut(300);
}
}
Like #murli2308 said in the comments above, you need to attach a scroll event listener to the window:
$(document).ready(function () {
var $scb = $('<div class="scroll-border"></div>');
$('.above').append($scb);
var $ccol = $('.content');
$(window).scroll(function(){
$scb.stop(true,true).fadeTo(500, $ccol.scrollTop() > 10 ? 1 : 0);
});
})
Wrapping your code in $(document).ready() would also be a good idea.
The reason $ccol.scroll(function() { ... works in that fiddle is because of the CSS:
.content{
height: 200px;
width: 200px;
overflow: auto;
}
Notice overflow: auto;. This causes that specific div to be scrollable. However, on your website, you scroll the entire page, not $ccol. This means the event handler will never fire a scroll event (since $ccol will never scroll).
You might have forgotten to link Jquery.
<script type="text/javascript" src="http://code.jquery.com/jquery-1.8.3.min.js"></script>
Link this inside your head tag incase.....
This should do the job:
$(window).scroll(function(e){
if ($(this).scrollTop() > 0) {
$(".your_element").css("display", "block");
} else {
$(".your_element").css("display", "none");
}
});
I have this initially in my .css stylesheet:
#media only screen and (min-width: 901px){
#main_panel {
width: 750px;
}
}
#media only screen and (min-width: 300px) and (max-width: 900px), handheld {
#main_panel {
width: 500px;
}
}
And then after some user interaction, this jQuery command changes this CSS-value:
$("#collapse").click(function() {
if ((($(window).width()) >= 600) && ($(window).width() <= 900)) {
$("#main_panel").animate({width: "500px"}, 'slow');
}
});
When I resize the window to more than 901px, it still follows the recent declaration by the jQuery and not the CSS-declaration in the stylesheet for 901px.
How to prioritize CSS-declaration when resizing the window?
Or how do you handle this better?
Please don't make me rely to $(window).resize() event forever :) That disregards the CSS.
** EDIT **
If you want to give priority to the CSS and still be able to animate it, what you probably need is this:
http://jsfiddle.net/2Fe22/1/
1) create a "normal" panel class and style it
.panel {width:750px;height:400px}
2) create a collapsed class and style it
.collapsed {width:500px}
3) create a function to read the collapsed and normal widths from the css:
function getClassWidth(aClass) {
return parseInt($("<div />").addClass(aClass).css('width'));
}
4) handle the click by first animating and then (at the end of the animation) add or remove the "collapsed" class to the panel and removing inline styles left by the animation:
var collapsed=false;
$("#collapse").click(function() {
collapsed=!collapsed;
if(collapsed) {
$("#main_panel").animate({width: (getClassWidth('collapsed'))+"px"}, 'slow',afterAnimation);
} else {
$("#main_panel").animate({width: (getClassWidth('panel'))+"px"}, 'slow',afterAnimation);
}
});
function afterAnimation() {
if(collapsed) $("#main_panel").addClass( "collapsed" ).removeAttr("style");
else $("#main_panel").removeClass( "collapsed" ).removeAttr("style");
}
You do this, so if the user resizes the window and the css changes your screen updates correctly.
** OLD POST (for reference) **
If you set sizes with JQuery you may go on setting them this way:
var collapsed=false;
$( window ).resize(calculateNewSizes); // When resized
calculateNewSizes(); // At startup
function calculateNewSizes() {
if(collapsed) {
// if screen width < xxx set elemt width to yyy, etc.. collapsed version
} else {
// if screen width < xxx set elemt width to yyy, etc..
}
}
// This toggles the collapsed state if user clicks on an element
$("#collapse").click(function() {
collapsed=!collapsed;
calculateNewSizes(); // or do the animation here
});
This script should be called as fast as possible after the beginning of all the elements to be resized to avoid a FOUC.
<div class="to be resized">
<script>
//do the $( window ).resize(...) here
</script>
... all other stuff </div>.
Warning, this code is UNTESTED. It is just to show an idea.
Since you are using jQuery Animate, the element style will directly receive width value.
Like this:
<el id="mainpanel" style="width: 500px">
This will always override any css on the element unless you use !IMPORTANT:
width: 100px !IMPORTANT;
http://codepen.io/rafaelcastrocouto/pen/suEHn (DEMO)
Notice that you should avoid that since you won't be able to change this if you need.