Whenever I change zIndex of given div (even to the same value) its scrollTop property resets and it scrolls back to start. This causes a very ugly effect to my site (slowdown and black rectangle over the entire div while it repaints). After scrollTop reset I can set it back, but this causes yet another ugly repaint.
This FF bug is driving me mad! I submitted a bug in mozilla https://bugzilla.mozilla.org/show_bug.cgi?id=623937 but they don't care to work on it! Please, if somebody knows how to workaround this issue with some javascript magic? Maybe play with the HTMLElement prototype to somehow override scrollTop?
Here goes a little test case"
<html>
<head>
<style type="text/css">
div#parentDiv
{
position: absolute;
top: 10px;
left: 10px;
width: 300px;
height: 200px;
background-color: green;
}
div#elementToScroll
{
position: absolute;
top: 40px;
left: 40px;
width: 200px;
height: 100px;
overflow-y: hidden;
background-color: blue;
color: white;
}
</style>
</head>
<body>
<div id="parentDiv">
This is the parent DIV
<div id="elementToScroll">This is the child div with overflow-y: hidden and content a lot of a lot of a lot of a lot of a lot of a lot of a lot of a lot of a lot of a lot of a lot of a lot of a lot of a lot of a lot of a lot of a lot of a lot of a lot of a lot of a lot of a lot of a lot of a lot of ; </div>
</div>
<script>
var parentDIV = document.getElementById("parentDiv");
var elementToScroll = document.getElementById("elementToScroll");
alert ("elementToScroll.scrollTop initial: " + elementToScroll.scrollTop);
elementToScroll.scrollTop = 20;
alert ("We set elementToScroll.scrollTop = 20: current value is: " + elementToScroll.scrollTop);
parentDIV.style.zIndex = 0;
alert ("We set parentDIV.style.zIndex and now elementToScroll.scrollTop is: " + elementToScroll.scrollTop);
</script>
</body>
</html>
I tested and nothing is wrong with Firefox 4:
Related
I'm working on my own in browser live HTML/CSS code editor. What I'm having trouble with is applying the css styles typed out by the user to my div preview pane.
What I currently have is
<html lang="en">
<head>
<meta charset="utf-8">
<title>Code Editor</title>
<style>
.wrapper{
width: 100%;
}
.textWrapper {
width: 30%;
height: 100%;
float: left;
}
#css{
height: 300px;
width: 100%;
}
#html {
height: 300px;
width: 100%;
}
#preview {
height:600px;
width: 400px;
float:left;
border:2px solid black;
margin: 20px;
}
</style>
</head>
<body>
<div class ="wrapper">
<div class ="textWrapper">
<textarea placeholder="CSS..." id="css"></textarea>
<textarea placeholder="HTML..." id="html"></textarea>
</div>
<div id="preview"></div>
<button onclick="launch()">Launch</button>
<button onclick="toggleCSS()">Toggle</button>
<button onclick="clear()">Clear</button>
<script src="bebk9hScripts.js"></script>
</div>
</body>
</html>
and for my script page
function launch() {
document.getElementById("preview").innerHTML = document.getElementById("html").value;
}
function toggleCSS() {
document.getElementById("preview").style = document.getElementById("css").value;
}
but that is not working. Any suggestions? Also I realize using an iframe would be easier but we aren't supposed to.
A simple and effective way to accomplish what you're trying to do is to set the innerHTML of your preview element. This does not prevent you from utilizing HTML, CSS, or JavaScript in any way, so long as all necessary dependencies have been accounted for prior to your preview element. The simple implementation is:
var preview = document.getElementById("preview");
var html = document.getElementById("html").value;
var css = document.getElementById("css").value;
preview.innerHTML = html;
preview.innerHTML += '<style>' + css + '</style>';
However, as a developer in a very rapid environment, I can honestly say, using an interval to refresh the preview is much appreciated when you're trying to quickly update things. It'll be up to you as to how fast of an interval you'll use to refresh, or you could give your users a setting for update intervals.
Keep in mind though, that using intervals can cause undesired behavior such as animations being cutoff, etc. This is why a lot of code editors online use a refresh or run button in the first place. But I'd like to point out the usefulness of utilizing the keyup event that is available to us.
Coupling the keyup event with a timer, a manual refresh button, and an interval would be my recommendation:
var html = document.getElementById("html");
var css = document.getElementById("css");
// Use the `keyup` event as a primary check for updates.
var keyDelay = 1000;
var keyRecieved = false;
var timeSinceLastKeyRecievedInMilliseconds = 0;
document.addEventListener('keyup', prepareForRefresh);
function prepareForRefresh() {
keyRecieved = true;
timeSinceLastKeyRecievedInMilliseconds = 0;
}
function update() {
var preview = document.getElementById("preview");
preview.innerHTML = html.value;
preview.innerHTML += '<style>' + css.value + '</style>';
}
// Use an interval for checking if we should update.
setInterval(function() {
if (keyRecieved) {
timeSinceLastKeyRecievedInMilliseconds += 100;
if (timeSinceLastKeyRecievedInMilliseconds >= keyDelay) {
timeSinceLastKeyRecievedInMilliseconds = 0;
keyRecieved = false;
update();
}
}
}, 100);
// Use a high interval as a fail-safe for flukes.
var interval = 180000;
setInterval(update, interval);
input[type=text] {
margin: 5px;
background-color: #fffa;
border: 2px solid transparent;
border-bottom: 2px solid #fff;
border-radius: 5px;
}
.update {
width: 20%;
padding: 10px;
margin: 5px;
background-color: #f33a;
cursor: pointer;
user-select: none;
}
.primary-content {
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
}
html, body { overflow-y: auto; }
<link href="https://s3-us-west-2.amazonaws.com/s.cdpn.io/2940219/PerpetualJ.css" rel="stylesheet"/>
<div id="primary-content" class="primary-content">
<input id="html" type="text" placeholder="HTML" />
<input id="css" type="text" placeholder="CSS" />
<div class="update" onclick="update();">Refresh</div>
<div id="preview"></div>
<div id="refresh-preview"></div>
</div>
The simple example above utilizes a combination of the keyup event, a timer for detecting how long it's been since the user provided input, and a high interval as a fail-safe. This is close to the method utilized by CodePen, and I heavily recommend it for a web focused editor. Feel free to check out my implementation of this in it's simplest form over on CodePen.
Your Code works!
EDIT: Well, at least kind of. It applies the styles directly only to the preview element, not its children (see comments below this post).
Below ist my old answer:
There is nothing wrong with it, and the issue must be somewhere else.
Possible issues that come to mind are:
The CSS entered by the user is not valid, or is overwritten by another stylesheet
The Javascript function to update the file does not get triggered
The elements referenced in the Javascript are the wrong ones
Here is minimal working example using your code:
function toggleCSS() {
document.getElementById("preview").style = document.getElementById("css").value;
}
document.getElementById("apply_css").onclick = toggleCSS;
<textarea id="css" cols="40" rows="5">
width: 150px;
height: 100px;
border: 1px solid green;
background: rgb(170, 200, 250);
</textarea>
<br>
<button id="apply_css">Apply CSS!</button>
<br>
<div id="preview"></div>
I'm creating a chat app which when messages load (From Firebase), the div containing the messages scrolls to the bottom to display the most recent appended message div. scrollTop does somewhat work but it won't scroll all the way to the bottom, no matter what values I use for scrollTop. I've tried both the JS and the jQuery versions of scrollTop, but neither can get it to scroll to the bottom. Here's some of my code:
HTML
<div id="msgContainer">
<div id="msgFeed">
//Messages load here from a database
</div>
</div>
CSS
#msgContainer {
height: 165px;
overflow-x: hidden;
overflow-y: visible;
}
#msgFeed {
display: block;
background-color: white;
position: relative;
margin: 0;
overflow: hidden;
}
JS
function scrollToBottom (id) {
var div = document.getElementById(id);
div.scrollTop = div.scrollHeight - div.clientHeight;
}
or...
$('#scroll').scrollTop(1000000);
Doesn't seem to matter which version or what values I use, it just refuses to scroll that last approximately 5% of the way to the bottom. Any ideas what I might be doing wrong??
I dealt with a similar issue. I was receiving a value from a web socket to put into a chat box. Whenever I used scrollTop/Height, it always scrolled to the NEXT to last message (off just a bit). Even if I put in the max or a very high value, it would not scroll all the way.
This occurs b/c the dimensions of the container (with the added item) are not yet what we expect. A simple timeout will solve this problem:
setTimeout(() => {
el.scrollTop = el.scrollHeight;
}, 500);
If you're using Vue.js (probably something analagous in other reactive frameworks), you can also do the following ('this' is the Vue instance):
this.$nextTick(
() => (this.$refs.chat.scrollTop = this.$refs.chat.scrollHeight)
);
'nextTick' seems optimal, but not everyone will be using Vue. Hope this all helps someone solve this simple yet not so evident problem.
EDIT: nextTick doesn't always seem to work. setTimeout should always work.
I don't know what element you were referring to with #scroll since I don't see it in your html, but try this and let me know if it still falls ~5% short.
$(document).ready(function(){
function scrollToBottom (id) {
var div = document.getElementById(id);
/*TRY*/
div.scrollTop = div.scrollHeight - div.clientHeight;
/*OR*/
$('#'+id).scrollTop(div.scrollHeight - div.clientHeight);
}
scrollToBottom('msgContainer');
});
#msgContainer {
height: 165px;
overflow-x: hidden;
overflow-y: visible;
border: 3px solid red
}
#msgFeed {
display: block;
background-color: white;
position: relative;
margin: 0;
overflow: hidden;
border: 1px solid blue
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="msgContainer">
<div id="msgFeed">
<br><br><br><br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br><br><br><br>
//Messages load here from a database
</div>
</div>
I want an interactive experience for my users.. AND I want to remain responsiveness. I try to learn the web by making a card game.
What I have is things to click on, which are supposed to be appearing somewhere else on the page. (Im using jQuery so far)
The (simplified) use-case is:
var card = $('[card=X]').remove();
$('.board').append(card);
Now I want to add some animation to it.
I am failing in choosing an appropriate framework.
In the ones that I tried I couldn't time the removal, or the animation was gone, when I tried to call the removal, in a callback. Which was horrible, because the removal either fired before the callback or not at all. Or there was nothing left to be reattached..
So it should be more then just 'blur' or 'fade'.
So I want to detach a thing with an animation, place it somewhere else, and make it 'appear' there with an animation.
As a superb bonus, those animations would have an orientation, so that the 'from' and 'where to' are visible appearing to the end user. (Like an arrow or a line drawn between those 2 locations.)
(Sry for not being more specific, but asking that question for all the frameworks/ libs out there appears not that appealing..)
edit:
Nick pointed me in the right direction. My issue was the boilerplate code. I adjusted the code he provided. (added fade in animation + have the things 'reappearing' with event handler)
..thus I marked his answer as correct. (even that it wasn't, he didn't append the original thing, instead he created a new one.)
$('.cards ').on('click', '[card-id]', function() {
$(this).fadeOut(1000, function() {
var old = $(this).remove();
$('.cards').append(old);
old.fadeIn();
});
for(var i = 0; i < 6; i++) {
$('.cards').append('<div class="card" card-id="'+i+'"></div>');
}
$('[card-id]').click(function() {
$(this).fadeOut(2000, function() {
$(this).remove();
$('.cards').append('<div class="card" card-id="'+$(this).attr('card-id')+'"></div>');
});
});
.card {
position: relative;
display: inline-block;
width: 120px;
height: 180px;
background-color: #F4F4F4;
border: 1px solid #E8E8E8;
border-radius:5px;
margin: 15px;
cursor: pointer;
}
.card:after {
content: attr(card-id);
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
font-size: 24px;
font-weight: 700;
font-family: courier, serif;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="cards"></div>
Consider using .animate() from Jquery. There is a lot you can do with it.
Take a look at the API: http://api.jquery.com/animate/
I am doing a project from The Odin Project. Basically this.
Here is the code:
HTML
<!DOCTYPE html>
<html>
<head>
<script src="js/jQuery.js"></script>
<link type="text/css" rel="stylesheet" href="css/sketch.css">
<script src="js/sketch.js"></script>
</head>
<body>
<div class="grid_controls">
<button class="clear">Clear</button>
</div>
<div class="container">
</div>
</body>
</html>
CSS
/*=================
General
=================*/
body {
background: aqua;
}
/*=================
Sketchpad Holder
=================*/
.container {
width: 500px;
height: 400px;
background-color: orange;
overflow: hidden;
margin: auto;
position: relative;
top: 20px;
}
.box {
width: 16px;
height: 16px;
background: yellow;
display: inline-block;
margin: 1px 1px 1px 1px;
left: 0.5%;
right: auto;
position: relative;
}
.clear {
position: relative;
margin: auto;
text-align: center;
}
Javascript/Jquery
var default_grid_num = 435;
var div_limit = prompt("How large would you like your grid to be?");
var button_prompt = "Would you like to redraw the grids?";
/*var div_limit = prompt("number")*/
$(document).ready(function() {
for(var i = 1; i <= div_limit; i++)
$(".container").append("<div class='box'></div>");
$(".container > div").hover(function() {
$(this).css("background-color", "red");
});
$("button").click(function() {
$(".box").fadeOut();
if(confirm("Would you like to redraw the grid?"));
{
boxes_per_row = prompt("Define width of grid.");
}
});
});
What I want to do is get user input(.div_limit) and resize the divs(.box) based on the users input(.div_limit) So if the user only typed in the number one, the one div would take up the whole container box.
Here is what I have so far: http://codepen.io/zappdapper/full/epdPKb/
I know I can do this, but how?
I've made a jsfiddle that uses the mod operator % and some math to determine a percentage for the boxes.
I've included max_per_row as well to determine how many should show in a row.
UPDATE
I've taken another look at your example and your comment and come up with this:
http://jsfiddle.net/xw4cbo5n/
I edited the example slightly so that instead of asking two questions, only one is asked: "How many boxes per row of grid" (this is similar to your example).
It then goes on to draw out a grid where each row contains that number and sets each bow width and height accordingly. I also edited your CSS styles slightly.
Is that closer to what you're looking for?
I've created a JSFiddle which displays two prompts when run:
1) How many boxes would you like?
2) How many boxes should take up one row?
http://jsfiddle.net/5vg6n232/
After the responses are given, the grid is drawn.
I've edited your CSS slightly but the main functionality is driven by a couple of functions:
function drawBoxes(){
takes care of adding the correct number on divs to the page. After this is done it calls:
function restyle(numberofBoxesPerRow){
which simply reset's the CSS width of each box based on how may boxes per row the user specified.
Does this answer your question?
Given the following test case, the expected behaviour is that the lightblue element exactly matches the size of the red parent as the browser window is resized.
<html>
<head>
<script src="https://code.jquery.com/jquery-1.11.1.min.js"/></script>
<style type="text/css">
#viewport{
width: 100%;
height: 30%;
background-color: red;
}
#child{
background-color: lightblue;
}
</style>
</head>
<body>
<div id="viewport"><div id='child'></div></div>
<script>
window.addEventListener( 'resize', function(){
var width = $('#viewport').innerWidth();
var height = $('#viewport').innerHeight();
$('#child').css('height', height+'px');
$('#child').css('width', width+'px');
});
</script>
</body>
</html>
The actual behaviour on chrome 36.0.1985.143 is that sometimes (especially at smaller window sizes) the child element is set exactly 5px less tall and/or 1px less wide than the parent element. The issue stops happening if $('#child').css('width', width+'px'); is commented out.
It has been reported that the issue doesn't occur on firefox.
A similar issue seems to have been picked up on http://thewebivore.com/using-settimeout-win-race-condition-changing-views/ however I haven't been able to mitigate it with a timeout < 10 ms which is not really a solution.
I've plugged your example code into a fiddle and I seem to be having a host of other problems.
However, if I use vh and vw instead of %, I get much better results:
#viewport {
width: 100vw;
height: 30vh;
background-color: red;
}
#child {
background-color: lightblue;
}
fiddle here...