Cannot update div style attributes - javascript

I'm trying to change a couple of style attributes. Here is the style I first assigned to clickedMenuHexagonDiv:
clickedMenuHexagonDiv.style.MozTransform = "scale(.9999)";
clickedMenuHexagonDiv.style.width = num2px(this.width);
clickedMenuHexagonDiv.style.marginRight = "3px";
clickedMenuHexagonDiv.style.position = "relative";
clickedMenuHexagonDiv.style.zIndex = "5";
clickedMenuHexagonDiv.style.styleFloat = "right";
clickedMenuHexagonDiv.style.cssFloat = "right";
Here is the code later on, for the attributes I want to change:
clickedMenuHexagonDiv.className = "centerHexagonDiv";
clickedMenuHexagonDiv.style.bottom = "auto";
clickedMenuHexagonDiv.style.right = "auto";
clickedMenuHexagonDiv.style.float = "none";
alert("clickedMenuHexagonDiv: " + clickedMenuHexagonDiv.style.cssText);
And here is the output of the alert:
clickedMenuHexagonDiv: transform: scale(0.9999); width: 80px; margin-right: 3px; position: relative; z-index: 5; float: right; right: auto; bottom: auto;
As you can see, it only updates attributes that weren't declared earlier. There were no console errors. Also, somewhat oddly, bottom and right were changed by the jquery animate function (I put an alert in before clickedMenuHexagonDiv.className = "centerHexagonDiv";, and it showed values other than "auto" for bottom and right.
I figured out that I can sort of fix this if I insert clickedMenuHexagonDiv.style.cssText = "" before changing the style attributes, but then I have to declare all of the attributes again. I'd rather try to understand why I can't update specific attributes.

If figured it out: I needed to use "styleFloat" and/or "cssFloat". "float" isn't a css property.
Here's the updated code (only the second section needed updating):
clickedMenuHexagonDiv.className = "centerHexagonDiv";
clickedMenuHexagonDiv.style.bottom = "auto";
clickedMenuHexagonDiv.style.right = "auto";
clickedMenuHexagonDiv.style.styleFloat = "none";
clickedMenuHexagonDiv.style.cssFloat = "none";

Related

SVG object display toggle stops EventListener

I managed to load an external svg and to grab the path's name and insert it into a tooltip.
But when i now toggle the display of the div, containing the svg object, off and on again the EventListener somehow doesn't work anymore (it only works in FireFox) and the name of the path will not show again.
Any idea Why Safari and Chrome won't listen anymore?
window.onload = function() {
var a = document.getElementById("Map1");
var svgDoc = a.contentDocument;
var myImage = svgDoc.getElementsByTagName("path");
for (var i = 0; i < myImage.length; i++) {
myImage[i].addEventListener('mouseover', show);
myImage[i].addEventListener('mouseout', hide);
}
var text = document.getElementById("show");
function show() {
var myID = this.id;
text.innerHTML = myID;
document.getElementById("show").style.display = "block";
}
function hide() {
var myID = this.id;
text.innerHTML = '';
document.getElementById("show").style.display = "none";
}
}
function myFunction() {
var toggle = document.getElementById("Map");
toggle.style.display = toggle.style.display === 'none' ? 'block' : 'none';
}
#show {
display: none;
}
<button onclick="myFunction()">Show Map!</button>
<div id="show" style="position: absolute; left: 100px; background-color:aqua; padding: 5px;"></div>
<div id="Map" style="display: block;"><object id='Map1' data="Test-01.svg" type="image/svg+xml">Your browser doesn't support SVG</object></div>
That's a weird bug, which I did reproduce here.
The core of this bug is that webkit browsers will unload an <object> or <embed> content when its CSS display is set to none. Doing so, it will remove all of its content, your event listeners included.
Thus, you've got two possible workarounds (at least) :
1 - Use an <iframe>. This tag is not concerned by this bug...
Live example
2 - Use some other CSS rules to hide your <object>.
Something like the following should provide the same functionality as display: none
object.hidden {
position: absolute;
z-index: -99;
width: 0px;
height: 0px;
visibility: hidden;
pointer-events: none;
}
Live example
And to add more weirdness, this bug doesn't affect BlobURIs in chrome (couldn't test in Safari, the blob gets downloaded, one other bug...).

When using element.style = <some CSSStyleDeclaration> makes element dissapear

I use, (pls never mind the selector, I know it should be changed but it is found nevertheless).
let leftArrow = <HTMLElement> document
.querySelector('div[style="position: absolute; left: 6px; transform: skewX(22.6deg);' +
' transform-origin: 0px 0px 0px; height: 24px; width: 10px;' +
' box-shadow: rgba(0, 0, 0, 0.6) 0px 1px 6px; background-color: rgb(255, 255, 255);"]');
Then I use:
let myStyle = leftArrow.style; //this gets me a CSSStyleDeclaration object
console.log(myStyle); // those are equal objects
console.log(leftArrow.style); // those are equal objects
But when I do:
leftArrow.style = myStyle; //this should change nothing ?!
my element dissappears ?!
My goal is to use a class and then do sth like this:
leftArrow.style = this.getStyleFromClass(selector_to_find_class_name);
But after simple:
leftArrow.style = myStyle;
my element from upper one becomes :
<div></div>
which makes it basically not visible. Why ?
I think what you are trying to do is apply the original inline styles back. To do this, you can use cssText to get the values, and than you can set it back.
var div = document.getElementById("x");
var backUp = div.style.cssText;
div.style.backgroundColor = "yellow";
div.style.color = "blue";
window.setTimeout( function () {
div.style.cssText = backUp;
}, 4000);
<div id="x" style="background-color:red">Hello</div>
leftArrow.style = myStyle; //this should change nothing ?!
Yes but only if you have:
let myStyle = leftArrow.style; //this gets me a CSSStyleDeclaration object
letArrow.style = myStyle;
This is most likely not the code you have and you are generating the object on the fly. Do not assign to style directly. Instead assign to members of style e.g. letArrow.style.color = "red"

Getting margin-top with obj.style.marginTop failed, but it worked if marginTop was set explicitly first

Please review this question first:
document.body.style.marginTop returning blank string in JS
There were a couple working solutions... then there was my working solution:
https://stackoverflow.com/a/34473070/2813224
Summary:
Tried to get the margin-top value of a div by doing the following code as well as variations of the same:
/*~~~~~~~~~~~~~~~~~~~[ Attempt 1 ]~~~~~~~~~~~~~~~~~~~~~~~~*/
alert(document.getElementById("testDiv").style.marginTop);
/*~~~~~~~~~~~~~~~~~~~[ Attempt 2 ]~~~~~~~~~~~~~~~~~~~~~~~~*/
var tDiv = document.getElementById('testDiv');
var tMgn = tDiv.style.marginTop;
alert(tMgn);
/*~~~~~~~~~~~~~~~~~~~[ Attempt 3 ]~~~~~~~~~~~~~~~~~~~~~~~~*/
var tDiv = document.querySelector('testDiv');
alert(tDiv.style.marginTop);
/*~~~~~~~~~~~~~~~~~~~[ Attempt 4 ]~~~~~~~~~~~~~~~~~~~~~~~~*/
function mTop() {
var tDiv = document.getElementById('testDiv');
var tMgn = tDiv.style.marginTop;
alert(tMgn);
}
mTop();
The one thing these combinations had in common is .style.marginTop. The Op's question was answered shortly thereafter.
My question is this:
I don't know why, but I got it working by explicitly assigning the margin-top by JS first. I never had to set a style value first just to get a style value back, especially if it's already set by CSS. Why would something simple like:
alert(document.getElementById("testDiv").style.marginTop);
not work, but this does:
document.getElementById("testDiv").style.marginTop = "50px";
alert(document.getElementById("testDiv").style.marginTop);
When CSS is already:
#testDiv { margin-top: 50px; }
?
Snippet of my working answer:
document.getElementById("testDiv").style.marginTop = '50px';
document.body.style.marginTop = '100px';
alert(document.getElementById("testDiv").style.marginTop);
alert(document.body.style.marginTop);
body {
margin-top: 100px;
}
#testDiv {
margin-top: 50px;
}
hi!
<div id="testDiv">test</div>
You need to use the window.getComputedStyle to get the style that was computed, but not set through JavaScript, as HTMLElement.style can get only the inline styles.
The syntax is:
var style = window.getComputedStyle(element[, pseudoElt]);
So in your case, it should be:
var elem = document.getElementById("testDiv");
var theCSSprop = window.getComputedStyle(elem,null).getPropertyValue("margin-top");
document.getElementById("output").innerHTML = theCSSprop;

Javascript transition duration won't work

I wan't to make show() and hide() method like jquery have, but with pure javascript because I want to modify how the element show and hide. But after my attempts, I've changed where the code placed, changed the code, etc, still it won't work. Only for a few times it was work but it was inconsistent (when I try to run it through firefox, it work for once but never again). The display (block and none) and the exact width and height is work, but not the 2s transition. How to fix this?
<!doctype html>
<html>
<head>
<style>
div {
width: 0px;
height: 0px;
background-color: yellow;
border: 1px solid black;
display: none;
}
</style>
</head>
<body>
<div>
</div>
<button>
click !
</button>
<script>
var x = document.getElementsByTagName("button");
var y = document.getElementsByTagName("div");
x[0].onclick = fungsi;
function fungsi() {
if (y[0].style.display != "block") {
y[0].style.display = "block";
y[0].style.transition = "width 2s";
y[0].style.transition = "height 2s";
y[0].style.width = "100px";
y[0].style.height = "100px";
} else {
y[0].style.display = "";
y[0].style.transition = "width 2s";
y[0].style.transition = "height 2s";
y[0].style.width = "";
y[0].style.height = "";
}
};
</script>
</body>
</html>
I've messed around with your code and found that the reason for your problem was the switching from display: none; to display: block; and back. I've made a simple solution for this if you would like to use it.
Here is the modified CSS code.
div {
width: 0px;
height: 0px;
background-color: yellow;
border: none;
}
Here is the modified JS code.
var x = document.getElementsByTagName("button");
var y = document.getElementsByTagName("div");
x[0].onclick = fungsi;
var expanded = false;
function fungsi() {
y[0].style.transition = "all 2s";
if (!expanded) {
y[0].style.border = "1px solid black";
y[0].style.width = "100px";
y[0].style.height = "100px";
expanded = true;
} else {
var applyBorder = function () {
y[0].style.border = "none";
};
y[0].style.width = "0";
y[0].style.height = "0";
expanded = false;
setTimeout(applyBorder, 2000);
}
};
And here is a JSFiddle of this code for an example.
It could be something to do with vendor prefixes
So as well as having the following:
y[0].style.transition
You will also need:
y[0].style.mozTransition
y[0].style.webkitTransition
Try that, hopefully should work.
What you are doing is not animating show and hide with "pure javascript", it really is animating show and hide with CSS3. You are just setting the CSS properties trough javascript!
That being said, CSS3 transitions are not supported by every browser. For example even IE9 does not support it. Some other browser only work with prefixed versions of this property.
Try setting -moz-transition, -webkit-transition and -o-transition too.
For more details see: Transition browser support
However if you expect your animation to work across all major platforms I suggest you to use jQuery and try adjusting the settings to your desired behavior..
When you run
y[0].style.transition = "width 2s";
y[0].style.transition = "height 2s";
The first line will be overwritten by the second. So the transition goes only for width or height at a time, and when one of them is 0, the transition will be invisible.
You should set transition like this:
y[0].style.transition = 'width 2s,height 2s';
Or just set it for all properties that support transition:
y[0].style.transition = 'all 2s';
BTW, since the transition property is not changing, you should set them outside the changing part.
Another problem is, the <div> must be visible before the animation starts, otherwise it will have the desired width and height once become visible, and no transition is needed any more. visibility is another choice since an element with visibility: hidden still takes the place.
Here is a working copy of code:
<!doctype html>
<html>
<head>
<style>
div {
width: 0px;
height: 0px;
background-color: yellow;
border: 1px solid black;
/* Use visibility instead of display */
visibility: hidden;
}
</style>
</head>
<body>
<div>
</div>
<button>
click !
</button>
<script>
var x = document.getElementsByTagName("button");
var y = document.getElementsByTagName("div");
x[0].onclick = fungsi;
// set transition
y[0].style.transition = "width 2s,height 2s";
function fungsi() {
if (y[0].style.visibility != "visible") {
y[0].style.visibility = "visible";
y[0].style.width = "100px";
y[0].style.height = "100px";
} else {
y[0].style.visibility = "";
y[0].style.width = "";
y[0].style.height = "";
}
};
</script>
</body>
</html>
And something more, if you want to hide the element after the animation ends, setTimeout will work.

Dynamically created divs not showing next to each other

I am dynamically creating divs and I want them to appear next to each other. I have the following code and after applying style to it (line 5) they keep showing one of top of the other. Please help.
rmc.onstream = function (e) {
if (e.isVideo) {
var uibox = document.createElement("div");
uibox.appendChild(document.createTextNode(e.userid));
uibox.className = "userid";
uibox.id = "uibox-" + e.userid;
uibox.style.cssText = 'display: inline-block; float: left';
document.getElementById('video-container').appendChild(e.mediaElement);
document.getElementById('video-container').appendChild(uibox);
} else if (e.isAudio) {
document.getElementById('video-container').appendChild(e.mediaElement);
}
else if (e.isScreen) {
$('#cotools-panel iframe').hide();
$('#cotools-panel video').remove();
document.getElementById('cotools-panel').appendChild(e.mediaElement);
}
};
Your styles are only being applied to uibox, and you need to apply them to emediaElement too:
if (e.isVideo) {
var uibox = document.createElement("div");
uibox.appendChild(document.createTextNode(e.userid));
uibox.className = "userid";
uibox.id = "uibox-" + e.userid;
uibox.style.cssText = 'float: left; width: 50%';
e.mediaElement.style.cssText = 'float: left; width: 50%';
document.getElementById('video-container').appendChild(e.mediaElement);
document.getElementById('video-container').appendChild(uibox);
}
Here is a working pen - I had to modify your code since I can't see where e.mediaElement is coming from, but you can get the idea: http://jsbin.com/woluneyixa/1/edit?html,css,js,output
If you're still having issues, please create a working codepen so we can see the problem you're having.
Also, using display: inline-block and float: left; is unnecessary; inline-block will have no effect whatsoever when using float.

Categories