Change element-class on click, more elegant solution - javascript

I'm using some of my spare time to learn som basic programming and I've hit kind of a bump.
The following script works, but it's not elegant, at all, and I suspect that It can be solved with far less code.
<div class="naal brukbar" id="naal_1" onclick="writeText(brukbar); byttKlasse_1();"></div>
<div class="naal circus" id="naal_2" onclick="writeText(circus); byttKlasse_2();"></div>
In this case it is a map, with pins located trough CSS-coordinators. The above is the default.
The "problem" if you can call it that, is that i got more than 20 pins, and therfore the pin-class-changing-javascript seems unnecessary long and residual.
JS:
function byttKlasse_1()
{
document.getElementById("naal_1").className = "over brukbar";
document.getElementById("naal_2").className = "naal circus";
document.getElementById("naal_5").className = "naal micro";
document.getElementById("naal_6").className = "naal disko";
document.getElementById("naal_7").className = "naal lundgreen";
document.getElementById("naal_8").className = "naal kos";
document.getElementById("naal_9").className = "naal raus";
document.getElementById("naal_10").className = "naal mormors";
document.getElementById("naal_11").className = "naal samfundet";
}
I need 25 + 1 of these (25 for the pins onclick and one for the reset once the site reloads)
Don't know if it's relevant, but here is the -
CSS:
.naal {
position: relative;
background-image: url('bilder/naal.png');
width:12px;
height:20px;
opacity:1;
}
.over {
position: relative;
background-image: url('bilder/naal_aktiv.png');
width:12px;
height:20px;
opacity:.9;
cursor:pointer;
}
.brukbar {top: -270px; left: 285px;}
.circus {top: -450px; left: 368px;}
Is it possible to "array it up" somehow? I can't just change one class, due to the pins relative location on the map.

something like that? (i tested only in chrome)
js
var current='x';
function smallBoxesHandler(e){
if(current!='x'){
bigBox.childNodes[current].classList.remove('checked');
}
current=Array.prototype.slice.call(e.target.parentNode.childNodes).indexOf(e.target);
bigBox.childNodes[current].classList.add('checked');
}
var bigBox=document.createElement('div');
bigBox.addEventListener('click',smallBoxesHandler,false);
document.body.appendChild(bigBox).innerHTML=new Array(11+1).join('<div></div>');
css
body>div{
width:220px;
border:1px solid rgba(0,0,0,0.5);
overflow:auto;
}
body>div>div{
width:20px;
height:20px;
float:left;
box-sizing:border-box;
}
body>div>div:hover{
border:1px dotted rgba(0,255,0,0.5);
}
body>div>div.checked{
border:1px dotted rgba(0,255,0,0.5);
background-color:red;
}
example
http://jsfiddle.net/bg2Hw/
EDIT
with extra styles....
http://jsfiddle.net/bg2Hw/1/
or
http://jsfiddle.net/bg2Hw/2/ , http://jsfiddle.net/bg2Hw/3/

Related

How to add and remove CSS code from classes with pseudo element?

function toggle(){
var button=document.querySelector('.toggle');
var bar=document.querySelector('.slide');
if(bar.className==='slide up'){
bar.className='slide down';
}else{
bar.className='slide up';
}
}
*{
margin:0px;
padding:0px;
height:100%;
width:100%;
}
.box{
overflow:hidden;
background-image: url('http://tombricker.smugmug.com/Travel/San-Francisco-California/i-jk2Z7D7/0/L/san-francisco-golden-gate-bridge-morning-sun-bricker-L.jpg');
background-size: cover;
background-position:center;
}
.slide{
position: relative;
left:39vw;
width: 55vw;
height: 75vh;
background: red;
}
.slide:before {
content: '';
position:absolute;
top:-3vh;
width: 0px;
height: 0px;
border-left:27.5vw solid transparent;
border-right:27.5vw solid transparent;
border-bottom:3vh solid white;
}
.slide.down{
transform:translateY(100vh);
}
.slide.up{
transform:translateY(25vh);
}
.slide{
transition:transform 0.4s ease-out;
}
<div class='box'>
<div class='slide up' onclick='toggle()'></div>
</div>
The white triangle on top of the red rectangle is made with pseudo element :before. What I am trying to do is when the sliding tag is up, the white triangle should be pointing down. To do that, I want to write a JS code that will add a transform CSS to that class with pseudo element that will translate triangle down by its height and rotate by 180deg.
I find on this developer blog the JS code to add, but it does not work and I don't know how to delete that code when the tag is down.
function toggle(){
var button=document.querySelector('.toggle');
var bar=document.querySelector('.slide');
if(bar.className==='slide up'){
bar.className='slide down';
//Here is where I need to add the line to delete CSS
}else{
bar.className='slide up';
//This is to add CSS
//3vh is the height of that white triangle
document.styleSheets[0].addRule('.slight:before','transform:translateY(3vh) rotateX(180deg)');
}
}
You can add the transformation to the CSS class, and simply toggle it.
CSS
.slide.up:before {
transform: translateY(3vh) rotateX(180deg);
}
JS
var bar = document.querySelector('.slide')
function toggle() {
var cl = bar.classList
cl.toggle('down', cl.contains('up'))
cl.toggle('up', !cl.contains('down'))
}
JSFiddle demo: https://jsfiddle.net/htq8ouyn/2/
Resources
Element.classList - Web APIs | MDN

How to "dim" certain area in a webpage

I have a page which i need to dim a certain area (div) instead of the entire page. How can I achieve this?
I have googled some answer but all of them is about dimming the whole page. Below is the sample code that I got but it dimmed the entire page.
<div id="dimmer"></div>
#dimmer
{
background:#000;
opacity:0.5;
position:fixed; /* important to use fixed, not absolute */
top:0;
left:0;
width:100%;
height:100%;
display:none;
z-index:9999; /* may not be necessary */
}
It covered the whole page because you set the width and height to 100%. If you were to make it 100px or 50%, that would work, but if you set it to 100%, it will cover 100% of the page.
.area-to-dim {
position: relative;
}
.dimmer {
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
background-color: rgba(0,0,0,0.5);
}
HTML
<div class="area-to-dim">
<div class="dimmer"></div>
</div>
Two ways, one really simple but I'm not 100% sure this is what you wanted.
First way, use CSS
.genericClassGivenToDivs, #idOfDiv {
background:#fff;
}
/* on mouse over, change the background colour */
.genericClassGivenToDivs:hover, #idOfDiv:hover {
background:#aaa;
}
The second way is more complex. Basically, reposition a div using javascript on mouse over. This requires some CSS and javascript. The following could be a lot cleaner with some work.
<html>
<head>
<style>
body {
margin:1em;
background:#ddd;
}
#contain {
margin:auto;
width:100%;
max-width:720px;
text-align:center;
}
#row1, #row2, #row3 {
width:100%;
height:48px;
line-height:48px;
color:#000;
background:#fff;
}
#row2 {
background:#eee;
}
#dim {
position:absolute;
top:0px;
left:0px;
width:100%;
height:100%;
background:rgba(0,0,0,0.5);
display:none;
}
</style>
</head>
<body>
<div id="contain">
<div id="row1">Row 1</div>
<div id="row2">Row 2</div>
<div id="row3">Row 3</div>
</div>
<div id="dim"></div>
<script>
var dimEl = document.getElementById('dim');
function over() {
//console.log('over:['+ this.id +']');
dimEl.style.top = this.offsetTop +'px';
dimEl.style.left = this.offsetLeft +'px';
dimEl.style.height = this.offsetHeight +'px';
dimEl.style.width = this.offsetWidth +'px';
dimEl.style.display = 'block';
}
window.onload = function() {
var list = ['row1', 'row2', 'row3'];
var e;
for(x in list) {
e = document.getElementById(list[x]);
if (e) {
e.onmouseover = over;
}
}
}
</script>
</body>
</html>
Not entirely sure what "dimming a certain area" means, but I recently created a solution that might be applicable in some extent.
I had a div with a background image and some overlaid text, and the background (but not the text) should darken slightly on mouse over.
I solved it by having two containers and a textfield, so that the outermost div had the background image, the inner div expanded to 100% height and width and had a transparent black solid-color background, and then there was some text in that div.
Then, simply, on hover, I change the inner div background-color from rgba(0, 0, 0, 0) to rgba(0, 0, 0, .3), dimming the background image.
If this sounds applicable, see this jsFiddle
Why the display is none?
Check this?
#dimmer {
background: #111;
top: 0;
left: 0;
width: 100px;
height: 100px;
z-index: 9999;
/* may not be necessary */
}
#dimmer:hover {
background: #000;
opacity: 0.5;
transition: opacity 1s ease;
cursor: pointer;
}
<div id="dimmer">ok</div>

Make an image transparent and fill with color relative to a percentage value

I found the following on codepen and really liked this effect. Now I'm trying to adapt this to my needs and ran into some problems:
Whenever a user scrolls down or is resizing his screen, the image is behaving weird (I can't describe it in my own words, see jsfiddle for what I mean).
I guess this problem might relate to the 'background-attachment: fixed' property.
See:
.image {
width:100%;
height:100%;
position:absolute;
bottom:0;
background:url("http://lorempixel.com/400/200/") fixed top center no-repeat;
background-clip:content-box;
opacity: 0.4;
filter: alpha(opacity=40);
}
.show {
width:100%;
height:100%;
position:absolute;
bottom:0;
background:url("http://lorempixel.com/400/200/") fixed top center no-repeat;
background-clip:content-box;
}
I tried to experiment with both, the position of the div and the background-attachment property, but I didn't get a decent result. You can see my updated fiddles for that (Rev.: 2-4).
Does one of you have an idea of how I can use this effect without the shown weird behaviours?
Maybe there's some jQuery magic with whose help I can achieve this effect?
It would be best if the solution also supports the IE 8, but it's not a must at this point, as I only want to understand what I did wrong.
Thanks in advance.
The problem is that author used fixed background attachment, without it the script is more complex.
If I get it right you want to control the position by clicking the buttons.
I created a snippet that will give you a good starting point: JSnippet
As you can see things are more complex there but it does not uses fixed background and allows you to easily update the "loading" to any point you want, I have not tested it but it should work on most of the browsers and even older once.
You can set all you need using attributes:
data-loader-size -> sets the size.
data-back-image -> sets the back image.
data-front-image -> sets the front image.
data-update-to -> For the controls set the percentage you want.
The CSS:
div.loader {
position:relative;
background-repeat:no-repeat;
background-attachment: scroll;
background-clip:content-box;
background-position:0 0;
margin:0;
padding:0;
}
div.loader .loaded {
position:absolute;
top:0;
left:0;
background-repeat:no-repeat;
background-attachment: scroll;
background-clip:content-box;
background-position:0 0;
margin:0;
padding:0;
}
div.loader .position {
position:absolute;
left:0;
border-top:1px dashed black;
width: 100%;
text-align:center;
margin:0;
padding:0;
min-height: 40px;
}
div.loader .position div {
font-family: 'Concert One';
background:#2f574b;
width: 25%;
margin:0;
padding:5px;
margin: 0 auto;
text-align:center;
border-radius: 0 0 4px 4px;
border-bottom: 1px solid black;
border-left: 1px solid black;
border-right: 1px solid black;
color:white;
}
The HTML:
<div class="loader"
data-loader-size="450px 330px"
data-back-image="http://fdfranklin.com/usf-bull-bw.png"
data-front-image="http://fdfranklin.com/usf-bull.png"
>
<div class="loaded"></div>
<div class="position"><div>0%</div></div>
</div>
<br><br>
<div>
<button class="set-loader" data-update-to="0">Set 0%</button>
<button class="set-loader" data-update-to="25">Set 25%</button>
<button class="set-loader" data-update-to="50">Set 50%</button>
<button class="set-loader" data-update-to="100">Set 100%</button>
</div>
The jQuery:
$(function() {
var loader_class = ".loader",
control_class= ".set-loader";
var oLoader = {
interval : 10,
timer : null,
upPerc : 0,
upHeight : 0,
curHeight : 0,
step : 1,
diff_bg : 0,
diff_top : 0,
size : $(loader_class).data("loader-size").split(" "),
heightInt : 0,
bimage : $(loader_class).data("back-image"),
fimage : $(loader_class).data("front-image"),
loader : $(loader_class).children('.loaded').eq(0),
position : $(loader_class).children('.position').eq(0),
pos_height : 0
};
oLoader.heightInt = parseInt(oLoader.size[1],10);
oLoader.pos_height = parseInt($(oLoader.position).height(),10);
$(loader_class).css({
width: oLoader.size[0],
height: oLoader.size[1],
'background-image':'url(' + oLoader.fimage + ')',
'background-size':oLoader.size.join(' ')
});
$(oLoader.loader).css({
width: oLoader.size[0],
height: oLoader.size[1],
'background-image':'url(' + oLoader.bimage + ')',
'background-size':oLoader.size.join(' ')
});
$(oLoader.position).css({
bottom: 0 - oLoader.pos_height
});
$(control_class).each(function(){
$(this).click(function(){
clearInterval(oLoader.timer);
oLoader.upPerc = parseInt($(this).data('update-to'));
oLoader.upHeight = Math.ceil((oLoader.upPerc/100)*oLoader.heightInt);
oLoader.upHeight = (oLoader.upHeight>oLoader.heightInt?oLoader.heightInt:oLoader.upHeight);
oLoader.curHeight = parseInt($(oLoader.loader).height(),10);
oLoader.step = (oLoader.upHeight>(oLoader.heightInt - oLoader.curHeight)?-1:1);
oLoader.diff_bg = (oLoader.step === 1?
(oLoader.heightInt - oLoader.curHeight) - oLoader.upHeight:
oLoader.upHeight - (oLoader.heightInt - oLoader.curHeight));
oLoader.diff_top = parseInt($(oLoader.position).css('bottom'),10);
oLoader.timer = setInterval(function () {
if (oLoader.diff_bg) {
oLoader.diff_bg--;
oLoader.curHeight += oLoader.step;
oLoader.diff_top += -oLoader.step;
oLoader.calc_perc = Math.ceil((oLoader.diff_top + oLoader.pos_height) / oLoader.heightInt * 100);
oLoader.calc_perc = (oLoader.calc_perc < 0?0:oLoader.calc_perc);
oLoader.calc_perc = (oLoader.calc_perc > 100?100:oLoader.calc_perc);
$(oLoader.loader).css({ height: oLoader.curHeight });
$(oLoader.position).css({ bottom: oLoader.diff_top });
$(oLoader.position).children('div').text(oLoader.calc_perc + "%");
} else {
clearInterval(oLoader.timer);
$(oLoader.position).children('div').text(oLoader.upPerc + "%");
}
}, oLoader.interval);
});
});
});

Tumblr posts cycling between two different colors

I would like to make it so that the container around a particular post is a different color than the one adjacent to it. Basically, the the containers just need to cycle between two different colors.
Left side is how it currently looks, right is how I want it to look. Thanks!
CSS
#content {
float:left;
width:800px;
padding:25px;
top:-50px; left:45px;
background:transparent;
{block:PermalinkPage}
width:300px;
{/block:PermalinkPage}
}
.entry {
width:150px;
margin:50px;
overflow:hidden;
background:#336136;
margin-left:-12px;
margin-bottom: -10px;
padding:12px;
{block:PermalinkPage}
width:250px;
margin-left:40px;
{/block:PermalinkPage}
}
.entry:nth-child(odd) {
background: #000;
}
HTML
<div id="content">
{block:Posts}
<div class="entry">
{miscellaneous_blocks_here}
</div>
{/block:Posts}
</div>
Why not use CSS3 selectors and forgo the javascript dance?
.entry:nth-child(odd) {
background: #000;
}
.entry:nth-child(even) {
background: #ff003d
}
Browser support: http://caniuse.com/css-sel3
A good idea would be to use classes and ids. For each class that you want this feature you can increment your id by one:
$('.your_class_for_each_item').each(function(){
i++;
var newID='your_id'+i;
$(this).attr('id',newID);
$(this).val(i);
});
This will result in newID1, newID2 etc. Then for odd ids use a color and for even ids another color. You use a function like this:
function(){
if(i%2==0){ //check if the number is odd
var z = document.getElementById('newID');
z.setAttribute('style','background:color_for_even_numbers');
}
else{
z.setAttribute('style','background:color_for_odd_numbers');
}
}

how to set the absolute position div center align

I want to show the text text masking effect with animation
Here is my fiddle for what I am trying to achieve: http://jsfiddle.net/qTWTH/2/
I am not able to position the Red text in "center" above theblack text so the efffect should be something like this: http://jsfiddle.net/qTWTH/1/ *BUT aligned Center*
Also how to repeat the animation, this as per the JS, it just animate only once, I want to repeat the JS once the effect is done.
Code: HTML
<div id="mainbox">
<span id="black">Waiting for the task!</span>
<span id="red">Waiting for the task!</span>
</div>
CSS
#mainbox {
width:600px;
text-align:center;
}
#black {
color:black;
font-weight:bold;
font-size:2em;
}
#red {
position:absolute;
z-index:10;
left:8px;
width:0px;
overflow:hidden;
font-weight:bold;
font-size:2em;
color:red;
white-space:nowrap;
}
JS
var red = document.getElementById('red');
var black = document.getElementById('black');
red.style.width = "0px";
var animation = setInterval(function () {
console.log(red.style.width);
if (red.style.width == "290px") clearInterval(animation);
red.style.width = parseInt(red.style.width, 10) + 1 + "px";
}, 50);
Let me know if you need any other information.
Please suggest.
Check this fiddle
By centering the div itself, and positioning the red according to that, you'll ensure they line up.
#mainbox {
display: inline-block;
position: relative;
}
html {
text-align: center;
}
#red {
left: 0;
}
To run it again and again change like this:
var red = document.getElementById('red');
var black = document.getElementById('black');
red.style.width = "0px";
var animation = setInterval(function(){
console.log(red.style.width);
if(red.style.width == "290px")
{
red.style.width = "0px"; // here i have changed
}
red.style.width = parseInt(red.style.width,10)+1 +"px";},50);
Correct fiddle: http://jsfiddle.net/arjun_chaudhary/qTWTH/22/
I altered your code slightly, you almost had it
http://codepen.io/nighrage/pen/EAmeF/
<div id="mainbox">
<span id="black">Waiting for the task!</span>
<div id="red">Waiting for the task!</div>
</div>
#red {
z-index:10;
left:8px;
width:0px;
overflow:hidden;
font-weight:bold;
font-size:2em;
color:red;
white-space:nowrap;
margin: 0 auto;
margin-top: -37px;
}
change the second span for a div

Categories

Resources