Nested Conditional Statement Works, but Combines Conditional Statement Doesn't - JavaScript - javascript

I have a piece of code where I have solved a problem, but I don't know why my solution works, which I'm finding almost as frustrating as when something doesn't work.
Basically I have an SVG viewbox that I've resized with JS for big screens.
This SVG viewbox is only on one page of my site, page1.
I have a conditional statement where if the users in on page1 and the window is 1920px or larger the viewbox resizes.
I have achieved this with a nested if statement.
if (page1) {
if (window.innerWidth > 1919) {
// set SVG viewbox for screens larger than 1920px
} else {
// keep normal viewbox dimensions.
}
}
When I orginally tried this, I did it as one if statement with two conditions, and although this worked on page1 it threw an error in the console when I wasn't on page1.
Why does it throw an error on pages that aren't page1 when there is one combined condition, and not when the conditions are nested? The error I was getting was basically saying the SVG element doesn't exist. I'm very confused.
if (page1 && window.innerWidth > 1919) {
// set SVG viewbox for screens larger than 1920px
} else {
// keep normal viewbox dimensions.
}

Think of what your code means: in the first version, if it is page1, then you either change the size or you maintain the default size. If it isn't page1, you do nothing.
In the second case, if it's page1 and the window is big, you use the big viewbox. If it's either not page1 or the page isn't large enough, you use the default size.
They're just not the same.

Related

Navigation bar doesn't work with Intersection Observer API

I have a problem when I use the Intersection Observer API. I am trying to use it for, once the nav-bar is not visible anymore when you scroll, make this latter appears with a white background and fixed to the viewport.
I first of all tried to console.log('visible') and console.log('visible') when the nav-bar is visible or not and I succeed ! But when I wanted to apply the new class when the navbar wasn't visible anymore, my page starting to get mad : the class was applied and removed, and the console was only displaying "visible", "not visible" all the time very frequently.
I think it is because when I apply the class, it moves the rootMargin (of the options object) but I don't know how to fix it.
My entire website (my code is in app.js) : https://replit.com/#Xeway/IntersectionObserver#app.js
PS : I only have build app.js, HTML and CSS are codes made by FreeCodeCamp.
PS : Sorry for the link, but I can't share this code here because my code uses backtick and it doesn't seems to work ^^ Also, try to open the website with a big width because it's responsive and you can see more precisely the problem when it's on a computer's screen width.
Thank you in advance for your answers guys :)
Intersection observer is not needed for your case.
You just need to apply class to your header, when window is scrolled beyond certain height.
In your case, it would be equal to the height of the header.
So, when the window scroll height > height of the header, then apply class
and in the else, remove the class.
Call the same function on document.ready as well (To check the window scroll position on the page load, if the window is already scrolled).
Here is the little script for your help:
$(window).scroll(function() {
var scroll = $(window).scrollTop();
// assume 100px is the height of the header
if (scroll >= 100) {
addScrolledClassToHeader();
} else {
removeScrolledClassToHeader();
}
});
function addScrolledClassToHeader() {
$('header.site-header').addClass('header-is-scrolled');
}
function removeScrolledClassToHeader() {
$('header.site-header').removeClass('header-is-scrolled');
}

Imitate 1920x1080 window in a smaller div with sizing of elements

I am working on a project that uses two windows, similar to a video board, where the main screen is a control panel of sorts with a "preview" screen, and the secondary screen is a projection of the viewing content in 1920x1080 resolution. I would like the smaller control panel preview div to match the stylings of the larger viewing window. Currently, I am passing in a "windowInstance" prop to my styled component and adjusting the styles that way, for example:
const SomeComponent = styled.div`
height: ${props => props.windowInstance === 'controlPanel' ? '300px' : '400px'};
`
// ...
return (
<SomeComponent windowInstance={windowInstance} />
)
(windowInstance is passed from the parent component. this is not relevant for the problem at hand, and it gets a bit complicated)
Obviously, this has gotten quite tedious as my app has grown, and nothing is quite right unless I meticulously calculate the difference in window sizes as a percentage and translate that to the new property values. What I want to know is if there is any way with CSS or JS that I can unify these styles and have the results render correctly and identically on both screens.
Important to note is that neither window needs to be responsive or will ever be resized. Here is a sketch I did in excalidraw to better describe the goal:
I was able to solve my problem using the css property zoom - which I was previously unaware of. It works like a charm. My preview screen happens to be exactly 47.5% of the size of my viewing window. So I solved the problem like this:
// Wrapper.js
return (
<StyledWrapper className={windowInstance === 'controlPanel' && 'preview-screen'}>
{children}
</StyledWrapper>
)
// index.css
.preview-screen {
zoom: 47.5%;
}

IE, and iframe.elementFromPoint not passing event

Update: Fiddle Demonstration -- http://jsfiddle.net/7tfbtso6/2/ -- Most of the settings work in chrome and firefox, but the only one that works in IE is Left-align: 105px. I do have overflow set to hidden on html and body, but this makes no difference. IE will not work if the element is not visible on screen. And overflow: visible on html and body give the effect of auto and no effect on the problem here.
My site uses two contentEditable divs.
#rInput is part of the document.
#rSyntax is part of an iframe under (z-index) #rInput.
In every browser I've tried so far, except IE (I'll get to that in a moment.), I'm able to determine what element is contained within the iframe using elementFromPoint().
In IE's case, this is only possible if they're not overlapping which isn't possible because a secondary purpose, as the name implies, is to provide syntax-highlighting.
The IE IFrame has to be visible, on screen, not obstructed by any objects. I've tried display: none;, visibility: hidden, and pushing it down in a div with overflow: hidden, but all of these attempts cause it not to work. I've also tried setting the height and width to small proportions.
If any of these could work, I could use two copies of rSyntax, one on top (z-index), hidden somehow, for mouse events and one for syntax highlighting.
Most of these solutions work in every browser but IE. The IE box simply demands that it be on top.
"Flickering" it with css (display, visibility, pointer-events) seems awfully hacky (and just plain awful). I haven't really tried to implement it because it seems like a last resort.
The problem is further complicated because I'm trying to capture clicks and mouseovers, for different purposes (clicks for finding content, mouseovers for tooltips--created with a div mimicking attr("title").
I've briefly tried placing the iframe on top (z-index) of the div, but there's no way to intercept the clicks and pass to the lower object because it runs in to the same problem.
Here's the script I'm using to get the objects, partly in case it's useful to anyone.
$(document).on("mousemove", "#rInput", function (e) {
$element = $(document.getElementById('frSyntax').contentDocument.elementFromPoint(e.pageX+$("#rInputContainer").scrollLeft()-10,e.pageY+$("#rInputContainer").scrollTop()-12));
if ($element.is("span") && $element.attr("title") && $element.attr("title").length) {
$("#syntip").text($element.attr("title"));
$("#syntip").css({"top": e.pageY+10, "left": e.pageX, "display": "inline-block"});
} else {
$("#syntip").hide();
}
});
I have considered transparency, and that works for this element, because it's small, but I use a similar setup with a large element that takes up more than 50% of the screen, there would be problems.
After many frustrating efforts, I concluded that pushing the top (z-index-wise) element offscreen was the only solution for IE/Edge. Flickering it with display: none causes some properties I needed, like width, to not be accurate.
Just make sure you push it farther than the element will ever be. My application is sidescrolling so I merely needed to place the css top to something like 2000.

Positioning div elements left & top not working with content in FireFox

I've got a webpage with a full-screen canvas. Over the canvas I'm going to place and position divs that will contain UI elements for the canvas. I'm using jQuery to create the divs and give them the css style they need. I also re-position and/or re-size them in JavaScript upon window re-size. The problem is, as soon as I enter even one space into a div, FireFox says 'NO!' and seems to ignore any css changes made by JavaScript, even if I remove the content of the div again.
Here's some technical details:
The div I'll show is a fullscreen div that overlays the canvas and functions as dim-screen in case there are dialogs the user has opened so the canvas appears darker and extra attention is pulled towards the dialog.
The css I'm using is:
.ui_layer {
position: absolute;
top:0px;
left:0px;
}
#ui_layer_dim {
background-color: #000000;
opacity: 0.5;
}
In JavaScript I have my own function that creates the div, but it runs this jQuery:
$("<div id='ui_layer_dim' class='ui_layer' style='z-index:1'/>");
Then, on onWindowResize (tiggered by a window 'resize' eventlistener), I change the div's width and height to fit the new window size:
gameUI.layers["ui_layer_dim"].onWindowResize = function() {
this.css("width", window.innerWidth + "px");
this.css("height", window.innerHeight + "px");
};
In Chrome this works perfectly, even if I place content in the div. FireFox works, but only when the div is in it's initial state. One change to the div's contents and 'BOOM it goes': No more dynamic sizing.
I've tried the different css position settings, tried setting the width and height attributes using the css function, using the style function of the element and using setAttribute to see if it's caused by some sort of incompatibility; the results didn't change.
I've run a series of tests to see what happens to the html as soon as content is placed into the div and noticed something weird: The inspector and css rules won't show changes to the width and height of the window's innerWidth and innerHeight. Neither does the div itself, but I've set up some logging to view info about the window's innerWidth and innerHeight before setting the div's width and height and some logging about the div's width and height after setting it, and that actually shows the correct dimensions...
After building and testing the system for several days I have no clue anymore what could cause the problem. Like I've said before: Chrome works as it should so I know my code technically works, but it might just be that a different approach is needed to make it work in FireFox. I hope anyone knows. Help would be greatly appreciated!
Edit: Here's a fiddle with the code, try running in FireFox, resize the result, it should resize the grey div as well. Now, right click the result, go to the inspector and put some text or even a space inside the div and resize again. Not working for me. Link: http://jsfiddle.net/UsLL6/
Edit 2: Here's a screenshot that will hopefully clear up the problem I'm having. Marked yellow is the initial state of the browser width, I set it to very narrow to be able to show the problem more clearly. Marked orange is the state after I made the browser wider a bit. You can see the grey div doesn't resize with it as it should, neither do the inspector value and the CSS rules value, but the console shows the correct value. The first ("Setting property:.....") was retrieved from window.innerWidth, the second ("Property height now has....") was retrieved from the actual width property from the div element using style.getPropertyValue.
Just noticed IE gives the same result as FireFox, but yea..IE....
Is your gameUI.layers known by mozilla?
Did you try the jQuery solution?
$(window).resize(function(){
$('#ui_layer_dim').width(window.innerWidth);
$('#ui_layer_dim').height(window.innerHeight);
});
When adding and removing content from the div using JavaScript it works. Even though the problem does not exist for me anymore I'm still very confused by the fact that editing the div in the FF inspector creates such a weird result.

Get updated div size when content size changes

I have a div that contains several inner divs. In my javascript/jQuery code a function executes, that changes the size of the inner divs using the jQuery css() function. In another function after the first one, I need to read the size of the outer div. Its size should have increased according to the size increase of its contents.
So basically it looks like this:
resizeInnerDivs();
//...do something else...
doSomethingWithOuterDivSize();
When doSomethingWithOuterDivSize is entered, IE8 and IE9 still get the old size for the outer div. IE10, Firefox and Chrome on the other hand return the updated size.
I assume that IE8 and IE9 are not done with recalculating the new size. I tried wrapping doSomethingWithOuterDivSize(); with a setTimeout call. If I wait long enough, I can get a better (but not necessarily correct) size value, depending on the timeout.
Can I somehow force the recalculation of the outer div? How can I get the correct values in IE8 and IE9 as well?
You are probably looking for this:
$('.yourClass').width();
$('someElement').width();
$('#someId').width();
$('any valid jQuery/CSS selector').width();
Resource: http://api.jquery.com/width/
$.width() will give you computed width of your element.
I guess you have either of these two:
The inner divs don't affect your outer div width on IE.
The inner divs are not finished rendering before you are trying to get the
width of outer div, thus you still get the old width.
You can check this by querying width in the console manually:
console.log($('outer_div_selector').width())
If this returns the correct (updated) width, then you are having issue #2. You can solve it like this:
$('outer_div_selector').width(); // this will force rendering to finish before executing the next line
doSomethingWithOuterDivSize();
Otherwise you have an CSS issue (eg. make sure all floats are correctly cleared).

Categories

Resources