Javascript - Multi-Usage of General Function - javascript

I have a example of a situation here, I want to change the color of a div when clicked. Do I have to have two different functions, one for each div? What if the functions that I wanted to apply to the div was very complex? What if I had hundereds of the div? Can I make a general function, that can be applied for every div? By this I do not mean for example document.getElementsByClassName(" ... "), I want to for example change the color of the separately.
To be clear, how can I apply the same function to different objects? Something like document.getElementThatIsClicked(" ... " ) Thank you.
function changeColor1() {
document.getElementById("div1").style.backgroundColor = "#21a9c9";
}
function changeColor2() {
document.getElementById("div2").style.backgroundColor = "#21a9c9";
}
<div id="div1" onClick="changeColor1()" style="position:absolute; top:10px; left: 10px; width:200px; height: 200px; background-color:#000000;"></div>
<div id="div2" onClick="changeColor2()" style="position:absolute; top: 10px; left: 220px; width:200px; height: 200px; background-color:#000000;"></div>

You can make a function that accepts the element you want to change the color and make the function change the background color for that element
function changeColor(elem) {
elem.style.backgroundColor = "#21a9c9"
}
<div id="div1" onClick="changeColor(this)" style="position:absolute; top:10px; left: 10px; width:200px; height: 200px; background-color:#000000;"></div>
<div id="div2" onClick="changeColor(this)" style="position:absolute; top: 10px; left: 220px; width:200px; height: 200px; background-color:#000000;"></div>

Copied from https://stackoverflow.com/a/32828729/227299 but:
Avoids setting handlers using inline HTML attributes in favor of unobtrusively setting handlers from JavaScript itself. See onclick="" vs event handler
Avoid setting CSS attributes from HTML attributes. See What's so bad about in-line CSS?
function changeColor(elem) {
elem.style.backgroundColor = "#21a9c9"
}
var divs = document.querySelectorAll('div');
for (var i = 0; i < divs.length; i++) {
divs[i].addEventListener('click', function(e) {
changeColor(this);
});
}
#div1,#div2 {
display: inline-block;
width: 200px;
height: 200px;
background-color:#000000;
}
<div id="div1"></div>
<div id="div2"></div>

Related

Replacing a containers content with css transition between with unkown height

I would like to replace the content of a modal popup dynamically, and it do a smooth transition between the old size and the new size.
I thought I may be able to do this using CSS transition, however I have been unsuccessful so far.
My setup is something similar to the JS fiddle here, where I have a container, and I swap out the inner content with different width and height.
http://jsfiddle.net/Lsf76eby/24/
html
<input type="button" value="press me" onclick="changeDiv()" />
<div id="container">
<div id="a">
</div>
</div>
js
function changeDiv(){
var b = $('<div id="b">');
$('#container').empty().append(b);
}
css
#container{
transition: 2s;
height: auto;
}
#a {
height: 200px;
width: 200px;
background:blue;
}
#b {
height: 400px;
width: 300px;
background:red;
}
I made a few changes in a fork of the fiddle here. You can read more about this from https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Transitions/Using_CSS_transitions
I added a new javascript function, added a css property, and reorganized the css a little
You must define all the properties you will make subject to the transition using transition-property
One significant change is that my javascript function (as adapted from MDN) switches classes on a single div rather than switching the div itself.
Hope this helps!
html
<div id="container">
<div id="target" class="a">
</div>
</div>
javascript
//pretty much straight from the MDN doc...
function updateTransition() {
var el = document.querySelector("div.a");
if (el) {
el.className = "b";
} else {
el = document.querySelector("div.b");
el.className = "a";
}
return el;
}
css
#container{
height: auto;
}
#target{
transition: 2s;
transition-property: width height background-color;
}
.a {
height: 200px;
width: 200px;
background-color:blue;
}
.b {
height: 400px;
width: 300px;
background-color:red;
}

Hover over an element covered by another element's padding

So I have a map composed by tiles that are svg elements.
In the image, the tile itself is the blue area, but it has a buffer area to allow geometries that span outside the tile to render whole. The problem is that this buffer area (in green), is covering the geometries from other tiles that are below it. This buffer zone is set in CSS as the following:
padding: 128px;
margin: -128px;
Is there a way to hover/click "through" the buffer area, or is there a better approach in CSS to achieve this?
Padding is part of a element, therefore will react like it was content of your tag.
See here. If you absolutely need to have that spacing to be padding, you can't click anything behind neither content nor padding.
You might consider changing your layering, using z-index, but for further advise on this, you'll have to provide further code, your HTML Markup and CSS code.
If that blue thingy is the only element that needs this treatment, then I suggest creating a key bind to move that element to the back with z-index, and be done with it.
If you require this functionality on all of these red balls, the thing to do would probably be to move, the one you click on, to the back with z-index ( again ).
Both of these require you to use JavaScript most likely, unless you want to move that big blue element to the back on hover.
To always move the clicked element to the back you could just keep track of what was the last assigned z-index, and decrease it by one every time you assign it to a new object.
Something like this would probably do:
#box1 { position: absolute; background-color: #123; width: 100px; height: 100px; top: 200px; left: 300px; opacity: 0.9; }
#box2 { position: absolute; background-color: #ABC; width: 100px; height: 100px; top: 250px; left: 350px; opacity: 0.8; }
<div class="box" id="box1"></div>
<div class="box" id="box2"></div>
<script type="text/javascript">
var boxes = document.getElementsByClassName("box");
var length = boxes.length;
var index = 0;
function moveToBack(event)
{
var element = this;
this.style.zIndex = index;
index--;
return false;
}
for(var i = 0; i < length; i++)
{
var box = boxes[i];
box.addEventListener("click", moveToBack, false);
}
</scirpt>
Does that do the job ? or did you mean something else entirely ?
Only way I can seem to get it to work is to add a child inner element and give pointer-events:none to the wrapper and pointer-events:auto to the inner child element. It's not ideal as support for pointer-events is limited and there's no telling if all browsers will respect a child of pointer-events:none element having a different value than its parent. It will need tested. Well, in any case, here is the code:
$('.tile').on('mouseenter', function(){
$('.info', this).find('.tile-info').remove();
var ts = new Date().getTime();
$('.info', this).append('<div class="tile-info">mouseenter tile '+ts+'</div>');
});
$('.tile').on('mouseleave', function(){
$('.info', this).find('.tile-info').remove();
var ts = new Date().getTime();
$('.info', this).append('<div class="tile-info">mouseleave tile '+ts+'</div>');
});
$('.inner').on('mouseenter', function(){
$('.info', this).find('.inner-info').remove();
var ts = new Date().getTime();
$('.info', this).append('<div class="inner-info">mouseenter inner '+ts+'</div>');
});
$('.inner').on('mouseleave', function(){
$('.info', this).find('.inner-info').remove();
var ts = new Date().getTime();
$('.info', this).append('<div class="inner-info">mouseleave inner '+ts+'</div>');
});
.tile {
width: 200px;
height: 200px;
background: rgba(100,100,200,0.2);
padding: 50px;
margin: -50px;
position: absolute;
pointer-events:none;
}
.tile:nth-of-type(1) {left: 300px;top: 20px;}
.tile:nth-of-type(2) {left: 90px;top: 210px;}
.tile:nth-of-type(3) {left: 0px;top: 0px;}
.tile:nth-of-type(4) {left: 360px;top: 240px;}
.tile .inner {
width: 100%;
height: 100%;
background: rgba(200,100,100,0.2);
pointer-events:auto;
overflow: auto;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="tile">
<div class="inner">
<div class="info"></div>
</div>
</div>
<div class="tile">
<div class="inner">
<div class="info"></div>
</div>
</div>
<div class="tile">
<div class="inner">
<div class="info"></div>
</div>
</div>
<div class="tile">
<div class="inner">
<div class="info"></div>
</div>
</div>

multiple lightbox gallery on one page

how can i fix this? when i click "smile" it appears smile but when i click sad it also appear a smiley face.
SMILE<br>
<div id="light"><img src="http://upload.wikimedia.org/wikipedia/commons/thumb/8/85/Smiley.svg/1024px-Smiley.svg.png" width=100 height=100></div>
SAD
<div id="light"><img src="http://www.clipartbest.com/cliparts/MiL/kkB/MiLkkBAia.png" width=100 height=100></div>
<div id="fade" onClick="lightbox_close();"></div>
CSS: fade for the close and light is for the the lightbox.
#fade{
display: none;
position: fixed;
top: 0%;
left: 0%;
width: 100%;
height: 100%;
background-color: #000;
z-index:1001;
-moz-opacity: 0.7;
opacity:.70;
filter: alpha(opacity=70);
}
#light{
display: none;
position: absolute;
top: 50%;
left: 50%;
width: 300px;
height: 200px;
margin-left: -150px;
margin-top: -100px;
padding: 10px;
border: 2px solid #FFF;
background: #CCC;
z-index:1002;
overflow:visible;
javascript: for the open and close function
window.document.onkeydown = function (e)
{
if (!e){
e = event;
}
if (e.keyCode == 27){
lightbox_close();
}
}
function lightbox_open(){
window.scrollTo(0,0);
document.getElementById('light').style.display='block';
document.getElementById('fade').style.display='block';
}
function lightbox_close(){
document.getElementById('light').style.display='none';
document.getElementById('fade').style.display='none';
You cannot use the same ID twice. You must use unique ID's.
Try this:
In the HTML, give your two light divs each a unique ID, for example lightSmile and lightSad.
In order to be able to use the same CSS for both lightboxes, give both boxes a class lightbox, and in the CSS, change the #light to .lightbox.
Finally, change the lightbox_open() function to the one below here.
HTML
SMILE<br>
<div class="lightbox" id="lightSmile"><img src="http://upload.wikimedia.org/wikipedia/commons/thumb/8/85/Smiley.svg/1024px-Smiley.svg.png" width=100 height=100></div>
SAD
<div class="lightbox" id="lightSad"><img src="http://www.clipartbest.com/cliparts/MiL/kkB/MiLkkBAia.png" width=100 height=100></div>
<div id="fade" onClick="lightbox_close();"></div>
CSS
.lightbox{
display: none;
...
}
JS
function lightbox_open(id){
window.scrollTo(0,0);
document.getElementById(id).style.display='block';
document.getElementById('fade').style.display='block';
}
function lightbox_close(){
document.getElementById('lightSmile').style.display='none';
document.getElementById('lightSad').style.display='none';
document.getElementById('fade').style.display='none';
}
If you look at the HTML, you see that now a string of the lightbox's ID is send along when lightbox_open() is called.
In the function, this ID-string is supplied as a variable (between the brackets: id). And in the line where lightbox's display-style is changed, this id is used.
In the close-function, the display-style of both the lightbox's is set back to default.
UPDATE
If you have a lot of lightboxes, it's easier to access the lightboxes by classname in the close-function:
function lightbox_close(){
var list = document.getElementsByClassName('lightbox');
for (var i=0; i<list.length; i++) {
list[i].style.display = 'none';
}
document.getElementById('fade').style.display='none';
}
And if you're willing to use jQuery, you can do that with one line (and probably more reliably cross-browser):
function lightbox_close(){
$('.lightbox').css('display','none'); //<--------------jQuery
document.getElementById('fade').style.display='none';
}

How to keep one jQuery UI's draggable group above the other?

I have 2 classes of divs to which I apply draggable with the stack option set.
How can I make one of those classes(class "A") float above the other one(class "B"), so that no matter if the object is moved in the B all the elements in A stay above all of the elements in B?
CSS:
div { opacity:0.5; position:absolute; font-size:2em; padding:20px; }
.above { background:green; }
.below { background:red; }
JS:
$("div").draggable({ stack:'div' });
​
HTML:
<div class="above" style="left:30px; top:0px">A1</div>
<div class="above" style="left:60px; top:0px">A2</div>
<div class="above" style="left:90px; top:0px">A3</div>
<div class="below" style="left:30px; top:30px">B1</div>
<div class="below" style="left:60px; top:30px">B2</div>
<div class="below" style="left:90px; top:30px">B3</div>​
Fiddle:
http://jsfiddle.net/4Cje9/2/
Lets take an example:
HTML
<div id="container">
<div id="navi">a</div>
<div id="infoi"><img src="info_icon2.png" height="20" width="32"/>b</div>
</div>
CSS
#container {
width: 100px;
height: 100px;
position: relative;
}
#navi,
#infoi {
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
}
#infoi {
z-index: 10;
}
Add these styles to two respective divs.it'll solve your problem.
I would suggest learning about position: relative and child elements with position: absolute.

Reposition <div> with Javascript

I am trying to reposition a div on the page depending on a certain condition.
if (somecondition)
document.getElementById("Div1").setAttribute("style", "position: absolute; left:297px; top:882px; height: 30px; width: 181px; margin-top: 0px;");
It is not repositioning the div in the html below:
<div id="Div1" style="top:366px; left:134px; position:absolute; height: 30px; width: 175px;">
Other code in the if fires.
Can anyone help?
Browser: IE8
Using setAttribute is unreliable if you want the change to be reflected in the document. Use Element.style instead:
var el = document.getElementById('Div1');
el.style.position = 'absolute';
el.style.left = '397px';
el.style.top = '882px';
el.style.height = '30px';
el.style.width = '181px';
el.style.marginTop = '0px';
You only need to do
document.getElementById("Div1").style.<some css property> = <some value>; // like
document.getElementById("Div1").style.left = "297px";
document.getElementById("Div1").style.top = "882px";
(of course you should cache the getELementById)
To use the CSS as a single string, you should set the Element.style.cssText property:
var element = document.getElementById("Div1");
element.style.cssText = "position: absolute; left:297px; top:882px; height: 30px; " +
"width: 181px; margin-top: 0px;";
Its working perfectly all right, check out the demo here.
HTML:
<div id="Div1" style="top:366px; left:134px; position:absolute; height: 30px; width: 175px;">
hello world
</div>
​
Javascript:
document.getElementById("Div1").setAttribute("style", "position: absolute; left:297px; top:82px; height: 30px; width: 181px; margin-top: 0px;");
​
Make two style classes and add two different positions to the classes. Then change the DIVs class if javascript condition is satisfied. E.g:
if(someCondition) {
document.getElementById('Div1').setAttribute('class', 'style2');
} else {
document.getElementById('Div1').setAttribute('class', 'style1');
}
CSS Styles
.style1 {
top:366px;
left:134px;
position:absolute;
height: 30px;
width: 175px;
}
.style2 {
position: absolute;
left:297px;
top:882px;
height: 30px;
width: 181px;
margin-top: 0px;
HTML
<div id="Div1" class="style1"></div>
try like
document.getElementById("Div1").style.left = "297px";
document.getElementById("Div1").style.top = "882px";
Didn't you put the javascript code in the document.ready(function(){});?

Categories

Resources