How to change all of a div's style attribute using JavaScript? - javascript

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>

Related

Javascript Logic in Extending Search Bar

I've created an expanding search bar: You click on the magnifying glass the input extends out and to the right, click it again and it closes. (See Fiddle Below).
I'm new to the world of JS and I thought this would be a great opportunity to implement some logic. Here's what I;m trying to do:
If the search bar is open and the inner.html is empty, if you click the "search" magnifying glass, I want to prevent the default submission of the form and simply close the search bar
If there is text, I want the form to be submitted.
Right now I've got the elements layered in such a way as to when you click the "search" button for the first time, the bar extends and the z-index of the button drops to one where the actual submit button is higher, but I want to control the functionality a little more.
What I've tried:
I tried creating a function that added an event listener that said, basically, if the bar has a width of 700px (the extended length) and the inner html is empty, bring the z-index of the extend button up back higher than the submit simply close the form. But I can't seem to work the logic out properly.
I'm wondering how in JS you can control the z-index.
Here is the code I tried and did not work. I tried something simply like just alerting when the task I wanted to watch for was done first but it doesn't seem to be working.
Any help would be wonderful.
Code:
HTML:
<div id="wrap">
<form id="myForm">
<input id="search" name="search" type="text" placeholder="What are we looking for?" />
<input id="search_submit" value="" type="submit">
</form>
</div>
CSS:
#wrap
{
margin: 50px 100px;
display: inline-block;
position: relative;
height: 60px;
float: right;
padding: 0;
}
input[type="text"]
{
height: 40px;
font-size: 35px;
border: none;
outline: none;
color: #555;
padding-right: 60px;
position: absolute;
width: 0px;
top: 0;
right: 0;
background: none;
z-index: 4;
cursor: pointer;
transition: width .4s ease-in-out;
}
input[type="text"]:focus
{
width: 700px;
z-index: 1;
border-bottom: 1px solid #bbb;
cursor: text;
}
input[type="submit"]
{
position: absolute;
height: 60px;
width: 60px;
display: inline-block;
float: right;
background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAMAAABg3Am1AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAADNQTFRFU1NT9fX1lJSUXl5e1dXVfn5+c3Nz6urqv7+/tLS0iYmJqampn5+fysrK39/faWlp////Vi4ZywAAABF0Uk5T/////////////////////wAlrZliAAABLklEQVR42rSWWRbDIAhFHeOUtN3/ags1zaA4cHrKZ8JFRHwoXkwTvwGP1Qo0bYObAPwiLmbNAHBWFBZlD9j0JxflDViIObNHG/Do8PRHTJk0TezAhv7qloK0JJEBh+F8+U/hopIELOWfiZUCDOZD1RADOQKA75oq4cvVkcT+OdHnqqpQCITWAjnWVgGQUWz12lJuGwGoaWgBKzRVBcCypgUkOAoWgBX/L0CmxN40u6xwcIJ1cOzWYDffp3axsQOyvdkXiH9FKRFwPRHYZUaXMgPLeiW7QhbDRciyLXJaKheCuLbiVoqx1DVRyH26yb0hsuoOFEPsoz+BVE0MRlZNjGZcRQyHYkmMp2hBTIzdkzCTc/pLqOnBrk7/yZdAOq/q5NPBH1f7x7fGP4C3AAMAQrhzX9zhcGsAAAAASUVORK5CYII=) center center no-repeat;
border: none;
outline:none;
top: -15px;
right: 0;
z-index: 2;
cursor: pointer;
transition: all .4s ease;
}
JS
var search = document.getElementById("myForm").search;
var search_submit = document.getElementById("myForm").search_submit;
function showOpen()
{
if(search.style.width=="700px")
{
alert("OPEN!");
}
};
search.addEventListener("click", showOpen);
showOpen();
HERE IS THE FIDDLE: https://jsfiddle.net/theodore_steiner/7begmkf3/37/
Your issue can be solved using a few basic JavaScript elements (if you're looking to get into basic logic, these are important to know). The JS uses onsubmit, onclick, and some basic form logic. Basically, when you try to submit the form it checks if the form is empty, and if it is, the program refuses to submit the code. I added the new JavaScript to the HTML file:
<script>
function check(){
value = document.forms["myForm"]["search"].value;
if(value == "" || value == null){
alert("please enter a search term");
return false;
}else{
document.getElementById("myForm").submit();
}
}
</script>
<div id="wrap">
<form id="myForm" onsubmit="return check()">
<input id="searchBar" name="search" type="text" placeholder="What are we looking for?" />
<input id="search_submit" value="" type = "submit">
</form>
</div>
fiddle: https://jsfiddle.net/q1L3Lstx/1/
It might also help in the future to look at the required element: http://www.w3schools.com/tags/att_input_required.asp
I saw a couple of issues with the code.
search and search_submit are pointing to the wrong items they can be like this:
var search = document.getElementById("search");
var search_submit = document.getElementById("search_submit");
You could call a function on submit. like this:
<form id="myForm" onsubmit="myFunction(event)">
finally you can work your code inside that function:
function myFunction(e){
if(search.value.length <= 0){
e.preventDefault();
alert('empty');
}
}

Element split-second out of place rendering

Plunker: https://plnkr.co/edit/6aBljcPRK78pLegnyL5p
Alright, so the example (in plunker, and also attached as code snippet to this question) is pretty straightforward. There is a div ("button") which can be clicked. When clicked, a loading element is displayed inside it. When the "operation" finishes (replaced by a setTimeout here), the loading element should disappear, and a message area appear above the div.
The effect I'm seeing (and which only occurs if the "operation" finishes as good as immediately) is that the loading element (in my example a Font Awesome icon) is rendered outside the box for a split second.
NOTE: the loading icon might not be shown at all the first time you click the element. Just use the "Reset" button and click again. For me it's produceable every time.
Since the display property of both elements are changed at the same time, I would have expected the browser to keep the loading icon inside the box until it would it disappear. This does not, however, seem to be the case.
I've used pure HTML / CSS / Javascript (well, Font Awesome) in order to avoid any bugs / weird behaviour with those.
Is this just how browsers render? Would there be a way to avoid this effect other than using a timeout to delay setting either property (which I consider really ugly for this use case)? I don't believe this is a purely visual effect (my eyes playing a trick on me), but it could be...
I've tried the following to see if anything changed (which it didn't):
Positioned the icon absolutely inside the ".content" element.
Replaced the icon with a static <img> tag.
Explicitly hid the icon element, and not just the parent one.
#messageBox {
display: none;
height: 50px;
background-color: #cccccc;
margin: 10px;
}
#element .content {
position: relative;
width: 120px;
margin: 0;
padding: 10px;
float: left;
box-sizing: border-box;
-moz-box-sizing: border-box;
font-size: 14px;
text-align: center;
}
#element .content .shadow {
height: 124px;
box-sizing: border-box;
-moz-box-sizing: border-box;
border-radius: 4px;
border: 1px dashed #ccc;
padding-top: 32px;
color: #bbb;
cursor: pointer;
}
#element .content .shadow:hover {
color: #888;
border-color: #999;
}
#element .content .shadow.inactive {
color: #bbb;
border-color: #999;
cursor: default;
padding-top: 48px;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Positioning plunker</title>
<link data-require="font-awesome#*" data-semver="4.5.0" rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.css" />
<script>document.write('<base href="' + document.location + '" />');</script>
<link rel="stylesheet" href="style.css" />
</head>
<body>
<script type = 'text/javascript'>
window.doSomething = function() {
var action = document.getElementById('actionButton');
var icon = document.getElementById('icon');
var message = document.getElementById('messageBox');
icon.style.display = "block";
window.setTimeout(function() {
message.style.display = 'block';
icon.style.display = 'none';
}, 50);
};
window.reset = function() {
var action = document.getElementById('actionButton');
var icon = document.getElementById('icon');
var message = document.getElementById('messageBox');
action.style.display = 'block';
icon.style.display = 'none';
message.style.display = 'none';
};
</script>
<div id="messageBox">Some box containing stuff to push down the content...</div>
<div id="element">
<div class="content" style="border:1px solid black; padding: 0">
<div id="actionButton" class="shadow" onclick="doSomething();">
<i id="icon" style="display: none" class="fa fa-cog fa-2x text-info"></i>
</div>
</div>
</div>
<button onclick="reset(); return false;">Reset</button>
</body>
</html>
I took a video and made a slow motion gif from the clicking. I'm pretty sure it's just an optical illusion. Here's eight total frames from the video:
I saw this first with this. Seems like the classic "Bird in a Cage" illusion.
window.setInterval(function() {
icon.style.display = "block";
message.style.display = "none";
}, 60)
window.setInterval(function() {
message.style.display = 'block';
icon.style.display = 'none';
}, 50);

Javascript, HTML5 (canvas) progressbar with update

I'm looking for the best way to do a progress bar (in my case it's a life bar for a game) in an html5 canvas.
I don't know if it's better to use javascript and dom element, or draw this bar directly in the canvas.
I need an update function, for example myBar.updateValue(40), and I need to show the new bar without refresh all the page or all the canvas, of course.
Do you know something like that? An existing script? Thanks!
It’s very easy in HTML/CSS:
<style>
#progress-holder{width:400px;height:20px;background:grey}
#progress{width:0;height:100%;background:black}
</style>
<div id="progress-holder">
<div id="progress"></div>
</div>
<script>
var progress = document.getElementById('progress');
function updateValue(perc) {
progress.style.width = perc+'%';
}
updateValue(40);
</script>
DEMO: http://jsbin.com/EGAzAZEK/1/edit
And animating with CSS: http://jsbin.com/EGAzAZEK/3/edit
HTML:
<div class='progress'>
<div class='progress-bar' data-width='//Enter a percent value here'>
<div class='progress-bar-text'>
Progress: <span class='data-percent'>//This is auto-generated by the script</span>
</div>
</div>
</div>
CSS:
html, body {
margin: 0;
padding: 15px;
width: 100%;
height: 100%;
position: relative;
color: #fff;
}
.progress {
position: relative;
width: 100%;
height: 30px;
}
.progress-bar {
margin-bottom: 5px;
width: 0%;
height: 30px;
position: relative;
background-color: rgb(66, 139, 202);
}
.progress-bar-text {
position: absolute;
top: 0px;
width: 100%;
text-align: center;
/*
Do not change the values below,
unless you want your text to display away from the bar itself. */
line-height: 30px;
vertical-align: middle;
}
jQuery:
$('.progress-bar').each(function (){
var datawidth = $(this).attr('data-width');
$(this).find("span.data-percent").html(datawidth + "%");
$(this).animate({
width: datawidth + "%"
}, 800);
});
Link to JSFiddle
The HTML data-width attribute is used to track the percent the bar should be set to. Change it to your liking.
The jQuery script works with ALL progress bars on your page (See the JSFiddle, so you don't have to copy and paste the same jQuery for every new progress bar.
(Just be sure to keep the structure of the HTML, or change it to your liking).
The div "progress" is just an expander, it can be named whatever your want - without you having to change the jQuery.
EDIT:
If you can use Javascript & HTML, don't use a canvas. Canvas (imho) are good for only 1 thing: Seat bookings for concerts, theaters and alike.

How can I log information without using alert in userscripts

i have an userscript which traces all the dynamically created tags in javascript of a webpage. the problem here is presently i am using alert box to dispaly the output. The problem with alert() is that it can be very obtrusive. For every alert, you need to click the OK button to proceed which wastes your time. so i want an alternative method like log files other than alert box. how can i do this.
i am restricted to use console.log
I would use some kind of console element statically placed on your page which can be hidden if necessary. See this jsFiddle.
HTML:
<div id="console">
<div class="header">
Console
<span class="expand" onclick="toggleConsole();">+</span>
</div>
<div class="content" style="display: none;"></div>
</div>
CSS:
#console {
position: fixed;
right: 0px;
bottom: 0px;
width: 300px;
border: solid 1px #dddddd;
}
#console .header {
background-color: #ededed;
border: solid 1px #dddddd;
}
#console .header .expand {
padding-right: 5px;
float: right;
cursor: pointer;
}
#console .content {
overflow: auto;
background-color: #F9F9F0;
width: 100%;
height: 180px;
}
Javascript:
function log(text) {
var consoleContent = document.getElementById('console')
.getElementsByClassName('content')[0];
var line = document.createElement('div');
line.className = 'consoleLine';
line.innerHTML = text;
consoleContent.appendChild(line);
}
function toggleConsole() {
var content = document.getElementById('console')
.getElementsByClassName('content')[0];
if (content.style.display === "none") {
content.style.display = "block";
document.getElementById('console')
.getElementsByClassName('expand')[0].innerHTML = "-";
} else {
content.style.display = "none";
document.getElementById('console')
.getElementsByClassName('expand')[0].innerHTML = "+";
}
}
document.onload = function() {
document.getElementById('console')
.getElementsByClassName('expand')[0].onclick = toggleConsole;
};
Use log("some text"); to output to your console !
Install firefox add-on to your Mozilla(if you are using) and you the follwing code:
console.log("test"+your_variable);
So above code will display all logs in console.If IE press F12 and check console.
If a normal user should be able to see it, using the console is not a very user-friendly way.
Define a space on your webpage (a <div> might be handy) where you want the information to be, and just add the messages to that space using javascript (or jQuery) to modify the DOM:
HTML:
<div id='logmessages'>Log messages:</div>
JavaScript
function log(yourMsg) {
document.getElementByID('logmessages').innerHTML() += yourMsg;
}
It might be friendly to allow the user to show/hide the div with a button or another way.
Create a fixed div either at the top, bottom or corner of your page with set width/height and overflow auto, then insert the log entries in it.

Issue with tabbing between form fields when using jQuery custom scrollbars

I'm working on project to provide a bolt-on tool for websites, which makes heavy use of jQuery. Presentation / design is crucial, and I want to replace the standard (ugly) scrollbar applied by the browser to html elements with overflowing content, with something better looking.
There are numerous jQuery plug-ins around that apply custom scrollbars and allow styling via CSS which is great, but all the ones I've tried seem to suffer from the same problem which is this: if the scrollable content contains a form with text fields etc, tabbing between fields does not activate the scrollbar, and in some cases can screw up the custom scrollbar layout altogether.
Two examples of plug-ins I've tried:
http://manos.malihu.gr/jquery-custom-content-scroller
http://baijs.nl/tinyscrollbar/
I've tried others also, but in all demos / examples the content is plain text. I've done a lot of searching on this already, but it seems no-one has tried using these plug-ins with form-based content.
All these plug-ins seem to work in more or less the same way, and I can see exactly what happens and why, but just wondered if anyone else has had this problem and / or found a solution?
This issue can be easily replicated as follows (using the tinyscrollbar plug-in):
Add this to a standard html test page -
CSS:
<style>
#tinyscrollbartest { width: 520px; height: 250px; padding-right: 20px; background-color: #eee; }
#tinyscrollbartest .viewport { width: 500px; height: 200px; overflow: hidden; position: relative; }
#tinyscrollbartest .overview { list-style: none; position: absolute; left: 0; top: 0; }
#tinyscrollbartest .scrollbar { position: relative; float: right; width: 15px; }
#tinyscrollbartest .track { background: #d8eefd; height: 100%; width: 13px; position: relative; padding: 0 1px; }
#tinyscrollbartest .thumb { height: 20px; width: 13px; cursor: pointer; overflow: hidden; position: absolute; top: 0; }
#tinyscrollbartest .thumb .end { overflow: hidden; height: 5px; width: 13px; }
#tinyscrollbartest .thumb, #tinyscrollbartest .thumb .end { background-color: #003d5d; }
#tinyscrollbartest .disable { display: none; }
</style>
Html:
<div id="tinyscrollbartest">
<div class="scrollbar">
<div class="track">
<div class="thumb">
<div class="end"></div>
</div>
</div>
</div>
<div class="viewport">
<div class="overview">
</p>Here's a text field: <input type="text"/><p>
...
// lots of content to force scrollbar to appear,
// and to push the next field out of sight ..
...
<p>Here's another field: <input type="text"/></p>
</div>
</div>
</div>
Plug-in reference (assuming jquery libraries etc are referenced also):
<script type="text/javascript" src="scripts/jquery.tinyscrollbar.min.js"></script>
Jquery code:
<script type="text/javascript">
$(document).ready(function () {
$('#tinyscrollbartest').tinyscrollbar();
});
</script>
Now click in the first text field so it has focus, hit the tab key to move to the next one and see what happens.
I understand your problem.. But is hard to find a good solution to this. You could try to set a focus event on your form elements. And let this event trigger the scrollbar_update function of tinyscrollbar. You can set the offsetTop of the form element that currently has focus as the methods parameter. I think that would work.
$('formelements').focus(function(){
YourScrollbar.tinyscrollbar_update(this.offsetTop);
});
I had to overwrite the standard tabbing functionality with my own:
$(".scrollable").each(function() {
if (!$(this).data("scrollbar"))
{
$(this).data("scrollbar", new Scrollbar({
holder:$(this)
}));
$(this).find("input").bind("keydown", function(e)
{
var keyCode = e.keyCode || e.which;
if (keyCode == 9)
{
e.preventDefault();
var scrollTo = $(this);
if (e.shiftKey)
{
var nextInput = $(this).prevAll("input:not([type=hidden])").first();
scrollTo = nextInput.prevAll("input:not([type=hidden]), label").first();
}
else
{
var nextInput = $(this).nextAll("input:not([type=hidden])").first();
}
if (nextInput.length)
{
console.log(scrollTo);
$(this).closest(".scrollable").data("scrollbar").scrollTo(scrollTo, function()
{
nextInput.focus().select();
});
}
}
});
}
});
It's a bit annoying to have to wait for the scroll but I don't see any other option.

Categories

Resources