Remove image from span on screen resize | jQuery - javascript

I am trying to add and remove images from span dependable on screen size.
I have 1 event handler to check the screen size and fire one of the functions if condition is true.
Here is my event handler:
jQuery(window).resize(function() {
var innerWidth = window.innerWidth;
if (innerWidth < 1000) {
ApplyIconsToMobileNav();
console.log("apply icons hit");
} else if (innerWidth > 1000) {
RemoveIconsDesktopNav();
console.log("removed icons hit");
}
});
Here is my apply icons function:
function ApplyIconsToMobileNav() {
var Categories = jQuery(".nav-menu > .nav-mobile > .nav-item > a").find("span:first-of-type");
jQuery(Categories).each(function() {
var Category = jQuery(this).text();
if(Category == "E-Liquid") {
jQuery(this).html("<img src='/media/wysiwyg/purple_icons/e-liquid(32x32).png' />" + Category);
} else if (Category == "E-Cigarette Kits") {
jQuery(this).html("<img src='/media/wysiwyg/purple_icons/e-cigarette(32x32).png' />" + Category);
}
});
};
And here is my remove icons function:
function RemoveIconsDesktopNav() {
var CategoriesImg = jQuery(".nav-menu > .nav-mobile > .nav-item > a").find("span:first-of-type");
jQuery(CategoriesImg).each(function() {
jQuery("img", this).hide();
});
};
I have a lot more images in the navigation but pasted only relevant code. My event listener is working fine, so is the ApplyIconsToMobileNav() function, however, I can't get the RemoveIconsDesktopNav() to work. I know, that I can do exactly the same thing I did in the ApplyIconsToMobileNav() but add style of display: none to the image but I want to select all images from the selected span and hide/remove them.

I am not familiar with this syntax: jQuery("img", this).hide();
However, you could try the following: $(this).find('img').hide();
Alternatively, you can also use .toggle(); instead of .hide(); if you wish to alternate between show/hide.

Instead of jQuery use CSS Media Queries. eg-
This CSS will work only when screen is than 767px that is a normal mobile screen
#media (max-width: 767px){
.class_name img{
display: none;
}
}

Related

How to swap JavaScript event listeners at different screen sizes

I'm building a nav menu where the desktop version shows sub-menus as drop-downs that appear on hover, and the mobile version has accordion style sub-menus that are triggered on click/touch.
I have both of these set up using the (simplified) code below, but I want to be able to swap the event listeners as the browser window is resized. I've been trying to use resizeObserver to remove and re-add the event listeners, but I'm having trouble unbinding the listeners correctly.
const viewportWidth = window.innerWidth;
const menuItems = document.querySelectorAll('[data-menu-item]');
function setupMenu() {
menuItems.forEach((item) => {
const itemHandler = toggleState.bind(null, item);
if (viewportWidth > 960) {
item.addEventListener('mouseover', itemHandler);
item.addEventListener('mouseout', itemHandler);
} else {
item.addEventListener('click', itemHandler);
}
});
}
Instead of swapping listeners on an element, you should use two seperate elements, each with one of the event listeners, and then use a CSS media query to set display: none on the one you want hidden.
Here's an overly simplified example with just CSS, if you really want to use JS for this then you can set the element.style.display property, but using CSS is more performant and will work even when the screen is resized multiple times.
#top-bar {
display: block;
}
#side-bar {
display: none;
}
#media screen and (min-width: 960px) {
#top-bar {
display: none;
}
#side-bar {
display: block;
}
}
<div id="top-bar">top</div>
<div id="side-bar">side</div>

Run function on window resize below specific window size

I have a function that breaks an address down, line by line based on comma separation. I need to only run this when the window is below 750px and return the text to one line above 750px. I have the following function which breaks the text down:
var fixed = $('.location-header > p').text();
var address = fixed.substring(0, fixed.lastIndexOf(',')).replace(/,/g, "<br />") + fixed.substring(fixed.lastIndexOf(','));
$('.location-header > p').html(address);
I'm trying to use .resize() function in jquery, but it doesn't seem to be triggering properly.
When function runs properly, text should look like this:
123 Nowhere Ln
Suite 200
Somewhere, NY 10009
JSFIDDLE: LINK
With Javascript: On resize, you can check the window width with $(window).width() and break/unbreak the address accordingly.
JSFiddle: https://jsfiddle.net/mu1zpvoq/
JSFiddle (ES6 + 1 line functions): https://jsfiddle.net/mu1zpvoq/4/
var fixed = $('.location-header > p')[0].innerHTML.replace('/(,)(?=\s{1}\D{2}[^\s][^\d{5,}])/g', "<br />");
var address = fixed.substring(0, fixed.lastIndexOf(',')).replace(/,/g, "<br />");
function breakAddress () {
$('.location-header > p').html(address)
}
function fixAddress () {
$('.location-header > p').html(fixed)
}
function toggleAddress () {
if ($(window).width() < 750) {
breakAddress()
} else {
fixAddress()
}
}
$(window).on('resize', toggleAddress)
$(document).ready(toggleAddress)
HOWEVER you can definitely just do this with CSS:
HTML:
<p class="address">
<span>123 Nowhere Ln</span>
<span>Suite 200</span>
<span>Somewhere</span>
</p>
CSS:
.address > span
display: block
#media all and (min-width: 750px)
.address > span
display: inline
.address > span:after
content: ', '
It would be better to use CSS media queries (reference) instead of resize callbacks.
You could split the address into separate html elements during the page loaded callback and then change display styles regarding to window's width with media queries.

How to append html element one time when specific screen resolution range occurs?

My html:
<div id="log">
</div>
My jQuery:
$(function() {
var win = $(window);
resizeHandler();
win.resize(resizeHandler);
function resizeHandler() {
if (win.width() <= 700) {
$("#log").append("<div>" + "success" + "</div>");
}
}
});
I want that when a specific screen resolution range occurs, the <div>success</div> element would be displayed one time in the "log" div element. For example: from 1 px to 700 px screen resolution the success must be displayed in the "log" div element one time, and when the screen resolution is out of the 1 px to 700 px range the <div>success</div> must be removed from the "log" div element. How should the code look like?
$(function() {
var win = $(window);
resizeHandler();
win.resize(resizeHandler);
function resizeHandler() {
if (win.width() >= 700) {
if ($('#log').children().length == 0)
$("#log").append("<div class='suc'>" + "success" + "</div>");
} else {
$('.suc').remove();
}
}
});
If you really want to append just one element. But, i would use media queries too, and hide/show desired element...
Based on information provided in the comments, you want a simple media query. No JS required. If that's what you really needed to do then #nevermind's answer was perfect.
Just change your code like this.
HTML:
<div id="log">
<div id="success">Success</div>
</div>
CSS:
#success {
display: none;
}
#media only screen and (max-width: 700px) {
#success {
display: block;
}
}
You could create a boolean variable and set it to true when appending
+ create an else statement in your resizeHandler to cope with the other screensizes.
But in a real world example i would have solved this issue by using CSS mediaqueries.

Jquery Nav Detecting Screen Sizes

I'm encountering a slight problem with my navigation. When I resize my browser to check the mobile menu and click the 'header' a couple times for the dropdown menu, then resize my page back to a tablet or desktop size, my navigation disappears. This problem resolves itself if I delete this segment of code:
if ( width == GetWidth() ) {
return;
}
width = GetWidth();
But I need this section of code so the navigation does not disappear when I scroll down on mobile.
var screensize = document.documentElement.clientWidth;
$(document).ready(function(){
var isMobile = window.matchMedia("only screen and (max-width: 600px)");
if (isMobile.matches) {
$('#mobile_active li a').on('click',function() {
$('.Back a').text('Back');
$('#mobile_active li ul li a').slideToggle(150);
e.preventDefault();
});
}
$(window).resize(function(){
if ( width == GetWidth() ) {
return;
}
width = GetWidth();
if( $(window).width() < 600) {
$('#mobile_active').hide();
} else {
$('#mobile_active').show();
}
});
$('header').on('click', function() {
$('#mobile_active').slideToggle(500);
e.preventDefault();
});
});
Any advice or input would be of great help. Thank you.
I agree you should use media queries and javascript for this type of thing, but I think I have found the cause of your issue.
When in mobile mode you have a click event attached to your <header> with a slideToggle. This slideToggle sets an inline style of display:block; or display:none; on the #mobile_active after it animates; depending on wether its closed or opened. When you resize to desktop size the #mobile_active still has an inline style of display:none; which is why you can not see it any more.
It looks like you may have code to correct this on your resize event:
if( $(window).width() < 600) {
$('#mobile_active').hide();
} else {
$('#mobile_active').show();
}
I think it just needs placed before this code block:
if ( width == GetWidth() ) {
return;
}
width = GetWidth();
Which may be why when you remove it, it works

Responsive Design - how to toggle a menu's visibility

Update
I have a new post here with jsfiddles and a clearer question.
I am attempting to use principles of responsive design to adapt to changing screen size. I have CSS which will hide a vertical menu contained in a div (main-nav-vert) and display a "Menu" button contained in a div (div_menu_toggle) when the browser width drops into a range. There is other div resizing happening, but this code is simplified.
When clicking on the Menu button, js code runs to toggle the menu div (main-nav-vert) by changing its display property.
All works great with the button appearing and the menu being hidden when the browser width shrinks.
Then when clicking on the Toggle Button, the menu is briefly made visible... and then spontaneously disappears again. I have verified that the code to hide the div is not being run (.display = 'none'). Is the menu getting hidden again because the CSS code is always active? If so, how can I accomplish this task? I am looking for a pure js answer, please no jQuery. Thanks.
CSS
/* When screen shrinks to this range, hide Menu, display Menu button */
#media (max-width: 697px) and (min-width: 320px) {
.div_menu_toggle{
display: block;
}
.main-nav-vert{
display: none;
}
}
JS
<script type="text/javascript">
function showmenu() {
var mainnavvert = getElementsByClassName('main-nav-vert');
var i, s, len = mainnavvert.length;
for (i = 0; i < len; ++i) {
if (i in mainnavvert) {
// toggle the menu
mainnavvert[i].style.display = 'block';
} else {
mainnavvert[i].style.display = 'none';
}
}
}
function getElementsByClassName(className) {
if (document.getElementsByClassName) {
return document.getElementsByClassName(className);
} else {
return document.querySelectorAll('.' + className);
}
}
</script>
*not tested but I'm guessing you just need a separate class for display:none and display:block;
then change the class, not the style. something like
if (i in mainnavvert) {
// toggle the menu
mainnavvert[i].className = "show-me";
} else {
mainnavvert[i].className = "hide-me";
}
}
Toggle the display depending of the current state of it.
Something like this might work.
for (i = 0; i < len; ++i) {
var menu = mainnavvert[i];
if (menu.style.display === 'block') {
menu.style.display = 'none';
} else {
menu.style.display = 'block';
}
}
you need to take new class to set active/inactive toggle menu.
css
/* When screen shrinks to this range, hide Menu, display Menu button */
#media (max-width: 697px) and (min-width: 320px) {
.div_menu_toggle{
display: block;
}
.main-nav-vert{
display: none;
}
.main-nav-vert.active{
display: block;
}
}
js
<script type="text/javascript">
function showmenu() {
var mainnavvert = getElementsByClassName('main-nav-vert');
var i, s, len = mainnavvert.length;
for (i = 0; i < len; ++i) {
if (i in mainnavvert) {
// toggle the menu
if(mainnavvert[i].style.display == "block")
removeClass(mainnavvert[i]);
}
else {
addClass(mainnavvert[i]);
}
}
}
}
function getElementsByClassName(className) {
if (document.getElementsByClassName) {
return document.getElementsByClassName(className);
} else {
return document.querySelectorAll('.' + className);
}
}
function addClass(ele) {
var classString = ele.className;
var newClass = classString.concat(" active");
ele.className = newClass;
}
function removeClass(ele)
{
[].forEach.call(ele, function(el) {
el.classList.remove("active");
});
}
});
As you want pure javascript,here it is but code is going very smooth and optimze if you do it with jquery and I don't know why you use for loop if there is only 1 element then you can ignore the loop.

Categories

Resources