jQuery duplicating div on resize events - javascript

There is a piece of code inside of a magento view.phtml file that was put there to control an out of stock functionality. It only displays on the page when the product is not saleable.
It works as intended, to a point. However on mobile devices such as an iPad or when the user resizes the viewport (even when inspecting for example) it causes a duplication of the div in question and eventually causes the browser to 'crash' the page.
The code is here:
<script type="text/javascript">
jQuery(document).ready(function () {
jQuery('.sharing-links').appendTo(jQuery('.current_configuration_bottom'));
jQuery('.configured-bundles-wrap').appendTo(jQuery('.current_configuration_bottom'));
function isElementOutViewport(el) {
el = document.getElementById(el);
var rect = el.getBoundingClientRect();
return rect.bottom < 0 || rect.right < 0 || rect.left > window.innerWidth || rect.top > window.innerHeight;
}
function setBuyBox() {
var width = jQuery(window).width();
var right_description = jQuery('.right_description');
var is_iPad = navigator.userAgent.match(/iPad/i) != null;
if (( width >= 998 || is_iPad )) {
right_description.appendTo('.product-sidebar');
right_description.addClass('stick-right');
right_description.css('top', '250px');
var rightContent = jQuery('.current_configuration');
var stick_right = jQuery('#header .container').offset().left
var stick_width = (22 / width) * jQuery('#header .container').outerWidth();
var rightCol_offset_top = right_description.offset().top - 205;
jQuery(window).scroll(function () {
var stop_offset_top = jQuery('#bottom').offset().top - right_description.outerHeight() - 250;
if (jQuery(window).scrollTop() > rightCol_offset_top && jQuery(window).scrollTop() < stop_offset_top) {
if (is_iPad) {
// console.log('case 1');
rightContent.css('top', '200px');
rightContent.css({
'position': 'fixed',
'width': '223px',
'max-width': '100%',
'right': 'auto',
'bottom': 'auto'
});
rightContent.removeClass("stick-right-bottom");
rightContent.removeClass("stick-right");
var footerOutView = isElementOutViewport('footer-container');
var headerOutView = isElementOutViewport('header');
if (!headerOutView) {
rightContent.css({
'position': 'static',
'top': '0',
'bottom': 'auto',
'right': 'auto'
});
}
if (!footerOutView) {
rightContent.css({
'position': 'absolute',
'bottom': '0',
'top': 'auto',
'right': '0'
});
}
} else {
// console.log('case 2');
right_description.css('top', '200px');
right_description.addClass("stick-right");
right_description.removeClass("stick-right-bottom");
rightContent.css('top', '200px');
rightContent.addClass("stick-right");
rightContent.removeClass("stick-right-bottom");
var footerOutView = isElementOutViewport('footer-container');
//console.log(footerInView);
if (!footerOutView) {
rightContent.css('top', 'auto');
rightContent.removeClass('stick-right');
rightContent.addClass('stick-right-bottom');
}
if (is_iPad) {
rightContent.css('top', 'auto');
rightContent.css({
'position': 'absolute',
'bottom': '0',
'top': 'auto',
'right': '0'
});
}
}
} else if (jQuery(window).scrollTop() > stop_offset_top) {
// console.log('case 3');
right_description.css('top', 'auto');
right_description.removeClass("stick-right");
right_description.addClass("stick-right-bottom");
if (is_iPad) {
// console.log('ipad 3');
rightContent.css({
'position': 'absolute',
'bottom': '0',
'top': 'auto',
'right': '0'
});
}
var footerOutView = isElementOutViewport('footer-container');
//console.log(footerInView);
if (!footerOutView) {
rightContent.css('top', 'auto');
rightContent.removeClass('stick-right');
rightContent.addClass('stick-right-bottom');
}
//rightContent.css({'width':'auto', 'position': 'static'});
} else {
// console.log('case 4');
right_description.css('top', 'auto');
right_description.removeClass("stick-right");
right_description.removeClass("stick-right-bottom");
rightContent.css('top', '200px');
var footerOutView = isElementOutViewport('footer-container');
//console.log(footerInView);
if (!footerOutView) {
rightContent.css('top', 'auto');
rightContent.removeClass('stick-right');
rightContent.addClass('stick-right-bottom');
}
if (is_iPad) {
var headerOutView = isElementOutViewport('header');
//console.log(headerOutView);
if (!footerOutView || !headerOutView) {
rightContent.css({'position': 'static', 'top': 'auto', 'width': 'auto'});
}
}
}
});
} else {
// console.log('case 5');
//right_description.appendTo('.product_details');
//right_description.css('top', 'auto');
//right_description.removeClass('stick-right');
}
}
jQuery(window).resize(function () {
setBuyBox();
});
window.onorientationchange = function () {
setBuyBox();
};
setBuyBox();
});
</script>
I have tried a couple of things to get this to stop happening, changing right_description.appendTo('product-sidebar'); to .after however it is still happening.
Im not entirely sure this whole code is necessary to achieve what was originally needed.
Im brushing up on my js/jquery implementation and any pointers on how to clean this code up and fix the issue would be appreciated.

Related

how to run javascript when screen size over certain width size?

I want to run certain javascript only when the window width is over 1024.
The script is long. I've tried to combine them with
if ($(window).width() >= 1024
but it still not working.
Can someone help me?
This is the script I want to run when the width is over 1024 :
<script src="http://code.jquery.com/jquery-1.9.1.js"></script>
<script>
$(window).load(function() {
$(window).on("scroll resize", function() {
var pos = $('#fixPlace').offset();
$('.post').each(function() {
if (pos.top >= $(this).offset().top && pos.top <= $(this).next().offset().top) {
var newDescr = $(this).find('.feature__description').html();
var oldDescr = $("#fixPlace").html();
$('#fixPlace').html(newDescr);
if (newDescr !== oldDescr) {
$("#fixPlace").css('opacity', 0.4).animate({ 'opacity': '1', }, 200);
return;
}
}
});
});
$(document).ready(function() {
$(window).trigger('scroll');
});
});
let fixPlace = '#fixPlace';
let scrollStart = null;
let scrollEnd = null;
let floatBoxTop = 0.25 * $(window).height();
$(document).ready(function() {
scrollStart = $('#fixPlace').offset().top;
scrollEnd = $('.transition').offset().top - 680;
})
$(window).scroll(scroll)
function scroll() {
let scrollTop = $(document).scrollTop() + floatBoxTop;
scrollTop = Math.min(scrollEnd, Math.max(scrollTop, scrollStart))
if (scrollTop === scrollStart || scrollEnd === scrollTop) {
$(fixPlace).css({
position: 'absolute',
top: scrollTop
});
} else {
$(fixPlace).css({
position: 'fixed',
top: floatBoxTop
});
}
}

How to fix a javascript map pop up

We had a developer code this javascript map that has pop-ups when you hover over certain points.
http://www.cadenceaerospace.com/products/aeros/centers_of_excellence/index_test.html
I'm trying to add a new point (B&E) and it should open up the same way that Tell Tool opens up but I can't get it to work. I don't know much javascript so would someone be able to take a look and see what I'm doing wrong?
This is the code on the page that controls the map:
<script language="javascript">
$(document).ready(function() {
$('#loc_map > DIV').css({'display': 'none', 'position': 'absolute'});
$('#loc_map > DIV > DIV').each(function(i,e) {
var close_button = document.createElement('span');
close_button.className = 'close_button';
var button_x = document.createElement('a');
button_x.innerHTML = 'X';
button_x.href = '#';
$(button_x).on('click', function(x) {
//console.log(e.parentNode.id);
$('#loc_map > DIV').css({'display': 'none'});
x.preventDefault();
});
$(close_button).prepend(button_x);
$(e).prepend( close_button );
});
$('#loc_map AREA')
.on('mouseover', function(e) {
e.preventDefault();
var div_id = e.currentTarget.alt,
div = $(document.getElementById(div_id)),
left = (div_id == 'tell_tool_operations')? e.pageX-5 - div.outerWidth() : e.pageX+5,
top = (RegExp(/^(giddens|pmw|tell|be)/).test(div_id))? e.pageY+5 : e.pageY-5 - div.outerHeight();
$('#loc_map > DIV').css({'display': 'none'});
div.css({'display': 'block', 'left': left, 'top': top});
});
$('#loc_map AREA')
.on('click', function(e) {
e.preventDefault();
var div_id = e.currentTarget.alt,
div = $(document.getElementById(div_id)),
left = (div_id == 'tell_tool_operations')? e.pageX-5 - div.outerWidth() : e.pageX+5,
top = (RegExp(/^(giddens|pmw|tell|be)/).test(div_id))? e.pageY+5 : e.pageY-5 - div.outerHeight();
$('#loc_map > DIV').css({'display': 'none'});
div.css({'display': 'block', 'left': left, 'top': top});
});
});
</script>
Let me know if you need anything else from me. Thanks!
The line that calculates the left position needs to be modified from
left = (div_id == 'tell_tool_operations')? e.pageX-5 - div.outerWidth() : e.pageX + 5
...to...
left = (div_id == 'tell_tool_operations' || div_id == 'be_oem')? e.pageX-5 - div.outerWidth() : e.pageX + 5
The added part is || div_id == 'be_oem'.
Modified code
<script language="javascript">
$(document).ready(function() {
$('#loc_map > DIV').css({'display': 'none', 'position': 'absolute'});
$('#loc_map > DIV > DIV').each(function(i,e) {
var close_button = document.createElement('span');
close_button.className = 'close_button';
var button_x = document.createElement('a');
button_x.innerHTML = 'X';
button_x.href = '#';
$(button_x).on('click', function(x) {
//console.log(e.parentNode.id);
$('#loc_map > DIV').css({'display': 'none'});
x.preventDefault();
});
$(close_button).prepend(button_x);
$(e).prepend( close_button );
});
$('#loc_map AREA')
.on('mouseover', function(e) {
e.preventDefault();
var div_id = e.currentTarget.alt,
div = $(document.getElementById(div_id)),
left = (div_id == 'tell_tool_operations' || div_id == 'be_oem')? e.pageX-5 - div.outerWidth() : e.pageX+5,
top = (RegExp(/^(giddens|pmw|tell|be)/).test(div_id))? e.pageY+5 : e.pageY-5 - div.outerHeight();
$('#loc_map > DIV').css({'display': 'none'});
div.css({'display': 'block', 'left': left, 'top': top});
});
$('#loc_map AREA')
.on('click', function(e) {
e.preventDefault();
var div_id = e.currentTarget.alt,
div = $(document.getElementById(div_id)),
left = (div_id == 'tell_tool_operations' || div_id == 'be_oem')? e.pageX-5 - div.outerWidth() : e.pageX+5,
top = (RegExp(/^(giddens|pmw|tell|be)/).test(div_id))? e.pageY+5 : e.pageY-5 - div.outerHeight();
$('#loc_map > DIV').css({'display': 'none'});
div.css({'display': 'block', 'left': left, 'top': top});
});
});
</script>

run jquery function after window resize only for minimum viewport width

I have a problem with my jquery script for block element floating animation.
I want to get floating box only if window width is greater than 1024px.
Code below works fine, but when I open page on desktop resolution(greater than 1024) and resize to less width, scrolling fire the same functions for changing css like on bigger resolutions.
How can I turn off/remove this css changing when window width will be less than 1024px?
Code:
$(document).ready(function() {
function stickyOfferBox() {
var isMobile;
if ($(window).width() > 1024) {
isMobile = false;
var $sticky = $('.career-offer-box'),
stickyOffset = $('.career-offer').offset().top - 80,
stickyOffsetRight = ($(window).width() - ($sticky.offset().left + $sticky.outerWidth())),
stickyWidth = $sticky.width(),
stickyHeight,
stickyStopBreakpoint;
if (!isMobile) {
$(window).scroll(function(){
var scroll = $(window).scrollTop();
if (scroll >= stickyOffset) {
$sticky.css({
'position': 'fixed',
'top': '80px',
'right': stickyOffsetRight,
'width': stickyWidth
});
stickyHeight = $sticky.height(); // We want only floating box height instead of static
stickyStopBreakpoint = $('#contact').offset().top - stickyHeight ;
} else {
$sticky.css({
'position': 'relative',
'top': 'auto',
'right': 'auto',
'width': 'auto'
});
}
if (scroll >= (stickyStopBreakpoint - 160)) {
$sticky.css({
'position': 'absolute',
'top': stickyStopBreakpoint - 80,
'right': $sticky,
'width': stickyWidth
});
}
});
}
} else {
isMobile = true;
return false;
}
}
stickyOfferBox();
$(window).resize(stickyOfferBox);
});
If I understand your code the right way, you simply have to unbind the scroll event from the window.
$(window).unbind('scroll');
you should create a construct like this:
if($(window).width() >= 1025){
$(window).scroll(function(){
/** your function code here **/
});
}else{
$(window).unbind('scroll');
}

Use JQuery to fix element from bottom of window

I found plenty of examples of fixing an element's top relative to the window. How do I fix an element X pixels from the bottom of the window? Simply changing 'top' to 'bottom' does not work (for example,if the element's height is more than the window height)
From the top:
var pixels = 10;
var $elemPosition = $element.position();
var $elementH = $element.height();
var $windowH = $(window).height();
var $bottom = $element.offset().top + $element.height();
if ($(window).scrollTop() + pixels >= $elemPosition.top) {
$element.css({
'position': 'fixed',
'top': pixels + 'px'
});
} else {
$element.css({
'position': 'relative',
'top': '0px'
});
}
Solved it! Solution I came up with:
if (($windowH + $(window).scrollTop() - $bottom - pixels) >= 0) {
$element.css({
'position': 'fixed',
'top': ($windowH - $element.height() - pixels) + 'px',
'width': $eW + 'px',
'height': $eH + 'px'
});
} else {
$element.css({
'position': 'relative',
'top': '0px'
});
}
Use the CSS bottom property instead of the top property.
$element.css({
'position': 'fixed',
'bottom': pixels + 'px'
});
According to your comments and demand :
for example,if the element's height is more than the window height
You wants something like this ?
JS
$element = $("#element");
function setPosition(){
var pixels = 10;
var $elementH = $element.height();
var $windowH = $(window).height();
if ($windowH > $elementH) {
$element.css({
'position': 'fixed',
'bottom': pixels + 'px'
});
} else {
$element.css({
'position': 'relative',
'bottom': '0px'
});
}
}
$(function(){
setPosition();
$(window).scroll(function(){
setPosition();
});
});
If you try to change the height of the element to 700px for instance, you'll see he gets relative position.

$(window).scroll being executed inside if-statement even when it doesn't meet the conditions

I'm using a debounce script as part of a conditional that will add some css to a side menu when a user scrolls a page beyond a certain amount of pixels and then hide the menu when they are a set amount of pixels from the bottom. The script works as intended for screen widths 992px and above (as per conditional if (debounce_bodyWidth >= 992)) but it is still executing for dimensions below this.
Is there something about $(window).scroll that means it is executed irrespective of conditionals?
(function ($) {
contactDebounce = function () {
var debounce_bodyWidth = $(window).width();
if (debounce_bodyWidth >= 992) {
$(window).scroll(function () {
var distanceFromBottom = $(document).height() - $(this).scrollTop();
if (distanceFromBottom <= 1200) {
$('.sticky-element').addClass('hide');
} else if ($(this).scrollTop() >= 150) {
$('.sticky-element').removeClass('hide');
$('.sticky-element').css({
'position': 'fixed',
'top': '15px'
});
} else if ($(this).scrollTop() < 150) {
$('.sticky-element').css({
'position': 'relative',
'top': '0'
});
}
});
}
}
contactDebounce();
$(window).on("debouncedresize", contactDebounce);
})(jQuery);
What you are doing is binding a function to $(window).scroll on page load if the bodyWidth >= 992, this condition is never run again as all that is run on scroll is inside the scroll function you have created.
EDIT: It has been pointed out in comments that this is run again, on debounced resize. The problem then is that the scroll function has already been set when the condition is true and is not unset when the condition becomes false. You can either unset the event and check again on resize or add the condition inside the event and stop running the check on resize.
Try this, adding the condition inside the event:
(function ($) {
contactDebounce = function () {
$(window).scroll(function () {
var debounce_bodyWidth = $(window).width();
if (debounce_bodyWidth >= 992) {
var distanceFromBottom = $(document).height() - $(this).scrollTop();
var stickyElement = $('.sticky-element');
if (distanceFromBottom <= 1200) {
stickyElement.addClass('hide');
} else if ($(this).scrollTop() >= 150) {
stickyElement.removeClass('hide');
stickyElement.css({
'position': 'fixed',
'top': '15px'
});
} else if ($(this).scrollTop() < 150) {
stickyElement.css({
'position': 'relative',
'top': '0'
});
}
}
});
}
contactDebounce();
})(jQuery);
Or this, unbind when smaller, rebind when bigger:
(function ($) {
contactDebounce = function () {
var debounce_bodyWidth = $(window).width();
if (debounce_bodyWidth >= 992) {
$(window).scroll(function () {
var distanceFromBottom = $(document).height() - $(this).scrollTop();
var stickyElement = $('.sticky-element');
if (distanceFromBottom <= 1200) {
stickyElement.addClass('hide');
} else if ($(this).scrollTop() >= 150) {
stickyElement.removeClass('hide');
stickyElement.css({
'position': 'fixed',
'top': '15px'
});
} else if ($(this).scrollTop() < 150) {
stickyElement.css({
'position': 'relative',
'top': '0'
});
}
});
}
else
{
$(window).unbind('scroll');
}
}
contactDebounce();
$(window).on("debouncedresize", contactDebounce);
})(jQuery);

Categories