Remove element at specific screen width with jquery? - javascript

I'm building a responsive site with a mobile first approach where i need to add a html element when the screen is larger than 641px and remove when less. The problem i'm having is when i resize my screen larger than 641px the code produces infinite numbers of said element and when i reduce the screen size there is masses amounts of space when they are removed.
my code looks like this:
<script>
$(function () {
$(window).resize(function () {
if ($(window).width() > 641) {
$('.project_nav').append('<li><a class="work_grid" href="#"><img src="images/noun_project_5193.svg"/> </a></li>');
} else {
$('.work_grid').remove();
}
});
});
</script>
And here's the html i want to append:
<div class="project_nav">
<ul>
<li><a class="up_arrow" href="#"><img src="images/noun_project_6978.svg"/> </a></li>
<li><a class="prev_arrow" href="#"><img src="images/noun_project_6976.svg"/> </a></li>
<li><a class="next_arrow" href="#"><img src="images/noun_project_6977.svg"/> </a></li>
</ul>
</div>
Any help is greatly appreciated!

You need to keep track of if the element has already been added or removed. Easiest way without pounding the dom is to store this in a variable:
$(function () {
var isAdded = false;
$(window).resize(function () {
if (!isAdded && $(window).width() > 641) {
isAdded = true;
$('.project_nav').append('<li class="work_grid_container"><a class="work_grid" href="#"><img src="images/noun_project_5193.svg"/> </a></li>');
} else if (isAdded && $(window).width() <= 641) {
isAdded = false;
$('.work_grid_container').remove();
}
});
});
This way it will only add the element if it hasn't already been added and it will remove it only if it currently exists on the page.
Note: You need to have a selector for the li instead of the a! Otherwise you will keep adding lis. You need to fully remove what you added.

What is happening is that when you resize, you are actually resizing a whole bunch, adding way too many elements. What you want to do is add some sort of Timeout. Here is an example.
$(window).resize(function () {
clearTimeout(window.refresh_size);
window.refresh_size = setTimeout(function () {
//Do stuff
}, 100);
This way, it will only do your code after you have stopped resizing the page for a least 100 ms.

Related

Gif image not animate after refreshing the page

I have some gif images on my website that I want to animate once you scroll to that part of the page. I have some JavaScript code that hides those gifs then shows them once you get to that part of the page. The issue I am having is that those gifs start animating before I scroll to that part of the page. Another issue I am having is that once I refresh the page the gifs will sometimes animate, but I would like them to animate each time the page gets refreshed.
Here is the link to my website: http://lam-parker.github.io/my_portfolio_website/
This isn't all of the gifs but here's is the portion of my html where my gifs are:
<div class="row4">
<h1 id="title3">Software Skills</h1>
<div class="col-md-2 col-sm-4 col-xs-6">
<img src="img/software-skills/photoshop.gif">
</div>
<div class="col-md-2 col-sm-4 col-xs-6">
<img src="img/software-skills/indesign.gif">
</div>
</div>
Here is the .show()/.hide() JavaScript I added to the gifs section:
$(window).scroll(function() {
if ($(window).scrollTop() > 70) {
$('.row4').show("slow");
} else {
$('.row4').hide();
}
});
I would appreciate it if someone could help me. Thanks in advance.
I think the only way to 'control' them would be to reassign the src attribute :
Demo
img {
opacity: 0;
}
$(window).scroll(function() {
var current = $(this).scrollTop(),
path = 'animated.gif',
visible = $('img').css('opacity') != 0;
if (current > 200) {
if (!visible) $('img').attr('src', path).fadeTo(400,1);
}
else if (visible) $('img').fadeTo(0,0);
});
Update - by request some code that makes it possible to loop through all animated gifs :
Pen
$(function() {
var target = $('.anigif'),
path = [], zenith, nadir, current,
modern = window.requestAnimationFrame;
target.each(function() {
path.push(this.src);
});
$(window).on('load resize', storeDimensions).on('load scroll', function(e) {
current = $(this).scrollTop();
if (e.type == 'load') setTimeout(inMotion, 150);
else inMotion();
function inMotion() {
if (modern) requestAnimationFrame(checkFade);
else checkFade();
}
});
function storeDimensions() {
clearTimeout(redraw);
var redraw = setTimeout(function() {
zenith = []; nadir = [];
target.each(function() {
var placement = $(this).offset().top;
zenith.push(placement-$(window).height());
nadir.push(placement+$(this).outerHeight());
});
}, 150);
}
function checkFade() {
target.each(function(i) {
var initiated = $(this).hasClass('active');
if (current > zenith[i] && current < nadir[i]) {
if (!initiated) $(this).attr('src', path[i]).addClass('active').fadeTo(500,1);
}
else if (initiated) $(this).removeClass('active').fadeTo(0,0);
});
}
});
It will reinitiate them when they come into view (bottom and top) and fade them out when leaving the screen. All it needs is for the animated gifs to have a common class, assigned to the variable target. If the page contains only gifs and no other <img> tags you could even use $('img') and leave out the class. Looks like quite a bit of code but it has some debouncing and other optimisation.
B-)
You need to use CSS opacity 1 or 0 to show or hide your element. That is only way from "old-school". Second thing is to use relative position and move out of screen. Also you can resize image from original size to 1x1px to original size but that is a bad way.

Custom Menu collapsing on mobile scroll

I have read similar questions related to my issue, but have not come across a solution. I am working on a menu created by another developer for a new client of mine. The client does not wish to use a jQuery, which I believe would solve my issue, so I am hoping to find an adjustment to my jQuery to get this bug fixed. I have a 2-level menu, and on a mobile device, the menu collapses upon scrolling. I can not figure out how to prevent this from happening, as it does not occur when I test on my PC even at the same width. The jQuery used is triggered on .mouseenter and .mouseleave events, so I believe it might have something to do with that. Anyone have an idea as to how to prevent the menu from collapsing upon mobile scroll without a plugin?
Below is the jQuery used:
var $navItem = $("#main_nav").children("#nav").children("li").children("a");
var $subItems = $($navItem).siblings("ul");
$(function(){
$($subItems).hide();
var width = $(window).width(), height = $(window).height();
if ((width <= 570))
{
$("#main_nav").children("#nav").hide();
}
else
{
$("#main_nav").children("#nav").show();
}
});
$(window).on('load resize', function(){
var width = $(window).width(), height = $(window).height();
if ((width <= 570))
{
$("#main_nav").children("#nav").hide();
}
else
{
$("#main_nav").children("#nav").show();
}
});
$($navItem).mouseenter(function(e){
if ($(window).width() > 570) {
//show submenu
$(this).siblings("ul").show();
}
});
$($navItem).mouseleave(function(){
if ($(window).width() > 570) {
//hide submenu
$(this).siblings("ul").hide();
}
});
$($subItems).mouseenter(function(){
$(this).closest("ul").show();
$(this).closest("ul").siblings("a").addClass("active");
});
$($subItems).mouseleave(function(){
$(this).closest("ul").hide();
$(this).closest("ul").siblings("a").removeClass("active");
});
$(".drop-down-arrow").click(function(e){
e.preventDefault();
$(this).toggleClass("flip");
$(this).parent().siblings("ul").toggle();
});
$(".drop-down-arrow").each(function(){
if($(this).parent("a").siblings("ul").size() <= 0)
{
$(this).closest('.drop-down-arrow').css('display','none !important;');
}
});
HTML:
<ul id="nav" style="display: none;">
<li>Item 1<span class="drop-down-arrow"><img src="/media/199707/arrow-down.png" alt="drop down arrow"></span>
<ul class="child" style="display: none;">
<li>Transmission Repair</li><li>Brake Repair</li>
<li>Engine Repair</li><li>Air Conditioning</li>
<li>Auto Glass Repair</li><li>Window Tinting</li>
</ul>
</li>
<li>Item 2</li>
</ul>
If I understand your problem correctly, .mouseenter sure can cause this, because a touch/drag on mobile is also recognized as a mouse event in websites.
I see you try to filter mobile devices with checking the window's width. It may be wrong on tablets or phones with bigger resolutions.
Maybe you could try using this method in you mouse events:
What is the best way to detect a mobile device in jQuery?

Refresh page when container div is resized

This is a simple and pretty straightforward question:
If media query breakpoints are set at 750px and 970px, using jquery, is it possible to refresh the page after the width of .container div changes on browser resize and how?
You probably want to use a media query instead but, you can listen to a resize event if you really want to do this:
addEventListener('resize', function() {
location.reload();
});
If you want to only reload if a breakpoint is past, you can keep track of the last innerWidth and only reload if a certain value is crossed. Or instead of using innerWidth, use a width of a div. For example:
var last = document.getElementById('mydiv').clientWidth;
addEventListener('resize', function() {
var current = document.getElementById('mydiv').clientWidth;
if (current != last) location.reload();
last = current;
});
<script
src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js">
</script>
<div id="mydiv">
<h1>Page Resize demo</h1>
</div>
<script>
$(window).resize(function ()
{
if ($(window).width() < 700)
{
$("#mydiv").css("background", "red");
}
else
{
$("#mydiv").css("background", "orange");
}
});
</script>

Avoid loading images in mobiles

I want to avoid loading an image on the website when the screen width is lesser than 1146px. I've tried to add the below CSS rule:
#media only screen and (max-width: 1146px) {
#img_cabecera2 {display: none;}
}
And of course, the image is not shown, but it is loaded. I want to load an image only if the screen width s more than 1146px.How could achieve it?
I don't mind if the solution uses CSS, Javascript, jQuery or PHP code.
Edit:
I've achieved it in this way:
template.html:
<div id="img_cabecera2">
<img src="data:image/gif;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs%3D" width="0" height="0" alt="">
</div>
script.js:
$(function(){
/* Set img_cabecera2 size */
function set_src() {
var window_width = $(window).width();
if (window_width < 1147) {
$("#img_cabecera2").css({"display":"none"});
} else {
$("#img_cabecera2 img").attr('width', 300).attr('src', "/public/img/carrete.png").attr('alt', "logo").attr('height','auto');
$("#img_cabecera2").css({"top":"15px","left": "44%","display":"block"});
}
}
set_src();
$(window).resize(function() {
set_src();
});
/* ************************* */
...
I use this:
<!-- This image is a blank, 2*2 image -->
<img src="/images/transparant.png"
data-bigsrc="/images/big.jpg"
data-smallsrc="/images/small.jpg" />
With this as javascript
function getProperImageSource(){
var attr2use = $('body').outerWidth()>480 ? 'data-bigsrc' : 'data-smallsrc';
$('img[data-smallsrc], img[data-bigsrc]').each(function(i){
this.src = this.getAttribute(attr2use);
});
}
$(document).ready({
getProperImageSource(); // load images on init
$(window).on('resize', function(){
getProperImageSource();// again on resize
});
});
Might be handy to know: An image on display: none still loads, you just don't see it.
Also, removing images with (javascript-)functions can be slow aswell, because it can still trigger the downloading of the image, but because you removed the <img/> tag It wont be displayed, kinda a waste of time and resource :)
Add the css display:none; to the image and add this jQuery code:
function set_src() {
var window_width = $(window).width();
if (window_width < 1147) {
$("#img_cabecera2").hide();
} else {
$("#img_cabecera2").attr('src', BIG).show(); // Change to your image link
}
}
$(document).ready(function(){
set_src();
$(window).resize(function() {
set_src();
});
});
To avoid the image to be preloaded unnecessarily, while not just having an default empty src="" (omiting an image source is invalid, as I understand it), I found this post where one of the best solutions was to use this only 26 bytes big default source:
src="data:image/gif;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs%3D"
As has been mentioned, at the moment there is no way of doing this in pure CSS. i have made use of the picturefill script in the past and have found it quite reliable.

Jquery image cycling issues

I'm working on a website for a family friend. On it they wanted to have logos from all their associates on one row, that subtly fade to get replaced with additional logos that didn't fit the first time.
To achieve this i've assigned the <img>'s classes, that represent what cycle they should appear in, depending on how many of those images will fit on the row given its current width. This happens in my assignCycleNumbers function.
Then to actually fade them in and out i have another function called cycleAssociates which recursively fades the appropriate classes in and out. Well in theory, however it doesn't seem to be working properly, which is particularly odd because i tested the function here and it works fine. The only difference between them is that now i'm trying to assign the cycle numbers dynamically.
I'm really stumped and could do with some help!
You can see the website hosted here and if you scroll down to the bottom of the content you'll see the logos at the bottom, not behaving as expected. (First cycle appears okay but then subsequent cycles get muddled, more observable if you resize to a smaller screen width).
You can inspect the code thoroughly through your browser but here's everything you need to know, again i'd really appreciate any insight.
EDIT: The whole javascript file as requested. But all the relevant stuff is below:
JS:
//single global variable to represent how many logo cycles there is
var totalCycles = 0;
...
$(window).load(function() {
...
totalCycles = assignCycleNumbers();
cycleAssociates();
});
// window is resized
$(function(){
$(window).resize(function() {
...
totalCycles = assignCycleNumbers();
});
});
...
function cycleAssociates(){
var cycle = 0;
var recursiveCycling = function(cycle, totalCycles){
var currentAssociate = ".cycle" + cycle;
//fade in all img with the current cyle class over a second,
//wait 3 seconds before fading out over a second.
$(currentAssociate).delay(100).fadeIn(1000).delay(3000).fadeOut(1000,
function(){
cycle++;
if(cycle > totalCycles){
cycle = 0;
}
recursiveCycling(cycle, totalCycles);
});
};
recursiveCycling(cycle, totalCycles);
}
function assignCycleNumbers(){
//first remove any old cycle# classes (resized window case)
$('[class*="cycle"]').removeClass( function(unusedIdx,c){
return c.match(/cycle\d+/g).join(" ");
});
//measure div width
var divSpace = $("#bodies").innerWidth();
//assign a cycle number to a number of logos until no more will fit in that div
var cycleNum = 0;
$(".associate").each(function(){
if( divSpace - $(this).width() > 0){
$(this).addClass("cycle" + cycleNum);
divSpace = divSpace - $(this).width();
}
else{ //next logo won't fit current cycle, create next cycle
cycleNum++
$(this).addClass("cycle" + cycleNum);
divSpace = $("#bodies").innerWidth() - $(this).width();
}
});
return cycleNum;
}
html:
<img class="associate" src="IMG/spare.png" alt=""/>
<img class="associate" src="IMG/bcs_professional.jpg" alt="BCS Professional Member"/>
<img class="associate" src="IMG/climate_savers.jpg" alt="Climate Savers Smart Computing"/>
<img class="associate" src="IMG/code_of_conduct.jpg" alt="Data Centres Code Of Conduct Endorser"/>
<img class="associate" src="IMG/spare.gif" alt=""/>
<img class="associate" src="IMG/enistic.gif" alt="Enistic"/>
<img class="associate" src="IMG/greentrac_authorised.png" alt="Greentrac Authorised Reseller"/>
<img class="associate" src="IMG/very_pc.jpg" alt="Very PC Approved"/>
<img class="associate" src="IMG/spare.jpg" alt=""/>
css:
#bodies img.associate{
float: left;
max-width: 120px;
max-height: 80px;
display:none;
}
The issue is that your fadeOut function's callback is being executed even before all elements in the current cycle are faded out. Here's a modified version of your function that works as expected:
function cycleAssociates(){
var cycle = 0;
var recursiveCycling = function(cycle, totalCycles){
var currentAssociate = ".cycle" + cycle;
var n = $(currentAssociate).length; //How many images in current cycle?
$(currentAssociate).each(function() {
$(this).delay(100).fadeIn(1000).delay(3000).fadeOut(1000, function() {
n --;
if(n <= 0) { //current cycle done?
cycle++;
if(cycle > totalCycles){
cycle = 0;
}
recursiveCycling(cycle, totalCycles);
}
});
});
};
recursiveCycling(cycle, totalCycles);
}
To fix the issues that come up on window resize, try replacing your current $(window).resize handler with this:
$(function(){
$(window).resize(function() {
parallelNavbar();
$(".associate").stop(); //if there are any animations, stop 'em
$(".associate").hide(); //hide all associates
totalCycles = assignCycleNumbers(); //update the assignment
cycleAssociates(); //let's get cyclin' again!
});
});
Although I think you have some issues with scrolling. This should resolve the main cycling problem, though -- so I hope that helped!

Categories

Resources