After researching:
Changing images on hover
is about the closest found to something that helped me. It didn't help much. I don't have any formal web experience. So, anyone who does, it would be beyond appreciated to a) fix my issue, but b) to actually know why this thing is not shuffling images..
So this is where I'm at in my HTML:
<div class="navBar" id="myNavBar">
<ul id="navOptions">
<li> <img id="logo"
src="images/logo.png"
onmouseover="hoverFunction(this);" ></li>
<li class="active">Home</li>
<li>News</li>
<li>Contact</li>
<li>About</li>
</ul>
</div>
My JavaScript:
function hoverFunction(element) {
var images = ["images/logo.png",
"images/logo_2.png",
"images/logo_3.png",
"images/logo_4.png",
"images/logo.png"];
for(var i=0; i < images.length; i++){
$(element).attr("src",images[i]);
}
//element.setAttribute('src', 'images/logo_2.png');
}
Any advice?
What you appear to want is to, while the <img> is hovered, periodically change the image. Generally, this will be done by starting an interval timer, using setInterval(), when you receive the mouseenter event. The function that would be called each time the interval fires changes to the next image. When you receive the mouseout event, you would then stop the interval timer, using clearInterval().
The following code will cycle through images while the mouse hovers over the <div>:
var images = ["http://cdn.sstatic.net/Sites/stackoverflow/company/img/logos/so/so-icon.png?v=c78bd457575a",
"http://cdn.sstatic.net/Sites/stackoverflow/company/img/logos/se/se-icon.png?v=93426798a1d4",
"http://cdn.sstatic.net/Sites/stackoverflow/company/img/logos/sf/sf-icon.png?v=6c3100d858bb",
"http://cdn.sstatic.net/Sites/stackoverflow/company/img/logos/su/su-icon.png?v=0ad5b7a83e49"
];
var curImageIndex = 0; // 0 is displayed by default
var intervalId; //Remember the ID of the interval so we can stop it later.
function startImageCycle(el){
cycleImage(el); //Cycle the image now so feels responsive. Remove if not wanted.
intervalId = setInterval(cycleImage,1000,el); //Change image every 1000ms (1s)
}
function stopImageCycle(el){
clearInterval(intervalId);
}
function cycleImage(element){
curImageIndex++;
if(curImageIndex >= images.length) {
curImageIndex = 0;
}
$(element).attr("src", images[curImageIndex]);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="navBar" id="myNavBar">
<ul id="navOptions">
<li>
<img id="logo" src="http://cdn.sstatic.net/Sites/stackoverflow/company/img/logos/so/so-icon.png?v=c78bd457575a"
onmouseenter="startImageCycle(this);" onmouseout="stopImageCycle(this);"
</li>
<li class="active">Home
</li>
<li>News
</li>
<li>Contact
</li>
<li>About
</li>
</ul>
</div>
To achieve expected result, use counter
var counter=1;
function hoverFunction(element) {
counter++
var images = ["http://www.w3schools.com/css/img_fjords.jpg",
"http://www.w3schools.com/css/img_forest.jpg",
"http://www.w3schools.com/css/img_lights.jpg",
"http://www.w3schools.com/css/img_fjords.jpg",
"http://www.w3schools.com/css/img_forest.jpg"];
$(element).attr("src",images[counter]);
if(counter ==5){
counter=1;
}
//element.setAttribute('src', 'images/logo_2.png');
}
http://codepen.io/nagasai/pen/jAZogO
option2:updated codepen
http://codepen.io/nagasai/pen/WxYwvK
Related
This question already has answers here:
Getting id of any tag when mouseover
(3 answers)
Closed 4 years ago.
I have few separate elements in my html page right next to each other.
I want to show certain content while mouse is on one of those elements, and hide it when mouse moves away from them.
If I just use mouseon/mouseout events, I get some flickering on content i want to show when i move the mouse between correct elements.
For solution I figured i could create an aray of correct element ID's and then check if mouse is pointing at any of array's elements. But can't find a way to get element's id without clicking it.
So is it possible to get the id of the element mouse is curently hovering or pointing at without jquery or other libraries?
HTML part:
<div id="navigationBarContainer">
<ul id="navigationBarList">
<li>Naujienos</li>
<li id="dropDownBarControl">Veikla
<ul id="dropDownBar" class="hideList">
<li id="preschool" class="hide">Pradine</li>
<li id="middleschool" class="hide">Pagrindine</li>
<li id="highschool" class="hide">Abiturientai</li>
<li id="grownups" class="hide">Suauge</li>
<li id="conferences" class="hide">Konferencijos</li>
<li id="other" class="hide">Teminiai</li>
</ul><!--end of dropDownBar-->
</li>
<li>Kainorastis</li>
<li>Registracija
<ul>
<li id="forStudents" class="hide">Mokiniams</li>
<li id="forGrownups" class="hide">Suaugusiems</li>
</ul><!--end of dropDownBar-->
</li>
<li>Kontaktai</li>
</ul><!--end of navigationBarList-->
</div><!--end of navigationBarContainer-->
and Javascript:
function showItem(name){//make item visable
document.getElementById(name).classList.remove("hide");
}
function hideItem(name){//make item hidden
document.getElementById(name).classList.add("hide");
}
document.getElementById('dropDownBarControl').addEventListener("mouseover", function(){
document.getElementById('dropDownBar').classList.replace("hideList", "showList");
var links = ["preschool","middleschool","highschool","grownups","conferences","other"];
var time = 0;
links.forEach(function(element){
time = time + 20;
setTimeout(function(){
showItem(element);
}, time);
});
});
document.getElementById('dropDownBar').addEventListener("mouseout", function(){
document.getElementById('dropDownBar').classList.replace("showList", "hideList");
var links = ["other","conferences","grownups","highschool","middleschool","preschool"];
var time = 0;
links.forEach(function(element){
time = time + 20;
setTimeout(function(){
hideItem(element);
}, time);
});
});
Listens to mouse move and tracks when the underlying element changes.
uses document.elementAtPoint(x,y);
let element = undefined;
document.addEventListener('mousemove', (event) => {
let x = event.pageX;
let y = event.pageY;
let newElement = document.elementFromPoint(x,y);
if(!element || element !== newElement) {
element = newElement;
console.log(element.id||element);
}
});
<div id="navigationBarContainer">
<ul id="navigationBarList">
<li>Naujienos</li>
<li id="dropDownBarControl">Veikla
<ul id="dropDownBar" class="hideList">
<li id="preschool" class="hide">Pradine</li>
<li id="middleschool" class="hide">Pagrindine</li>
<li id="highschool" class="hide">Abiturientai</li>
<li id="grownups" class="hide">Suauge</li>
<li id="conferences" class="hide">Konferencijos</li>
<li id="other" class="hide">Teminiai</li>
</ul><!--end of dropDownBar-->
</li>
<li>Kainorastis</li>
<li>Registracija
<ul>
<li id="forStudents" class="hide">Mokiniams</li>
<li id="forGrownups" class="hide">Suaugusiems</li>
</ul><!--end of dropDownBar-->
</li>
<li>Kontaktai</li>
</ul><!--end of navigationBarList-->
</div><!--end of navigationBarContainer-->
I have a main menu.
The sub-menu opens when the link of any of the PARENT <li> that have children is clicked.
At this point, a class moves-out is added to the main menu and a CSS transition is started.
After the transition ends, the sub-menu is displayed.
The sub-menu contains the clicked <li> (if clicked again will take us back to the main menu) and it's children.
Here, my goal is to disable the click event on the parent <li> for 1 second,
then after this 1 second give it back the ability to be clicked so we can go back to the main menu.
An example of the navigation would be :
<ul class="main-nav">
<li>Home</li>
<li>Blog</li>
<li>About</li>
<li>Contact</li>
<li>
<span>PARENT</span>
<ul>
<li>Child 1</li>
<li>Child 2</li>
<li>Child 3</li>
And so on...
</ul>
</li>
</ul> <!-- .main-nav -->
The only way that worked for me was to hide/show the PARENT when the main menu has the moves-out class added to it like so :
$('.subnav-trigger').on('click', function(event) {
event.preventDefault();
if ($('.main-nav').hasClass('moves-out')) {
var $this = $(this);
$this.hide();
setTimeout(function(){
$this.show();
}, 1000);
}
}
I've tried A LOT off things, this is the only one that is near to my goal.
Instead off $this.hide(), $this.off('click') is working
but inside the setTimeout what ever I do to regain the click doesn't work.
Any help would be greatly appreciated.
NOTE : I want this to prevent fast click/re-click. Don't forget the transition ;)
Thanks again in advance for any help.
SYA :)
Try setting pointer-events on the li tag and resetting it after 1 second.
$('.subnav-trigger').on('click', function(event) {
event.preventDefault();
var $this = $(this);
$this.parent().css("pointer-events","none");
if ($('.main-nav').hasClass('moves-out')) {
$this.hide();
setTimeout(function(){
$this.show();
$this.parent().css("pointer-events","auto");
}, 1000);
}
});
Here's a way using a recursive function that enabled the click handler, disables it on click, enables the transitionend event, adds your class that enables the transition, then re-enables the function. Enabled a 3s transition to slow it down for the example.
var $lis = $('li'),
clicker = function() {
$lis.on('click', function() {
$lis.off('click');
$(this).on('transitionend', function() {
clicker();
}).addClass('color');
});
}
clicker();
li {
transition: background 3s;
}
li.color {
background: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="main-nav">
<li>Home</li>
<li>Blog</li>
<li>About</li>
<li>Contact</li>
</ul>
More like a debounce problem, you might want to take a look at it if you have not used it before, it will help a lot in design you code.
For the following example, I added moves-out to ul for testing, you can check the console.log to see the result. To use in your app don't forgot to remove it (moves-out) from the <ul...>
<ul class="main-nav moves-out">
function debounce() {
if ($('.main-nav').hasClass('moves-out')) {
console.log("Clicked - click event Disabled..");
$(this).off('click');
setTimeout(function() {
$(".subnav-trigger").on('click', debounce);
console.log("click event enabled!");
}.bind(this), 1000);
}
};
$(".subnav-trigger").on('click', debounce);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<ul class="main-nav moves-out">
<li>Home</li>
<li>Blog</li>
<li>About</li>
<li>Contact</li>
<li>
<span>PARENT</span>
<ul>
<li>Child 1</li>
<li>Child 2</li>
<li>Child 3</li>
And so on...
</ul>
</li>
</ul>
<!-- .main-nav -->
I am really new at javascript but as far as I can tell, the code that I have here should be working. No errors come up when I view in the console(nothing comes up for that matter) and all that appears on the website is the button that doesn't do anything and the list items already appearing on the page
<html>
<body>
<nav>
<ul>
<li>
<button class="accordion">Collections</button>
<ul class="dropDown">
<li><p>Mojica Lookbook</p></li>
<li><p>Andrade Editorial</p></li>
<li><p>Bell Videos</p></li>
</ul>
</li>
<li>
Shop
</li>
<li>
Stores
</li>
<li>
Contact
</li>
<li>
<img src="mojica_lookbook/mojica_credits.png" class="credits">
</li>
</ul>
</nav>
</body>
<script>
var dropDown = document.getElementsByClassName("dropDown");
var i = 0;
for(i = 0; i < dropDown.length; i++) {
dropDown[i].onclick = function(){
this.classList.toggle("active");
this.nextElementSibling.classList.toggle("show");
}
}
</script>
</html>
I believe you will need to use the element passed into the callback for the onclick. Instead of using the 'this' keyword within the callback try this:
for(i = 0; i < dropDown.length; i++) {
dropDown[i].onclick = function(e){
e.target.classList.toggle("active");
e.target.nextElementSibling.classList.toggle("show");
}
}
There are a few examples here. As for the button you have not mapped a click event, so that will as you explain do nothing.
I'm new to javascript and I wanted to create an event onclick to list items. The problem is that I want to create an event to the li tag, but it keeps firing when I click the descendent ul's.
Here goes part of my code:
<li id="1660761" class="HTMLFirstLevel HTMLHorizontalArrowDown">
<ul id="ul1223945" class="HTMLItem">
<li id="1490659" class="HTMLRemainingLevels"></li>
<li id="483463" class="HTMLRemainingLevels"></li>
<li id="80919" class="HTMLRemainingLevels"></li>
<li id="1280053" class="HTMLRemainingLevels"></li>
<li id="1799353" class="HTMLRemainingLevels"></li>
<li id="1882209" class="HTMLRemainingLevels"></li>
<li id="462917" class="HTMLRemainingLevels"></li>
</ul>
</li>
<li id= ......>
<ul....>
<ul...>
</li>
and my javascript:
var parentNode = document.getElementById('1660761');
parentNode.addEventListener("click",function(e) {
alert('Hi There');
});
}
Now I only want it to fire on the item li with the id 1660761, and not the items inside the list.
The list is an imported component and I can't create events inside the html, that's why I'm accessing it outside with javascript.
Now here's how I've done it by scaning the div by tag name and then adding a "click" event listener if the content equals the tag inner html that I was searching for.
I leave the rest of the html that it's important to this aproach:
<div id="MainMenu" class="HTMLMenuContainer HTMLMenuHorizontal">
<ul id="ul1351387" class="HTMLMenu">
<li id="1660761" class="HTMLFirstLevel HTMLHorizontalArrowDown">
<a href="#">
<span>Back Office</span>
</a>
<ul id="ul1172716" class="HTMLItem">
<li id="1490659" class="HTMLRemainingLevels">
<a href="#">
<span>
Some submenu Here
</span>
</a>
</li>
.....
and the code:
var divs = document.getElementsByClassName('HTMLMenuHorizontal');
var span = divs[0].getElementsByTagName('span');
//I iterate till 19 cause its more than all the spans in the page.
for(var i=0; i<20; i++) {
var sp= span[i];
if(sp.innerHTML==('Back Office')){
sp.addEventListener("click",function back(){
//do something here like
alert('Back Office');
});
}
}
This works fine and it doesn't fire on the itens inside.
This works because in my case the itens doesn't change the content, only the visibility.
I do the same for all the other itens that have descendents.
Thank you all.
Below is my jQuery code for this problem:
$(function(){
$("li.1660761").live("click", onListItemLink);
}
function onListItemLink(){
alert('Hello World!');
}
This one is for JavaScript:
var parentNode = document.getElementById('1660761');
parentNode.onclick = onListItemLink;
function onListItemLink(){
alert('Hello World!');
}
take a look at this page to undersand correctly:
capture event
and what's function(e-->??)
I hope it helps.
$('#1660761').unbind('click').click(function(e) {
if (e.target !== this) return;
alert('Hey There!');
});
Try This code : http://jsfiddle.net/sd5LZ/
Two issues I am having.
The mouseover function is very FAST and it's definitely not working properly. I made a separate function for the onmouseout state, but it didnt help.
The class changes properly, however it stays changed and doesn't go back to it's original class. It depends if the link is on the selected page. Any help would be GREATLY appreciated
JAVASCRIPT:
function changeRollover(rollover) {
var rollItems = document.getElementById(rollover);
var rollLinks = rollItems.getElementsByTagName('a');
var noOfLinks = rollLinks.length;
for (var r = 0; r < noOfLinks; r++) {
var normalText = rollLinks[r].innerHTML;
var rolloverText = rollLinks[r].title;
var rolloverItem = document.getElementById(rollover);
rolloverItem.innerHTML = "<a href='#' title='" + normalText + "'>" + rolloverText + "</a>";
rolloverItem.class = rollover + "rollover";
}
}
HTML:
<div class="nav">
<ul id="NavItems">
<li id="item0" class="selected" onClick="changeClass(this.id)"
onmouseover="changeRollover(this.id)">
Collections
</li>
<li id="item1" onClick="changeClass(this.id)"
onmouseover="changeRollover(this.id)">
<a href="#" title="Shop Everything" >All Jewlery</a>
</li>
<li id="item2" onmouseover="changeRollover(this.id)"
onClick="changeClass(this.id)">
As Seen On
</li>
<li id="item3" onmouseover="changeRollover(this.id)"
onClick="changeClass(this.id)">
Collaborations
</li>
<li id="item4" onmouseover="changeRollover(this.id)"
onClick="changeClass(this.id)">
Designer Pop Ups
</li>
</ul>
<div class="shipping">
<a href="#">start your free orders today<br>
*** click here for more information ***</a>
</div>
</div>
<!-- .nav -->
The effect you want (dubious from a usability perspective, but that aside) is better achieved using some simple CSS:
#NavItems .hover {
display: none;
}
#NavItems:hover .hover {
display: inline;
}
#NavItems:hover .normal {
display: none;
}
Which requires markup like this:
<ul id="NavItems">
<li id="item0">
<a href="#">
<span class="normal">Collections</span><span class="hover">Shop Trends</span>
</a>
</li>
</ul>
Depending on your browser compatability requirements, I'd recommend using onmouseenter instead as the trigger for your function.
DOM Events - Browser Compatability
But for one thing, you're missing an onmouseout function that can reset the class for you. Once you attach a class to an element, it has to be removed manually as well if you want it to go away depending on what the user does. So create something like a resetRollover function, like the one below, and attach an onmouseout DOM listener that fires that function:
function resetRollover(rollover) {
var className = document.getElementById(rollover).className;
document.getElementById(rollover).className = className.substring(0, indexOf(' rollover'));
}
The problem is your onmouseover handler is on the lis. When the mouse hovers over the <a>s in the <li> and "reenters" onmouseover of the <li> is triggered again.
Example here: this is the same code as yours, I added some colors. If you move the mouse only on the black part (the <li>), the rollover happens as desired. But when you move the mouse on the green part (the <a>s).
As a solution, you can either handle the rollover on the <a>s or change your basic design (see #Thomas' answer)