Dynamically adding a close button (Javascript) - javascript

Trying to add a 'X' - close button for a google maps marker. The markers will show small on the map but will enlarge when clicked (same marker, just increasing the size). I can add a close button but cannot get it to work (reduce the size back to original). Solutions need to be dynamically added please.
Fiddle: https://jsfiddle.net/gost1zLd/
var div = document.createElement('div');
div.style.width = '100px';
div.style.height = '100px';
div.style.background = 'black';
var img = document.createElement('img');
img.style.width = '100%';
img.style.height = '100%';
img.src = '';
var exit = document.createElement('div');
function large()
{
div.classList.add("large");
if (div.className == "large")
{
div.style.width = '300px';
div.style.height = '300px';
exit.innerText = 'X';
exit.style.width = '20px';
exit.style.height = '20px';
exit.style.fontSize = 'xx-large';
exit.style.fontWeight = 'bold';
exit.style.color = 'white';
exit.style.position = 'absolute';
exit.style.top = '5px';
exit.style.left = '265px';
}
}
function close()
{
div.classList.remove("large");
}
document.body.appendChild(div);
div.appendChild(img);
div.appendChild(exit);
div.addEventListener('click', large, false);
exit.addEventListener('click', close, false);
}

The problem is that removing the class large is not enough to reset the <div> to its original state since class large in itself is meaningless because it has no CSS definition. My advice is to move the styling to CSS instead of JavaScript. See fiddle: https://jsfiddle.net/gost1zLd/1/.

If you make separate functions, you can use start() again in your close() function to reset the original style. I've refactored your code a bit, hope it's self explanatory:
function close () {
div.classList.remove("large");
start();
}
Only problem with your setup is you will rebind everything when you would call start() on close(). Instead, try to separate functionality and the issue becomes clear.
DEMO
Additionally you can optimize the dynamic styling with some helper functions.
You need a function to convert a literal object to a css string.
You need a function to extend objects, similar to jQuery's $.extend() in order to set the style at once (doc) for both states (normal and large).
this.divStyle = convertLiteralToQs(cfg.div.style);
this.divLarge = convertLiteralToQs(extend(cfg.div.style, cfg.div.large));
this.div.style.cssText = this.divStyle; // normal style
this.div.style.cssText = this.divLarge; // large style
This will speed up the browser reflow for dynamic styling in JavaScript.
DEMO
Using this approach you can now more easily "style your logic" cross referencing the HTML DOM style object.

Related

How to add div and have it behave like a dev console?

I would like to dynamically create a div on a page using JS and have it behave like a dev console behaves in Chrome and Firefox. By this, I mean that when the div is visible, it does not negatively impact the display of other DOM elements. It would simply either "push up" or "push down" elements on the page.
Is this possible without having to redesign the application's DOM elements to account for the "div console?"
I've tried generating the div as the first element on the page, but that still would not account for DOM elements that are position absolute or fixed:
div = document.createElement('div');
div.id = 'wc-test-window';
div.style.width = "100%";
div.style.height = "200px";
div.style.backgroundColor = '#eee';
div.style.position = 'relative';
div.style.top = 0;
div.style.right = 0;
div.style.display = 'none';
document.body.insertBefore(div, document.body.firstChild);
I'm disappointed in this community for all of the unconstructive comments and downvotes for a perfectly legitimate question. Anyway, I solved it using framesets and frames for anyone looking for a viable answer to this problem.
function showDevConsole() {
var fs = document.createElement('frameset'),
f1 = document.createElement('frame'),
f2 = document.createElement('frame');
fs.rows = "200,*";
fs.framespacing = "0";
// top frame - show the dev console
f1.name = "topframe";
f1.src = "dev-console.html";
f1.marginwidth = "0";
f1.marginheight = "0";
f1.noresize = "noresize";
f1.scrolling = "no";
// bottom frame - show current page
f2.name = "bottomframe";
f2.src = window.location;
f2.marginwidth = "0";
f2.marginheight = "0";
f2.scrolling = "auto";
f2.frameborder = "0";
// append the frames to the frameset
fs.appendChild(f1);
fs.appendChild(f2);
// replace the entire body with the framset containing both frames
$("body").replaceWith(fs);
return false;
}
I put the current page on the bottom frame and the "console" at the top. Any DOM manipulations that the top frame can do on the bottom frame will be done via JS using the name or id of the frame.

Why is my image not loading?

At http://blajeny.com I have:
jQuery('body').click(function(event_object)
{
spark(event_object.pageX, event_object.pageY);
});
function spark(x, y)
{
console.log('Spark called.');
var image_object = new Image();
image_object.onLoad = function()
{
image_object.style.position = 'absolute';
image_object.style.zIndex = 1;
image_object.style.top = y;
image_object.style.left = x;
}
image_object.src = '/img/spark.png';
}
The intended effect, at this stage, is to load an image at the X and Y where the user clicked. (I want to do other things as well, like animate it, but right now I'm trying to get the image to show up where the user clicked.)
The javaScript console shows that the handler is being called, however I am not seeing what I expect, a hazy blue circle immediately below and to the right of the point where the mouse was clicked.
What can/should I do differently so it loads a fresh image below and to the right of the clicked coordinates?
Thanks,
As far as I know, the onLoad should be onload
var image_object = document.createElement('img');
image_object.onload = function() { // Note the small onload
// your code
}
// Also, append the image_object to DOM
document.body.appendChild(image_object);
I don't see you appending the image to DOM that's probably why you're not seeing it
$('body').append($(image_object));
I agree, first create an element with the "img" tag, assign the src value to it, and append it to the current div (in this case its the body), like so
var imgTag = document.createElement("img");
imgTag.src = '/img/spark.png';
document.body.appendChild(imgTag);
Hope this helps.
You never append the image to the DOM, that's why you can't see it.
You can do
document.body.appendChild(image_object);
You must also replace onLoad by onload and specify the top and left position with an unit :
image_object.onload = function() {
image_object.style.position = 'absolute';
image_object.style.zIndex = 1;
image_object.style.top = '100px';
image_object.style.left = '100px';
}
Demonstration

How do I get this transition to work in webkit?

I've have had success when using style sheets, but doing it in JavaScript isn't working for me. I need to do this programatically. Hopefully you will have realised that I'm trying to make the div 'grow'.
var myElement = document.createElement('div');
myElement.style.height = '0px';
myElement.style.padding = '0px';
myElement.style.webkitTransition = '2s'; /* problem with this line ? */
myElement.style.height = '200px';
I am not familiar with css3, but according to what I've tried this work:
var myElement = document.createElement('div');
myElement.style.height = '0px';
myElement.style.padding = '0px';
myElement.style.height = '0';
myElement.style.webkitTransition = '2s';
// Append the element to DOM
document.getElementById("a").appendChild(myElement);
// Alter the height after forcing a reflow
myElement.offsetWidth=myElement.offsetWidth;
myElement.style.height = '200px';​
/*// Alter the height later
setTimeout(function() {
myElement.style.height = '200px';
}, 1);​*/
Thanks to Esailija, you need to force a reflow, as stated in this answer of a question. Accessing properties such as offsetWidth will force a reflow, so that's a better way than a timer.

Resizing font based on screen width

Can someone help me with JavaScript code that resizes a font in a div if the screen width is lower than 1100px
if (window.screen.width <= 1100) {
var item = document.getElementById("div1");
item.style.fontSize = "25px";
item.innerHTML = "String";
}
This is what I have so far. Can someone help me with what to do next?
Your code works for me in JS Fiddle. Perhaps you are not specifying the correct id for your div or something like that.
http://jsfiddle.net/trott/GqFPY/
If you are hoping the code will be triggered on a browser resize, you will need to bind it to an event. (See Michael's answer.)
You will need to bind the action to the window.onresize event:
var resizeFonts = function() {
var item = document.getElementById("div1");
if (window.screen.width <= 1100) {
item.style.fontSize = "25px";
item.innerHTML = "String";
}
// Otherwise set a larger font
else item.style.fontSize = "30px";
};
window.onload = resizeFonts;
window.onresize = resizeFonts;
I have an OLD blog in which I posted about changing the font size, but it was made to show how to use jQueryUI slider. Maybe you can use some of the logic there to create your own solution:
http://weblogs.asp.net/thiagosantos/archive/2009/03/21/my-first-time-with-jquery-ui.aspx

plain javascript code to highlight an html element

to debug some javascript code, I am looking for javascript code (preferably just js, without libraries and dependencies) that can highlight a div or span (probably by putting over it a div or span of the same size and shape with a bright color and some transparency).
I pretty sure it can be done, but I don't know how to start.
CLARIFICATION
I need to put a semi transparent div on top of my element. Modifying the background or adding borders will not help as my elements have themselves backgrounds and borders.
element.style.backgroundColor = "#FDFF47";
#FDFF47 is a nice shade of yellow that seems perfect for highlighting.
Edit for clarification: You're over-complicating things. If you ever want to restore the previous background color, just store element.style.backgroundColor and access it later.
If you're debugging in a browser that supports the CSS outline, one simple solution is this:
myElement.style.outline = '#f00 solid 2px';
If for some reason you need to use javascript here is function that temporary highlits element background
function highlight(element) {
let defaultBG = element.style.backgroundColor;
let defaultTransition = element.style.transition;
element.style.transition = "background 1s";
element.style.backgroundColor = "#FDFF47";
setTimeout(function()
{
element.style.backgroundColor = defaultBG;
setTimeout(function() {
element.style.transition = defaultTransition;
}, 1000);
}, 1000);
}
Old post, but worth adding since it shows up in searches on the topic. A simple way to achieve a highlighting effect is:
myElement.style.filter = "brightness(125%)";
function highlight(element) {
var div = highlight.div; // only highlight one element per page
if(element === null) { // remove highlight via `highlight(null)`
if(div.parentNode) div.parentNode.removeChild(div);
return;
}
var width = element.offsetWidth,
height = element.offsetHeight;
div.style.width = width + 'px';
div.style.height = height + 'px';
element.offsetParent.appendChild(div);
div.style.left = element.offsetLeft + (width - div.offsetWidth) / 2 + 'px';
div.style.top = element.offsetTop + (height - div.offsetHeight) / 2 + 'px';
}
highlight.div = document.createElement('div');
// set highlight styles
with(highlight.div.style) {
position = 'absolute';
border = '5px solid red';
}
Do you use Firebug? It makes it very simple to identify dom elements and will highlight them in the page as you walk through the dom.
Here is a function that combines the top 2 answers:
function highlight(element){
let defaultBG = element.style.backgroundColor;
let defaultOutline = element.style.outline;
element.style.backgroundColor = "#FDFF47";
element.style.outline = '#f00 solid 4px';
setTimeout(function()
{
element.style.backgroundColor = defaultBG;
element.style.outline = defaultOutline;
}, 2000);
}

Categories