I'm relatively new to JavaScript, but I'm trying to find a more efficient method for calling a rollover function without using inline events within the HTML. Below is the method I'm currently using:
HTML
<div id="work_square">
<img onmouseover="rolloverIn('rollover_1');" onmouseout="rolloverOut('rollover_1');" src="images/frugal_image.png" width="100%"/>
<div onmouseover="rolloverIn('rollover_1');" onmouseout="rolloverOut('rollover_1');" id="rollover_1" class="rollovers">
<div id="rollover_text">
<h2>ROLLOVER 1 TITLE</h2>
<p>This is rollover 1.</p>
</div>
</div>
</div>
<div id="work_square">
<img onmouseover="rolloverIn('rollover_2');" onmouseout="rolloverOut('rollover_2');" src="images/exhibiton_image.jpg" width="100%"/>
<div onmouseover="rolloverIn('rollover_2');" onmouseout="rolloverOut('rollover_2');" id="rollover_2" class="rollovers">
<div id="rollover_text">
<h2>ROLLOVER 2 TITLE</h2>
<p>This is rollover 2.</p>
</div>
</div>
</div>
JS
<script>
function rolloverIn(el){
var elem = document.getElementById(el);
elem.style.opacity = 1;
elem.style.transform = "scale(1)";
}
function rolloverOut(el){
var elem = document.getElementById(el);
elem.style.opacity = 0;
elem.style.transform = "scale(0)";
}
Basically I'm calling a function to apply a CSS transform and opacity alteration for a rollover placed over each work_square when either the image or rollover is moused over, and then to remove the alterations on mouse out.
This method works, but it's my understanding that inline coding is bad practice. Could someone point me in the right direction towards a more efficient method?
Thanks.
Sorry to ruin your dream of using JS but
this is all doable in pure CSS:
.work_square{ position:relative; }
.work_square > img{ width:100%; }
.work_square .rollovers{
position:absolute;
top:0;
opacity:0;
transform: scale(0);
transition: 0.6s;
}
.work_square:hover .rollovers{
transform: scale(1);
opacity:1;
}
<div class="work_square">
<img src="//placehold.it/800x300/cf5" />
<div class="rollovers">
<div class="rollover_text">
<h2>ROLLOVER 1 TITLE</h2>
<p>This is rollover 1.</p>
</div>
</div>
</div>
<div class="work_square">
<img src="//placehold.it/800x300/f5f" />
<div class="rollovers">
<div class="rollover_text">
<h2>ROLLOVER 2 TITLE</h2>
<p>This is rollover 2.</p>
</div>
</div>
</div>
Note that I've removed all unnecessary ID (hey, you cannot use duplicate ID's in a valid HTML document).
Use your container class .work_square and use the CSS :hover on it to add that listener, than simply add the desired class of the children element to target:
.work_square:hover .rollovers{
First of all, do not ever use the same ID for multiple elements, IDs are unique. What you want here are classes, so your HTML code should be changed to something like this:
<div class="work_square">
<img class="rollover" src="images/frugal_image.png" width="100%"/>
<div class="rollover">
<div class="rollover_text">
<h2>ROLLOVER 1 TITLE</h2>
<p>This is rollover 1.</p>
</div>
</div>
</div>
<div class="work_square">
<img class="rollover" src="images/exhibiton_image.jpg" width="100%"/>
<div class="rollover">
<div class="rollover_text">
<h2>ROLLOVER 2 TITLE</h2>
<p>This is rollover 2.</p>
</div>
</div>
</div>
Now, if you want to use pure JavaScript, without inline code, you can easily use the rollover class to select all the elements and bind the mouseover and mouseout events to your functions. Here is the correct code:
function rolloverIn(e){
this.style.opacity = 1;
this.style.transform = "scale(1)";
}
function rolloverOut(e){
this.style.opacity = 0;
this.style.transform = "scale(0)";
}
var elements = document.getElementsByClassName('rollover');
for (var i=0; i < elements.length; i++) {
elements[i].addEventListener('mouseover', rolloverIn);
elements[i].addEventListener('mouseout', rolloverOut);
}
Related
I have a code like this in my html:
<div ng-mouseover="show_up()" ng-mouseleave="dont_show_up()" class="contain">
<img src="image/first_image.jpg">
<div class="overlay" ng-style="overlay">
show songs
</div>
</div>
<div ng-mouseover="show_up()" ng-mouseleave="dont_show_up()" class="contain">
<img src="image/second_image.jpg">
<div class="overlay" ng-style="overlay">
show songs
</div>
</div>
and this is my js code :
$scope.show_up = function () {
$scope.overlay={
"height":"100%"
};
};
$scope.dont_show_up = function () {
$scope.overlay={
"height":"0"
};
}
this is what I need to happen: whenever I hover on my first image it should add the style "height:100%"
to my first image, not both of them!
and when I hover on my second image it should add the style "height:100%"
to my second image, not both of them!
how can I fix this problem?
One solution would be passing some value to show_up() and dont_show_up() function, which identifies an image, say 1, 2 and then, inside function, change overlay variable to array and update appropriate item. ng-style="overlay" must be also changed to ng-style="overlays[0]"
--Edit
<div ng-mouseover="show_up(0)" ng-mouseleave="dont_show_up(0)" class="contain">
<img src="image/first_image.jpg">
<div class="overlay" ng-style="overlays[0]">
show songs
</div>
</div>
<div ng-mouseover="show_up(1)" ng-mouseleave="dont_show_up(1)" class="contain">
<img src="image/second_image.jpg">
<div class="overlay" ng-style="overlays[1]">
show songs
</div>
</div>
$scope.show_up = function (index) {
$scope.overlays[index] = {
"height":"100%"
};
};
$scope.dont_show_up = function (index) {
$scope.overlays[index] = {
"height":"0"
};
}
Well that becomes difficult to maintain when number of images increase
Second solution.
You can store all images as an array of objects and apply ng-repeat directive to loop through them.
<div ng-repeat="image in images" ng-mouseover="show_up(image.id)" ng-mouseleave="dont_show_up(image.id)" class="contain">
<img ng-src="image.src">
<div class="overlay" ng-style="image.overlay">
show songs
</div>
</div>
$scope.show_up = function (id) {
$scope.images.find(image => image.id === id).overlay = {
"height":"100%"
};
};
$scope.dont_show_up = function (id) {
$scope.images.find(image => image.id === id).overlay = {
"height":"0"
};
}
Not sure what you are trying to achieve since you state you want the image to change from 0 - 100% on the mouseover - but the ng-style is applied to the overlay. I assume you are trying to overlay the text over the image?
Anyway you don't need angular or even javascript for this - just CSS and apply a :hover on the parent level and style on the child element and you can achieve the desired outcome without the cost of the js.
.overlay {
height: 0;
overflow: hidden
}
.contain:hover .overlay {
height: 100%;
}
<div class="contain">
<img src="https://i.pinimg.com/originals/3e/6b/cd/3e6bcdc46881f5355163f9783c44a985.jpg" height="150">
<div class="overlay">
show songs
</div>
</div>
<div class="contain">
<img src="https://images-na.ssl-images-amazon.com/images/I/61W2FTW9ePL._AC_SL1500_.jpg" height="150">
<div class="overlay">
show songs
</div>
</div>
I'm working on an interactive website assignment, and I'm using video's for some parts. I managed to change the background-video src when a particular element is clicked, but the transition is very abrupt. I want it to be smooth and fade out.
I tried adding transition: all .3s ease-in-out; to the video css class, but that didn't work.
My current code:
JS
const handleClickItem = e => {
const $video = document.querySelector('.omgeving_vid');
const activeItem = e.currentTarget;
console.log(activeItem);
updateGroup(activeItem); //for changing opacity of elements, not relevant
console.log(activeItem.dataset.omgeving);
if (activeItem.dataset.omgeving === 'sneeuw') {
$video.setAttribute('src', './assets/longread/new_snowstorm.mp4');
} else if (activeItem.dataset.omgeving === 'regen') {
$video.setAttribute('src', './assets/longread/new_rainfall.mp4');
}
};
HTML
<video class="omgeving_vid" src="./assets/longread/new_snowstorm.mp4" autoplay loop muted></video>
<div class="omgeving-options">
<div data-omgeving="assen" class="omgeving--option assen">
<img src="./assets/longread/ash_icon.png" alt="ash">
<p class="omgeving-options--title">Assen</p>
</div>
<div data-omgeving="sneeuw" class="omgeving--option sneeuw">
<img src="./assets/longread/snow_icon.png" alt="snow">
<p class="omgeving-options--title">Sneeuw</p>
</div>
<div data-omgeving="regen" class="omgeving--option regen">
<img src="./assets/longread/rain_icon.png" alt="rain">
<p class="omgeving-options--title">Regen</p>
</div>
</div>
I am new to JavaScript and currently trying to create a page that:
1) is constantly cycling each div within an interval of time.
2) only the selected div would have the class "selected" in it.
3) the selected class's data-url is placed in src of the iframe below the divs.
This is my sample html.
<div class="content selected" data-url="">
Website 1
</div>
<div class="content" data-url="">
Website 2
</div>
<div class="content" data-url="">
Website 3
</div>
<div class="content" data-url="">
Website 4
</div>
<iframe id="iframe-container" src="" />
It seems most of the solutions on cycles is for hiding and showing divs. Is there a way to use the cycle function and add more codes to make it do what I want?
var sites = document.querySelectorAll('[data-url]');
var frame = document.querySelector('iframe');
var index = 0;
function moveAlong() {
sites.item(index).classList.remove("selected");
index++;
if (index >= sites.length) index = 0;
sites.item(index).classList.add("selected");
frame.src = sites.item(index).dataset.url;
}
setInterval(moveAlong, 3000);
body {
font-family: sans-serif;
}
.selected {
color: red;
}
iframe {
border: none;
}
<div class="selected" data-url="http://example.com">
Website 1
</div>
<div data-url="http://www.w3schools.com">
Website 2
</div>
<div data-url="http://wikipedia.org">
Website 3
</div>
<iframe src="http://example.com"></iframe>
I have made a simple code snippet to swap two divs using two separate buttons via javascript. Here is the code:
function SwapDivsWithClick2(div1, div2) {
d1 = document.getElementById(div1);
d2 = document.getElementById(div2);
d1.style.display = "block";
d2.style.display = "none";
}
.button1 {
content: url("http://placehold.it/250x50/000000/FFFF00?text=CLICK+FOR+DIV1");
}
.button2 {
content: url("http://placehold.it/250x50/000000/FFFF00?text=CLICK+FOR+DIV2");
}
<body>
<div class="buttons">
<span><a href="javascript:SwapDivsWithClick2('div1','div2')"><img class="button1 fade"/></span>
<span><a href="javascript:SwapDivsWithClick2('div2','div1')"><img class="button2 fade"/></span>
</div>
<div id="div1" style="display: block;">
<img src="http://placehold.it/500x300/FF0000/FFFFFF?text=div1" />
</div>
<div id="div2" style="display: none;">
<img src="http://placehold.it/500x300/0000FF/FFFFFF?text=div2" />
</div>
</body>
Codepen link to the above code: http://codepen.io/misteeque/pen/qNZJLj
In the above, how can I add a transition effect like "fade" or something else when the div's are swapped? If not possible via display: none, is there any other way to achieve the transition effect?
Thank you!
I made a JQuery carousel from scratch, so far the code is good and it works quite nice.
The main issue is when I try and use the fadeOut function alongside the fadeIn function, the images stack on top of each other.
I cant figure out how to make them overlap.
I tried to play around with absolute positioning but had no luck.
You can clearly see it when you go on my website http://techyhesh.com/Dogs/
html
<div class="carousel">
<div id="background-slideshow">
<div style="display: none;" id="img1" class="slides">
<img src="/2015/03/Carosuel2.png">
<div class="textblock">
<p class="carousel-text1">Slider 1</p>
<p class="carousel-text2">His nose gets into everything</p>
</div>
</div>
<div style="display: block;" id="img2" class="slides">
<img src="/2015/03/Carosuel.png">
<div class="textblock">
<p class="carousel-text1">Slider 2</p>
<p class="carousel-text2">His nose gets into everything</p>
</div>
</div>
<div style="display:none;" class="SlideJSON">2</div>
</div>
</div>
JS
jQuery(document).ready(function($) {
var slides= $(".JSONNumber").html();
var slides= parseInt(slides);
var animateInterval;
var i = 1;
var x = 2;
function animate() {
$("#img" + i).fadeOut(2000)
$("#img" + x).fadeIn(2000);
if (i == slidenumber) {
$("#img1").fadeIn(2000);
i = 1;
x = 2;
} else {
i++;
x++;
}
}
animateInterval = setInterval(animate, 3000);
})
As per your HTML, The selector you've used is wrong.
$("#img" + i)
It should be
$("#slideimg" + i)
in your slides css, just add display: inline-block;