Bug in Google Chrome for Iframes - javascript

I have a html graphing calculator that was relatively easy to create. I created an iframe and a textbox that held the code for a viewer to interact with. The system that was working before I put in the textbox and iframe but is now is acting buggy and not working properly. It could be I broke pieces of the code while transferring it, but I could not find the individual problems. The problems I noticed is that the system does not correctly graph on the y axis, whereas it did before (I fixed this problem by dividing the y-axis calculated by 13, but still am interested why it was higher than normal). Also, when I delete a number on one of the inputs after graphing once, the content of the iframe disappears, but reappears when I change the size of the page. Interestingly, if the size of the page is not your regular desktop, it does not disappear(I did not try any larger computers). I thought I may have done something wrong with the z-indexes I set but couldn't find any problems there. Does anyone know why I am running into these problems? Currently I am guessing that is is some king of loading problem for the iframe. The code is below;
<!DOCTYPE html>
<html>
<head>
<title>GCalcScratchpad</title>
<style>
body {
font-family: 'Courier New', Courier, monospace;
}
hr {
border-top: 3px solid #bbb;
}
iframe {
width: 100%;
height: 600px;
border: none;
}
textarea {
resize: none;
float: right;
width: 80%;
height: 1800px;
margin-bottom: 5px;
}
div {
width: 18%;
float: left;
}
button {
width: 100%;
text-align: left;
margin-top: 4px;
}
p {
font-size: smaller;
}
</style>
</head>
<body>
<iframe id="program"></iframe>
<hr>
<h2>My Coding</h2>
<div>
<button onclick="run()">Run Program</button>
<button onclick="fullScreen()">Fullscreen</button>
<p>The buttons above will run any changes to the code made in the textbox or resize to fullscreen.</p>
<p></p>
<h3>CSS</h3>
<p>This CSS is mostly beginner friendly, with one aspect of it slightly more complex. The majority of the CSS is me sizing divs and changing the body to a font and background color I like. I use z-index in this program too to make so that the graphed line does not go over text I do not want it to. There is also the #topGraph > div, which makes so that I can create other two pixel by two pixel divs using Javascript. I use this for the graphed line.</p>
<p></p>
<h3>HTML</h3>
<p>The HTML is more beginner friendly, just basic HTML elements. These elements consist of divs (to keep the content uniform and avoid the graphed lines covering other content as well as to create the blank graph), text (to inform the viewer how to use the program), buttons (as a form of text to display the formula and to trigger functions) and inputs for your y-intercept and slope. These simple peices form the basics of the HTML.</p>
<p></p>
<h3>Javascript</h3>
<p>The Javascript is more complex. It uses functions that calculate the basic formula to make the graph and to actually graph the points of the graph. It then uses your button's onclick function to take your input values and runs those values using the functions listed before.</p>
</div>
<textarea class="code" id="code">
<html>
<head>
<style>
/* This changes the body's font to one I think is more fitting for the program. */
body {
font-family: 'Courier New', Courier, monospace;
background-color: white;
}
/* This changes the width of every div. I use this to make the text look nicer. */
div {
width: 400px;
background-color: #fff;
z-index: 2;
}
/* This div is used in Javascript to create the graphed lines. */
#topGraph > div {
height: 2px;
width: 2px;
z-index: 0;
}
/* This div I use to create the bottom portion of this div. The download for the images I used is below. */
#bottomGraph {
position: relative;
height: 31px;
width: 441px;
background: url('../Pictures/grid2.png');
margin-left: 10px;
margin-bottom: 10px;
z-index: -2;
}
/* This div makes it so that the graphed line does not cover up the text. */
.noLine {
width: 550px;
background-color: #fff;
z-index: 2;
}
</style>
</head>
<body>
<!-- This div works similarly to the styling that I used on the divs in general except in CSS I made it slightly wider so that it could hold the length of the formula. -->
<div class="noLine">
<!-- This div shortens the width of the text so that it matches the rest of the page. The text inside gives instructions to the viewer which inform him how to use the page. -->
<div>
<h2>Slope-Intercept Graphing Calculator</h2>
<p>Put in your slope and your y-intercept. If you have a direct equation do not leave the y-intercept blank. Instead put in a zero. Then click the run button. Below is the code I used explained.</p>
</div>
<!-- The rest of these buttons make a visible formula to the viewer. The inputs have an id so that the Javascript can access their contents. The 'run' button allows the viewer to run the program using a function linked to the onclick aspect. -->
<button>{ y =</button>
<input id="slope" />
<button>x +</button>
<input id="y_intercept" />
<button>= ? }</button>
<button onclick="run()">run</button>
</div>
<!-- This div serves as the main graph picture (pictures are available for download below). The styling is in the div itself. -->
<div id="topGraph" style="position: relative; height: 271px; width: 441px; background: url('../Pictures/grid.png'); margin-left: 10px; margin-top: 10px; z-index: -1"></div>
<!-- This div serves as the graph underneath y axis 0. This time the styling is in the style tags. -->
<div id="bottomGraph"></div>
<Script>
// The first function I use is one that calculates the basic formula of a 2-dimensional graph; y=mx+b (basic algebra).
function calculate_y(m, x, b) {
return (m*x)+parseFloat(b);
}
// Then I create I second function that calculates what answer we would get every time y is given a new value using a for statement. Each new y value is 0.004 higher. Then each value x and y is mapped out on the div 'topGraph' and the point is shown using divs I've shown before in the CSS portion. These divs are solid black and 2 pixels by two pixels. I give it a z-index of -1 so that I can set a div with a background of white to a higher z-index to avoid lines going over that div. I use this to avoid lines going over text that I do not want it to.
function multiple_x_s(m, b) {
for (x = -3; x < 10; x += 0.004) {
y = calculate_y(m, x, b);
var new_div = document.createElement('div');
new_div.style.height = 4;
new_div.style.width = 4;
new_div.style.position = 'absolute';
new_div.style.left = x*130+'px';
new_div.style.bottom = y*130+'px';
new_div.style.background = 'black';
new_div.style.zIndex = '1';
document.getElementById('topGraph').appendChild(new_div);
}
}
// This function runs when you click the button (via onclick). This function runs the other two functions I described and set certain values using the ids of the input tags.
function run() {
var slope = document.getElementById("slope").value;
var y_intercept = document.getElementById("y_intercept").value;
multiple_x_s(slope, y_intercept/13);
}
</Script>
</body>
</html>
</textarea>
<script>
window.onload = function() {
document.getElementById("program").srcdoc = document.getElementById("code").value
}
function run() {
document.getElementById("program").srcdoc = document.getElementById("code").value
}
function fullScreen() {
document.getElementById("program").requestFullscreen()
}
</script>
</body>
</html>
EDIT1; I have tested this on multiple browsers and learned that the problem seems to only occur in Chrome, which leads me to believe that this is a bug in Google Chrome.
EDIT2; I have tested this when the number I delete is zero or letters and the program continues to work. It is only when I delete real numbers that the program fails. I have also tested using different forms of input such as the textarea but this did not fix the problem.
EDIT3; I tried deleting the "DOCTYPE html" tags and the "html" tags and the program still has the same bug. The rest of the program works however.
EDIT4; I tried making so that the overflow of the body is hidden, which seemed to eliminate the problem. I am still unsure what this fixed, but the entire program works now. Thankyou to everyone who helped. :)

Related

Insert elements on top of something without changing visible scrolled content

I'm building a chat interface for a website. When it first loads, the most recent messages are displayed, with the newest at the bottom, as is common with most chat apps.
As the user scrolls up, more messages are loaded via our API, and inserted above the existing messages.
As you might expect, the chat bubbles are styled <div>s inside a container <div> that has overflow-y: auto and a set height.
Currently what I'm doing is noting the top message <div>, loading the older messages above it, and then repositioning the view to try and put the user back to almost where they left off, but it's tricky, especially when the chat bubbles contain dynamically loading elements (embedded images, etc). (I do not know the height of these bubbles before the browser renders them.)
In an ideal world, I would like to find a way to insert the messages above, without causing the scrolled position to move at all, so that the user doesn't lose track of where they are in the stream of messages.
I've never heard of such a thing, but it would be cool if there was a way to tell the div to stretch itself in the upward direction, rather than causing it to push the existing messages down further.
Any advice would be appreciated.
Here is a JSFiddle that shows the basic problem. It simulates my chat interface, by loading 30 chat messages when the page loads, and then puts you at the bottom of the message list. As you scroll to the top, another 30 are loaded, but you'll see that this is jarring to the UX because you instantly lose your place.
UPDATE: Thanks to Richard's answer, with a technique based on requestAnimationFrame to re-align the viewport. (For my use of it, I utilized the scrollTop of my scrollable div, rather than window.scrollTo as shown in his example.)
Fortunately, there is. The CSS property is called overflow-anchor. When you set the overflow-anchor property of an element to auto, it will turn on scroll anchoring; which is an attempt of the browser to minimize the problem of content jumping (such as a large image loaded above your scroll position causing your content to scroll further down); and set said element as the potential anchor when adjusting scroll position.
That being said, overflow-anchor is automatically set to auto and you needn't set it, so I'm not sure how setting it manually helped you. From MDN:
Scroll anchoring behavior is enabled by default in any browser that supports it. Therefore, changing the value of this property is typically only required if you are experiencing problems with scroll anchoring in a document or part of a document and need to turn the behavior off.
Here's a simple demonstration. At first, the window is already scrolled by 200px. Every two seconds, a new div is inserted on top of the container. Note that the visible area of the window doesn't change even when a new div is inserted on top the container.
const container = document.querySelector('#container')
window.scrollBy(0, 200)
let counter = 9
setInterval(() => {
let newDiv = document.createElement('div')
newDiv.classList.add('messages')
newDiv.innerText = counter++;
container.prepend(newDiv)
}, 2000)
* {
box-sizing: border-box;
font-family: Helvetica;
}
html,
body {
margin: 0;
}
#container {
width: 100%;
height: 100%;
padding: 0 20px;
scroll-behavior: smooth;
overflow-anchor: auto;
}
.messages {
width: 100%;
padding: 20px;
text-align: center;
background: #121212;
color: white;
border-radius: 5px;
margin: 20px 0px;
}
<div id="container">
<div class="messages">8</div>
<div class="messages">7</div>
<div class="messages">6</div>
<div class="messages">5</div>
<div class="messages">4</div>
<div class="messages">3</div>
<div class="messages">2</div>
<div class="messages">1</div>
</div>
Update
As setting overflow-anchor manually did help you with adjusting scroll position upon height increase above the viewport, but Safari does not support overflow-anchor, here's a simple alternative mechanism (using requestAnimationFrame) to adjust the viewport so that it always stays in its current position. This code below also adjusts the scroll position when you are at the top of the container and older messages show up (an issue you mentioned).
Note that I've set the overflow-anchor to none, thus disabling the scroll-anchoring browsers usually enable automatically, to show that this code works (I'm running it in Firefox). Also, the code is adjusted such that it does not scroll down when new messages are appended to the container. Do consider the scenario when the user is reading the last message and a new message gets sent; you might want to scroll down in that case. Furthermore, I am calling getBoundingClientRect() every frame. If not used properly, this can cause layout thrashing (also read here for the list of JS properties/methods that can cause this).
One last note: I actually wanted to use ResizeObserver, but as Safari does not support that API, I used rAQ instead to observe container's height changes. There are already ResizeObserver polyfills, which I have not tried out yet, but may be more efficient than using rAQ to observe height changes. Here's the page that contains a lot of links to ResizeObserver polyfills.
const container = document.querySelector('#container')
let counter = 9
setInterval(() => {
let newDiv = document.createElement('div')
newDiv.classList.add('messages')
newDiv.innerText = counter++;
container.prepend(newDiv)
}, 2000)
window.scrollBy(0, 200)
// Mimicking scroll anchoring behaviour from browser
let previousLastChild = container.lastElementChild
let previousBoundingRect = container.getBoundingClientRect()
function scrollAdjustment() {
let boundingRect = container.getBoundingClientRect()
let isHeightIncreased = boundingRect.height !== previousBoundingRect.height
let isAppend = container.lastElementChild !== previousLastChild // Is height increase caused by new messages being appended?
if (isHeightIncreased && !isAppend) { // If new messages are appended, don't scroll down as people are reading the upper messages
let newScrollYPosition = window.scrollY + boundingRect.height - previousBoundingRect.height
previousBoundingRect = boundingRect
window.scrollTo(0, newScrollYPosition)
}
requestAnimationFrame(scrollAdjustment)
}
requestAnimationFrame(scrollAdjustment)
* {
box-sizing: border-box;
font-family: Helvetica;
}
html,
body {
margin: 0;
}
#container {
width: 100%;
height: 100%;
padding: 0 20px;
scroll-behavior: smooth;
overflow-anchor: none; /* Note I've set it to none */
}
.messages {
width: 100%;
padding: 20px;
text-align: center;
background: #121212;
color: white;
border-radius: 5px;
margin: 20px 0px;
}
<div id="container">
<div class="messages">8</div>
<div class="messages">7</div>
<div class="messages">6</div>
<div class="messages">5</div>
<div class="messages">4</div>
<div class="messages">3</div>
<div class="messages">2</div>
<div class="messages">1</div>
</div>

How to find actual perimeter of printable area?

What I'm trying to do is create an area on a page that users can interact with, which corresponds perfectly in size to the typical size of a piece of paper (A4), so that users are aware of exactly what the print will look like as they're constructing the printable area (before accessing print preview). I do not want to and should not have to use #media print at all.
It seems as if the perimeter of the printable area of the page corresponds to the actual browser window (window.innerWidth, etc) only sometimes, whereas at other times elements that are positioned closer to the center of the page are partially excluded from the printable area or even excluded altogether.
I can't seem to find any rhyme or reason to this. I've tried looking on SO and found one question in relation to printable areas but for a different language/context. Tried looking on Google. Nothing.
[edit] Now that I think about it, it's behaving kind of like viewport/viewbox cropping/zooming.
Anybody know how would one go about finding the actual printable area of a webpage and or the perimeter thereof?
Example
An element with the position right: 0 appears on the far right side of the page and will be included in the print, but ironically that very same element ends up becoming partially excluded when it is dragged closer to the center of the screen.
...
<body>
<div id="l"></div>
<div id="r"></div>
<textarea draggable="true" id="textarea"></textarea>
</body>
...
#media print {
#l, #r {
width: 50%;
height: 100%;
position: absolute;
top: 0;
}
#l {
background: blue;
}
#r {
left: 50%;
background: orange;
}
#textarea {
right: 0;
}
}
However, if I drag the image closer to the center of the page, ironically it becomes partially excluded from the printable area...
Often times, a special style sheet that is designed solely for purposes of printing is associated with a web page. This style sheet can literally include/exclude anything.
Here's some reading on setting up a print style sheet.

How to center <div> inside a <button>?

I have a round < button > with a < div > inside that represents a Unicode image. Currently the button is set to border-radius: 12px; height: 24px; and width: 24px; and the < div > is to font-size: 17px. The < div > Unicode image sits inside but not centered and the button is slightly off to the side.
How can I get the < div > to center inside an oval button despite what font-size the < div > is?
EDIT
I want to create a circle/round button with an emoji center to the middle of the button despite the button's size or the emoji image's size.
CSS for the button and emoji image for div:
#emoji-button {
border-radius: 19px;
width: 38px;
height: 38px;
}
#thumb-emoji:after {
content: "\01F44C";
font-size: 20px;
}
And round/circle button with emoji image inside:
<button
type="submit"
id="emoji-button"
>
<div id="thumb-emoji"></div>
</button>
But it is not centered.
And is there a way to just back the emoji image alone to be clickable for a method?
First off:
A <div> is a block element by nature. It will always become 100% wide. If you want it to not be 100% wide, give it a display:inline-block so it won't get bigger than it needs to be. Then give it a margin:0 auto; or a text-align:center on the parent to center it.
HOWEVER, You are not allowed to put <div>s inside of <buttons>. it is invalid HTML
See this answer for more information:
Why can't a <button> element contain a <div>?
Or, you could read here, from W3 that only phrasing content is expected to be used within a button:
https://www.w3.org/TR/2012/WD-html5-20120329/the-button-element.html#the-button-element
If you do not know what phrasing content is, See this page:
https://www.w3.org/TR/2012/WD-html5-20120329/content-models.html#phrasing-content
-- if you are looking into styling buttons specifically, maybe this very short tutorial would help:
http://web.archive.org/web/20110721191046/http://particletree.com/features/rediscovering-the-button-element/
Here is a fiddle of a working button like yours:
https://jsfiddle.net/68w6m7rr/
I honestly didn't have many problems with this. I only replaced your <div> with a span, that's it.
can you post your code?
You should NOT need a div inside the button. If you need the button to have a specific style give it a class. You could do something like this
CSS:
button.something {
padding: 25px;
border-radius: 100%;
font-size: 20px;
border: none;
}
HTML:
<button class="something">👌</button>
For clean and valid code, you'd better use a :before or :after pseudo-element. This would also take care of the centering by default.
It's even easy to set the content. Either in css only, like this:
1.
button:before {content:"\25b6";}
(put your unicode value there and classes/ids as needed, then specify them in turn in css)
2.
Or if you need to specify the value in mark-up, drop a custom data-* attribute like this:
<button data-myunicode="\25b6"></button>
with each button taking it's own value, then drop this single line in css:
button:before {content:attr(data-myunicode);}
Before answering, let's clear some things out.
div is a block level element, used in an inline element, which is the button element. Browsers will consider this invalid and will fix it by removing the block element from the inline element. For more about CSS concepts like box model, box generation please refer to these resources:
https://developer.mozilla.org/en/docs/Web/HTML/Block-level_elements#Block-level_vs._inline
https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Visual_formatting_model
https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Box_Model/Introduction_to_the_CSS_box_model
Also, if you are using an IDE, make sure you have installed linting/hinting tools to help you out. These tools can help you in code authoring so, make sure you have them. If you are using software like VSCode or Sublime Editor, there are many free code analysis tools out there.
Let's go back to the code now.
You said
I want to create a circle/round button with an emoji center to the
middle of the button despite the button's size or the emoji image's
size.
I went ahead and created a plunk here where I demonstrate this. Essentially, I wrapped the button around a div which serves as a container and through some CSS magic, I made it to have the same height as its width. More on that you can find at this SO answer.
The #emoji-button then has a border-radius: 100% in order to be round, width is inherited from the parent, meaning it has the same as the container and it position is absolute in order to fit in the container.
The #thumb-emoji has changed to a span element. By user agent styles it has text-align:center.
<div class="button-group">
<button type="submit" id="emoji-button">
<span id="thumb-emoji"></span>
</button>
</div>
CSS:
.button-group {
position: relative;
width: 100px;
}
.button-group:before {
content: "";
display: block;
padding-top: 100%;
}
#emoji-button {
width: inherit;
border-radius: 100%;
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
}
#thumb-emoji:after {
content: "\01F44C";
font-size: 200%;
}
You can change the .button-group width to whatever width you want, it will still keep its 1:1 ratio.
You can use then media queries on .button-group to adjust the font-size of your #thumb-emoji, by setting your desired breakpoints.

Keep element scrollable until last content is reached

I'm not sure what kind of keyword should I use to ask this question,
I already search this in Google but looks like my keyword is bad.
The problem is, I have two div relative element with dynamic content, meaning the height of this two element is not fixed and they are scrollable.
Let's say the first div has a class name of l-content stand for Left-Content and the second div has a class name of r-content stand for Right-Content.
The l-content will have more content than the r-content but they will both scrollable when the screen size is not enough to show the whole content.
Now what I want to happen is when the r-content has reached it's last content then scrolling on it will be stop so that only the l-content will continue scrolling.
The Example is like on Facebook, as you can see where ads,Recommendation,etc are shown in the right side of it
when the last content is reached then that element looks like fixing it's position.
I'm not sure if it is fixing or not but I'd like my r-content to be like that But have no idea on how.
Current this is all i have, note that I am using Bootstrap on this:
CSS
h1 {
font-family: sans-serif;
color: #FFF;
letter-spacing: 2px;
font-weight: 300;
}
.l-content, .r-content {
display: table;
float: left;
margin-bottom: 8px;
text-align: center;
padding: 20px;
}
.l-content {
width: 800px;
height: 2000px;
background: #E04C4E;
margin-right: 8px;
}
.r-content {
width: 430px;
height: 1000px;
background: #5996BC;
}
HTML
<!--LEFT CONTENT-->
<div class="col-lg-8 l-content">
<h1>Left Content with Continue Scrolling.</h1>
</div>
<!--RIGHT CONTENT-->
<div class="col-lg-4 r-content">
<h1>Right Content with Continue Scrolling but scrolling will stop when last content is reached.</h1>
</div>
I am not sure if it they are using a Javascript to do it.
Anyway, Thank you so much. Any help would be appreciated.
I believe you need javascript here, and jQuery is geared for exactly this.
scroll() and scrollTop() are the magic functions here:
var h = $(preceding-content).height()
var s = $('#your-sticky-element')
$(window).scroll(function(){
if($(window).scrollTop() <= h){
$(s).css({
'position':'fixed',
'top':'0px'
});
}else{
$(s).css({
'position':'initial'
});
}
}
This will work best if it's static content above your sticky element. If it's updating its height in real time, you're going to be doing a lot of calculations just to keep an element in place.

Centering text over an IMAGE BUTTON, while driving the text hover effect from hovering over the image- not the text

I have a set of buttons in which I need the text to - eventually - change based on country.
This means that I have to use a text element to be part of the button. Since the button has hover effect, I need the text to be contained inside the image div.
By using the "", I get the text to be position correctly, but the problems are:
A: the text responds to the pointer way outside the image boundary (which actually causing the click to activate a different button.
B: if the pointer is placed directly over the text, only the text get highlighted (through the hover effect), but not the button.
I am looking for a solution (either via CSS or JavaScript) that will make the button perform correctly e.g. the button will respond pointer hover over to the image only, but will still highlight the text (as if the text was part of the - and not separate as it actually is).
Note that since the text and image elements are screen-size adaptive, all distances and sizes must be percentage based)
See Fiddle HERE:
Note what happens when you hover just on top of the image. Also note what happens when you touch the edges of the image VS the center...
<div id="main_positioning_container">
<div id="my_account_dashboard_container">
<div id="contact_information_icon"
style="color:#292726"
onMouseOver="this.style.color = '#f48325'"
onMouseOut="this,style.color = '#292726'" >
<img src="../icons/icon_ContactInforrmation_inactive.png"
img onMouseOver="this.src='../icons/icon_ContactInforrmation_hover.png'"
onMouseOut="this.src='../icons/icon_ContactInforrmation_inactive.png'"
alt="icon_ContactInforrmation_inactive"
width="100%"
hight="auto"
style="margin-bottom: -20%;">
<p align="center">Contact Information</p>
</div>
</div>
</div>
#main_positioning_container {
position:relative;
width: 100%;
top: 75px;
left: 0px;
}
#my_account_dashboard_container {
visibility:visible;
}
#contact_information_icon {
position: absolute;
width: 25%;
z-index: 3;
color: #292726;
font: Kalinga;
font-size: 100%;
margin-top: 13.75%;
margin-left: 7.5%;
height: 20px;
}

Categories

Resources