How to change visibility css property using DOM when mouseover - javascript

I created an <img/> element from js and i want it to appear only when mouseover
The callback function makesVisible() is actually called but nothing is change.
I would like to change visibility from hidden to visible
var imgHover = document.createElement('img');
imgHover.setAttribute("src", "img/icona_play.jpg");
imgHover.style.width = "30px";
imgHover.style.height = "23px";
imgHover.style.position = "absolute";
imgHover.style.margin = "0 auto";
imgHover.style.left = "45px";
imgHover.style.bottom = "35px";
//I want to change this following property
imgHover.style.visibility = "hidden";
imgContainer.appendChild(imgHover);
//Calling the function when mouseover
imgContainer.addEventListener("mouseover", makeVisible, false);
function makeVisible()
{
imgHover.style.visibility = "visible";
}

You have an option of using an opacity property instead.
Initially set it like so: imgHover.style.opacity = 0;
Than in the makeVisible method change it to imgHover.style.opacity = 1;
Another solution to this problem would be setting addEventListener method on the container div. Assuming that you can have a container around the image with exactly the same dimensions as the Image.
For example:
imgContainer.addEventListener("mouseover", makeVisible, false);
The thing is that opacity and visibility will act the same in a sense of not collapsing the space that the element should occupy. What is different though that hidden element will ignore mouse/pointer events.

Your code works as it should provided that you set up a valid reference to imgContainer and that you set a valid path to an image for the dynamically created element:
var imgContainer = document.getElementById("container");
var imgHover = document.createElement('img');
imgHover.setAttribute("src", "https://www.wpclipart.com/signs_symbol/arrows/button_arrows/play_buttons/play_button_gray.png");
imgHover.style.width = "30px";
imgHover.style.height = "23px";
imgHover.style.position = "absolute";
imgHover.style.margin = "0 auto";
imgHover.style.left = "45px";
imgHover.style.bottom = "35px";
imgHover.style.visibility = "hidden";
imgContainer.appendChild(imgHover);
imgContainer.addEventListener("mouseover", makeVisible, false);
function makeVisible(){
imgHover.style.visibility = "visible";
}
<div id="container">Hover Over Me</div>
Having said that, you should avoid setting inline styles on elements as they are hard to override when needed and they often cause duplication of code. It's much simpler to set up CSS classes ahead of time and just apply/remove those classes as needed with the element.classList API.
Also, visibility does affect whether you see an element or not, but even when you don't see it, space is allocated in the UI for it, which isn't always desirable. In most cases, using a display:none to hide an element and then simply removing that instruction to show the element is the better approach.
Lastly, while using setAttribute() is certainly valid, you can also configure your elements via their direct properties. Almost all HTML attributes map to a corresponding JavaScript object property. Using these can make the code much simpler.
Take a look at an example that puts all this together:
var imgContainer = document.getElementById("container");
var imgHover = document.createElement('img');
// Just set properties of the element directly:
imgHover.src ="https://www.wpclipart.com/signs_symbol/arrows/button_arrows/play_buttons/play_button_gray.png";
// Just add pre-made classes to style the element
imgHover.classList.add("hoverImg");
imgHover.classList.add("hidden");
imgContainer.appendChild(imgHover);
imgContainer.addEventListener("mouseover", makeVisible);
function makeVisible(){
imgHover.classList.remove("hidden");;
}
.hidden { display:none; } /* Used when an element needs to be hidden */
/* This will be applied via JS */
.hoverImg {
width:30px;
height:23px;
position: absolute;
margin:0 auto;
left:45px;
bottom:35px;
}
<div id="container">Hover Over Me</div>

Here you were appending element like this
imgContainer.appendChild(imgHover);
So reference for imgHover element in dom will get
change. Fetch that element once again inside
makeVisible() function.
document.querySelector("img") // use your appropriate.

Related

Can't change html attribute via javascript

This is very odd, I'm getting videos via document.getElementsByTag('video') and I can't change their width nor any other value.
Here's the Javascript code I'm using -
window.onload = function() {
this.videos = document.getElementsByTagName('video');
var self = this;
for(var i=0;i<videos.length;i++) {
videos.item(i).addEventListener("loadedmetadata",
(function(index){
return function() {
console.log(self.videos[index].offsetWidth); //shows X
self.videos[index].offsetWidth = "480";
console.log(self.videos[index].offsetWidth); //shows X
}
})(i)
);
}
}
Example <video> tag -
<video><source src="videos/video_1.mp4" type="video/mp4"></video>
I have no idea what it is happening and I've never encountered such kind of problem.
Thanks
EDIT:
Using the setAttribute function just adds it to the live html, but the size isn't really changing
The offsetWidth is a read-only DOM property so you can not update it. However why not change the element width?
window.onload = function() {
this.videos = document.getElementsByTagName('video');
var self = this;
for(var i=0;i<videos.length;i++) {
videos.item(i).addEventListener("loadedmetadata",
(function(index){
return function() {
self.videos[index].width = "480";
}
})(i));
}
}
You can take into account the borders, paddings, margins...
Note there is a difference between three things you are conflating into one:
HTML attributes
DOM properties
CSS styles
This is an HTML attribute:
If you have a DOM element representing an HTML tag, you can modify the attributes like so:
var a = document.createElement('a')
a.setAttribute('href', "http://example.com")
This is a DOM property:
var a = document.createElement('a')
a.href = "http://example.com"
Note how a DOM property can be similarly named to an HTML attribute, but they are not the same thing. Oftentimes, changing an HTML attribute will modify the corresponding DOM property, but not vice versa. Also, not all attributes have matching properties, and so on.
CSS styles are accessed via the DOM property style(which corresponds to the HTML attribute style, but while the HTML attribute style is a string, the DOM property is an object):
var a = document.createElement('a');
a.style.width = "500px";
a.style.height = "20%";
There are HTML attributes "width" and "height", but their use is deprecated in favor of using styles. Also, "width" and "height" as HTML attributes can only be numerical values representing pixels - while a CSS style can be many variations(pixels, ems, percentages, etc)
In your specific case, just modify the width styling of your element to change its width.
Another thing in your code is the usage of this and self, which is entirely unneeded. this.videos is setting a property on the global object(window) for no reason. You can also avoid closing over the index property by using .bind():
window.onload = function() {
var videos = document.getElementsByTagName('video');
for (var i = 0; i < videos.length;i++) {
var video = videos.item(i);
video.addEventListener("loadedmetadata", (function () {
console.log(this.offsetWidth);
this.style.width = "480px";
console.log(this.offsetWidth);
}).bind(video));
}
}
Try using getAttribute and setAttribute, as in videos[index].setAttribute('offsetWidth', 480)
First off, this doesn't seem right:
for(var i=0;i<videos.length;i++) {
Shouldn't it be self.videos? Fix that.
Then, to change the video size, you can change the size of the element:
self.videos[index].width = "480";
or, even better, the CSS width:
self.videos[index].style.width = "480px";
The size of the video itself will automatically extend to the size of the video element.

Does Jquery/Javascript require an elem to be in the DOM to use .css()?

if(typeof this.description === 'undefined') {alert('No Description Set!'); return false;}
var tempDiv = document.createElement('div'); //create a div outside of the DOM
tempDiv.className = 'descriptionColumn formBox contentRow'; //make sure and use the
//same/equivlent class(s) to ensure accuracy
tempDiv.innerHTML = this.description; //insert the text
document.body.appendChild(tempDiv); //render div
lineHeight = parseInt($(tempDiv).css('line-height')); //get the line-height (make sure this is specified in CSS!)
//also we use Jquery here to handle any vender inconsistencies,
divHeight = tempDiv.clientHeight; //get the div height
tempDiv.parentNode.removeChild(tempDiv); //clean up, delete div
delete tempDiv;
return divHeight/lineHeight; //divide the height by the line-height and return
This code works, I am trying to calculate the number of lines in a div. That said I wasn't able to get the line-height until after I added this element to the DOM.
Origionally I planned on not adding it at all because I only use it to calcuate the number of lines in the DIV.
It makes sense that it wouldn't have a height until I added it, I am just wondering if I did the right thing, or if there is a way to get the line-height without adding it to the DOM in the first place.
Rendering/Layout decision by browser is taken by browser 2 conditions:
1)new element is inserted
2)some element's style has been changed
3)sometimes when window is resized
so until the element is in DOM Tree browser will not give Layout related style to it.
consider following code:
var div = document.createElement(div);
var style = window.getComputedStyle(div);
console.log( style.color );//prints "" (empty string)
why??
because window.getComputedStyle() returns the CSS style which are actully present in DOM(browser).
now,
document.body.appendChild(div);
var style = window.getComputedStyle(div);
console.log( style.color );//prints rgb(somevalue)
why??
because rendering engine has decided the CSS properties.
//One gotcha
var div2 = document.createElement("div");
div2.style.color = "red";
console.log( $(div2).css("color") ); //prints red because jQuery gives preference to div2.style.color over window.getComputedStyle(div2);
but console.log ( window.getComputedStyle(div2).color );//prints "" .... this proves that browser has not yet decided the properties of div2
Yes, it is. But ... if you have jQuery on your page, why don't you use it?
var $div = $('<div/>', {
class: 'descriptionColumn formBox contentRow',
text: 'Description',
css: {
position: 'absolute',
left: '-99999px'
}
}).prependTo('body'); // element wouldn't be visible for user on this step
//your calculations
$div.remove();

Close a Div element if you click outside of it

I need a function that hide the div if i click outside of the div area ?
I have defined a Div on Position: none, which I make visible by using the following function:
My Div:
<div id="TopBarBoxInfo1" onclick="showSerachOptions('BoxBox');" >
</div>
My function:
function showSerachOptions(element){
var element = document.getElementById(element);
// And then it will change what it is
if(element.id == 'Box'){
if(element.style.display == 'none'){
element.style.display = 'block';
}
else{
element.style.display = 'none';
}
}
}
Now I would need a function, which allows to close the div if you click with the mouse pointer outside of the area of the div. Please describe your solution in detail, because I am a beginner!
Since being registered doesn't mean knowing the rules i'm going to answer your question BUT you should always ask in english.
var body = document.getElementsByTagName('body')[0];
body.click = function(e){
//here you can get e.target as the click-target-element or
// e.srcElement(Microsoft) as the click-target-element
//than you can handle what you want to do since e.target/srcElement will give you
// an element (just like document.getElementById
}
remember the .click may not be the best way - addEventListener would be much better afaik

Remove Style on Element

I was wondering if this is possible.
There's this element
<div id="sample_id" style="width:100px; height:100px; color:red;">
So I want to remove width:100px; and height:100px;
the result would be
<div id="sample_id" style="color:red;">
Any help would be apprreciated. :)
You can edit style with pure Javascript. No library needed, supported by all browsers except IE where you need to set to '' instead of null (see comments).
var element = document.getElementById('sample_id');
element.style.width = null;
element.style.height = null;
For more information, you can refer to HTMLElement.style documentation on MDN.
var element = document.getElementById('sample_id');
element.style.removeProperty("width");
element.style.removeProperty("height");
Use javascript
But it depends on what you are trying to do. If you just want to change the height and width, I suggest this:
{
document.getElementById('sample_id').style.height = '150px';
document.getElementById('sample_id').style.width = '150px';
}
TO totally remove it, remove the style, and then re-set the color:
getElementById('sample_id').removeAttribute("style");
document.getElementById('sample_id').style.color = 'red';
Of course, no the only question that remains is on which event you want this to happen.
Update: For a better approach, please refer to Blackus's answer in the same thread.
If you are not averse to using JavaScript and Regex, you can use the below solution to find all width and height properties in the style attribute and replace them with nothing.
//Get the value of style attribute based on element's Id
var originalStyle = document.getElementById('sample_id').getAttribute('style');
var regex = new RegExp(/(width:|height:).+?(;[\s]?|$)/g);
//Replace matches with null
var modStyle = originalStyle.replace(regex, "");
//Set the modified style value to element using it's Id
document.getElementById('sample_id').setAttribute('style', modStyle);
$("#sample_id").css({ 'width' : '', 'height' : '' });
You can simply set that style to [unset], It forces CSS to pretend that style was never assigned to the given element.
var element = document.getElementById('sample_id');
element.style.width = "unset";
element.style.height = "unset";
Specifying auto on width and height elements is the same as removing them, technically. Using vanilla Javascript:
images[i].style.height = "auto";
images[i].style.width = "auto";
Just use like this
$("#sample_id").css("width", "");
$("#sample_id").css("height", "");

dynamically adding/removing a div to html

I want to dynamically create a div element with id="xyz". Now before creating this, I want to remove any other div with id ="xyz" if it exists. How can i do it?
var msgContainer = document.createElement('div');
msgContainer.setAttribute('id', 'xyz'); //set id
msgContainer.setAttribute('class', 'content done'); // i want to add a class to it. it this correct?
var msg2 = document.createTextNode(msg);
msgContainer.appendChild(msg2);
document.body.appendChild(msgContainer);
}
How can i remove all divs with id =xyz if they exist before executing above code?
Removing:
var div = document.getElementById('xyz');
if (div) {
div.parentNode.removeChild(div);
}
Or if you don't control the document and think it may be malformed:
var div = document.getElementById('xyz');
while (div) {
div.parentNode.removeChild(div);
div = document.getElementById('xyz');
}
(Alternatives below.)
But you only need the loop with invalid HTML documents; if you control the document, there's no need, simply ensure the document is valid. id values must be unique. And yet, one sees plenty of documents where they aren't.
Adding:
var msgContainer = document.createElement('div');
msgContainer.id = 'xyz'; // No setAttribute required
msgContainer.className = 'someClass' // No setAttribute required, note it's "className" to avoid conflict with JavaScript reserved word
msgContainer.appendChild(document.createTextNode(msg));
document.body.appendChild(msgContainer);
If you don't like the code duplication in my loop above and you think you need the loop, you could do:
var div;
while (!!(div = document.getElementById('xyz'))) {
div.parentNode.removeChild(div);
}
or
var div;
while (div = document.getElementById('xyz')) {
div.parentNode.removeChild(div);
}
...although that last may well generate lint warnings from various tools, since it looks like you have = where you mean == or === (but in this case, we really do mean =).

Categories