I have got 1 area, and on mouseenter I am fading in the following div:
$( "area.hasmore" ).mouseenter(function() {
$(this).next(".popup").stop().fadeIn();
});
Let's say the popup appears on the right hand side. What if the user leaves the area on the left hand side? Let's fade that popup out:
$( "area.hasmore, .popup" ).mouseleave(function() {
$(".popup").fadeOut();
});
Here comes my problem: users should be able to move the cursor into the fresh opened popup to the right and maybe even click a link in there. My problem is that it fades out due to the mouseleave event on the area. One problem might be the fact that the popup is no child. As a child of the area hovering the popup would still count as being 'inside' the area I guess. So I am kind of trying to find out how to keep the popup visible when mouseentering it and mouseleaving the area.
Here's the code:
<area class="hasmore" />
<div class="popup">...
Sry if I missed a question where this exact problem is being discussed.
jsfiddle here: fiddle
You could manage what is visible in the hover instead of mouseenter and mouseleave:
Something like this:
$('div').hover(function () {
console.log(this.className);
if (this.className === 'hasmore') {
$(this).next(".popup").stop().fadeIn();
} else if (this.className !== 'hasmore' && this.className !== 'popup') {
$(".popup").fadeOut();
}
});
Here is a fiddle demonstrating
html
<div class="hasmore">hover me</div>
<div class="popup">Popup 1</div>
<div class="evenmore">stuff</div>
<div class="popup">2nd popup. don't mind me</div>
Javascript
$( ".container" ).mouseenter(function() {
$(".popup").stop().fadeIn();
});
$( "div.container" ).mouseleave(function() {
$(".popup").fadeOut();
});
CSS (include this)
.container {
display: block;
line-height: 1em;
margin: 0;
padding: 0;
}
The trick is to create a div (.container) with display: block and enclosure .hasmore and .popup inside it!
Related
Well, i am stucked and can't find the answer myself. Hopefully someone can give me a hint.
I try to fullfill the following requirements:
There should be a Newsblock within a HTML Page with a fixed width and
height.
In this Newsblock only the title of the news are visible.
Those news are "collapsed" by default and should "expand" if the Mouse is over it.
Due the fact that the 'Newsblock' is limited by its height, there should be a Scrollbar visible. But only if the currently expanded news makes it necessary, so the user can Scroll down.
Newstitle and Newstext should never leave the Newsblock.
so far so good, i was able to fullfill all those demands except the one with the Scrollbar. If i try to reach the Scrollbar out of the currently expanded news it collapses again and the Scrollbar disappears. I understand that my .hover is configured that it always SlideUp if i leave the newsentry and the Scrollbar isn't a part of the newsentry div. But i have no idea what to change to still have an overall Scrollbar for the Newsblock, but won't disappear if i try to 'reach' it.
P.s.: A Scrollbar only per Newsentry looks weird. Thats why i want 'bind' the scrollbar to the parent container :S
HTML
<div id="newsblock">
<div> // some auto generated div's i have to life with, so the news entries are not 'direct' children of the newsblock.
<div class="newsentry">
<div class="newstitle">...</div>
<div class="newstext">...</div>
</div>
... another 9 'newsentry' divs.
</div>
</div>
JS
$(".newsentry").hover(
function() {
$(this).children(".newstext").stop(true,true).slideDown();
},
function() {
$(this).children(".newstext").stop(true,true).slideUp();
}
);
CSS
.newsblock {
height: 200px;
overflow-y: auto;
}
Instead of closing a .newsentry when the cursor goes out of it, a solution can be to close it only when it enters another .newsentry or when it leaves #newsblock.
The scrollbar being part of #newsblock, the entry isn't closed anymore when you go on it.
EDIT: Following our discussion about the scroll issue, I added a step callback to the closing animation to make sure that the top of the .newsentry getting opened remains visible when the other entries are getting closed.
Here is a working example:
var $newsblock = $("#newsblock");
function closeAllNews(slideUpArgs){
return $(".newstext").stop(true).slideUp(slideUpArgs);
}
function openNews(news, slideDownArgs){
$(news).find(".newstext").stop(true).slideDown(slideDownArgs);
}
function ensureNewsTopVisible(news){
// Check if the top of the newsentry is visible...
var top = $(news).position().top;
if(top < 0){
// ...and if not, scroll newsblock accordingly.
$newsblock.scrollTop($newsblock.scrollTop() + top);
}
}
$(".newsentry").each(function(){
var $this = $(this);
// When the mouse enter a news entry...
$this.on("mouseenter", function(){
// ...close all opened entries (normally there is at most one)...
closeAllNews({
// (while making sure that the top of this entry remains visible
// at each step)
step: ensureNewsTopVisible.bind(null, $this)
});
// ...open this newsentry.
openNews($this);
});
});
// When the mouse get out of the newsblock, close all news.
$newsblock.on("mouseleave", closeAllNews);
.newstitle {
font-size: 2em;
}
.newstext {
display: none;
}
#newsblock {
max-height: 150px;
overflow: scroll;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="newsblock">
<div>
<div class="newsentry">
<div class="newstitle">News 1</div>
<div class="newstext"></div>
</div>
<div class="newsentry">
<div class="newstitle">News 2</div>
<div class="newstext"></div>
</div>
<div class="newsentry">
<div class="newstitle">News 3</div>
<div class="newstext"></div>
</div>
<!-- Etc. -->
</div>
</div>
<!-- Ignore the script below. It is just filling in the news' text. -->
<script>
$(".newstext").each(function(i, newstext){
$.get("http://baconipsum.com/api/?type=meat-and-filler&format=html¶s=5&num=" + i)
.then(function(ipsumHtml){
$(newstext).html(ipsumHtml);
});
});
</script>
Try this:
$(".newsentry, .newsblock").hover( // <-- changed
function() {
$(this).children(".newstext").stop(true,true).slideDown();
},
function() {
$(this).children(".newstext").stop(true,true).slideUp();
}
);
This makes sure the block stays open when you hover either over the header or the block itself.
Is that what you mean?
There would be a joke , if i am wrong .. what i thing just change your css as
/* not .newsblock **/
#newsblock {
height: 200px;
overflow-y: scroll;/* not auto*/
}
It will be a lot better if you use click operation instead of hover to slide down news text block because the user can accidentally hover over any of the news entry in order to reach for the scroll bar. I think you need a accordion like functionality. You can use the below code if you are fine with click instead of hover.
$(".newsentry").click(
function() {
$(".newstext").stop(true,true).slideUp();
$(this).children(".newstext").stop(true,true).slideDown();
}
);
Or use the below one to go with hover.
$(".newsentry").hover(
function() {
$(".newstext").stop(true,true).slideUp();
$(this).children(".newstext").stop(true,true).slideDown();
},
function(){}
);
This will not close the news text block until you accidentally hover over another news entry.
I am making a personal website. I want to make it so that cliking the background changes the theme from dark to light and vice/versa. It works, but I dont want it to switch the theme if the user clicks on text, only the background of the webpage For example, if I click the text at the bottom it changes the css, but it should only do that if you click the white background.
Here is my code (Mainly checkout js/main.js, the switchTheme function and the index.html) and the website itself.
You are targeting your container class. Anytime that div (or anything in it) gets clicked, that event will fire. Try stopping the event propagation on your click event if $('this').selector === 'p' or whatever class you're using.
Also - not bad for 13 boss!
$( document ).click(function( event ) {
// if statement here
event.stopPropagation();
// else the regular behavior
});
Thanks everyone for your help! I'd almost given up and wanted to use a button to toggle it instead. The more you know!
And since this is an answer to my question: e.stopPropogation()
You can also do something like this:
document.querySelector('div').addEventListener('click', (e) => console.log("Heeeeyyy! Hoooo!"))
<div style="position: fixed; background-color: lightcoral; width: 500px; height: 180px;">
</div>
<div style="position: fixed; background-color: lightblue; width: 300px; height: 100px;">
<p>You can not click through me!</p>
</div>
Don't put the elements inside the "parent".
Move them together only by style.
How about
$("#container").on("click", "div", function(event){
event.stopPropagation();
switchTheme();
});
Add a test to see if the ID of the clicked element was actually the container.
function switchTheme( event ) {
if ( event.target.id === 'container' ) { //the container was clicked, and not a text node
if (dark) {
$("#container").css("background-color", "rgba(255,255,255,0.7);");
$("#container").css("color", "black");
dark = false;
} else {
$("#container").css("background-color", "rgba(0,0,0,0.7);");
$("#container").css("color", "white");
dark = true;
}
}
}
Try setting the following:
$("#container").on("click", "div", function(e){
e.stopPropagation();
});
How to add and remove class with the condition of CSS display. For example, I have some Div that can be hidden and shown. I want that, if the div is hidden with the display:none;, then the class of the div is removed.
But if the div is shown with the display:block;, I want to add a class to the div.
Here is what I have been trying:
$(document).ready(function(){
if($('.bigPicture').css('display') == 'block')
{$('.bigPicture').find('div').addClass('easyzoom easyzoom--overlay');};
if($('.bigPicture').css('display') == 'none')
{$('.bigPicture').find('div').removeClass('easyzoom easyzoom--overlay');}
});
EXPLANATION
I have multiple slideshows in one pages. Not all of the slideshow is going to be shown in the page, one of them will only show if the link to that slideshow is clicked. It sames like auto hide and show function. If one slideshow is shown, then other slideshows are hidden.
Each slideshow has their own thumbnails to control them.
The problem is all of the slideshow has no ID and has the same class, while all the slideshow is run with the same script.
If the thumbnail in the second slideshow I click, the slideshow doesn't move. And I realize it slides only the first slideshow.
SO, the solution is I have to remove the class of the slideshow.
Try is visible:
$(document).ready(function(){
if($('.bigPicture').is(':visible')){
$('.bigPicture').find('div').addClass('easyzoom easyzoom--overlay');
} else {
$('.bigPicture').find('div').removeClass('easyzoom');
}
});
This is what you are trying to do?
If so, it's easy to convert it to jquery syntax instead.
It would be easier if you had provided a jsFiddle of your problem.
CSS
.bigPicture {
width: 50px;
height: 20px;
border-style: solid;
border-width: 2px;
}
.hidden {
display: none;
}
.easyzoom {
background-color: red;
}
HTML
<div class="bigPicture">
<div>One</div>
</div>
<div class="bigPicture hidden">
<div class="easyzoom easyzoom--overlay">Two</div>
</div>
<div class="bigPicture hidden">
<div class="easyzoom easyzoom--overlay">Three</div>
</div>
Javascript
document.addEventListener('load', function () {
Array.prototype.forEach.call(document.querySelectorAll('.bigPicture'), function (bigPicture) {
var div = bigPicture.querySelector('div:first-of-type');
if (div) {
if (window.getComputedStyle(bigPicture).display === 'none') {
div.classList.remove('easyzoom', 'easyzoom--overlay');
} else {
div.classList.add('easyzoom', 'easyzoom--overlay');
}
}
});
}, true);
On jsFiddle
I think your code is somewhat working. Here is a fiddle where I have shown and hidden on the click of the buttons.
Code Snippet:
$(document).on('click','#addBigPicture',function(){
$('.bigPicture').css('display','block');
if($('.bigPicture').css('display') == 'block')
{$('.bigPicture').find('div').addClass('easyzoom easyzoom--overlay');};
});
$(document).on('click','#hideBigPicture',function(){
$('.bigPicture').css('display','none');
if($('.bigPicture').css('display') == 'none')
{$('.bigPicture').find('div').removeClass('easyzoom easyzoom--overlay');}
});
The if loops are as desired by you. Hope it helps!!
I am currently building a menu bar that consists of icons that show a contextual submenu when hovered over. Essentially, when hovering over an icon a popup menu/tooltip appears (with more options), but the icon itself should be clickable as well.
So far, I use the following HTML construct and jQuery for each menu item:
<div id="profile" class="menu-item">
<div id="profile-tip" class="tip">
**insert profile menu options**
</div>
</div>
<div id="search" class="menu-item">
<div id="search-tip" class="tip">
**insert search menu options**
</div>
</div>
and
$(".menu-item").hover(function() {
$(this).find("div").fadeIn("fast").show(); //add 'show()'' for IE
$(this).mouseleave(function () { //hide tooltip when the mouse moves off of the element
$(this).find("div").hide();
});
});
What I wish to do is to change the HTML to look as follows (so I can apply an onClick link to the "profiles" div):
<div id="profile" class="menu-item" onclick="window.location = 'profile.php'"></div>
<div id="profile-tip" class="tip">
**insert menu options**
</div>
However, I don't know how to modify the jQuery to find the matching div to display when hovered over. The associated tooltip/popup menu div will always be xxxx-tip (where xxx is the name of the parent div).
As an example, I imagine it will look something like this (keep in mind I know very little about jQuery so I'm well aware this will look stupid):
$(".menu-item").hover(function() {
$.find("div").attr('id'+"-tip").fadeIn("fast").show(); //add 'show()'' for IE
$(this).mouseleave(function () { //hide tooltip when the mouse moves off of the element
$.find("div").attr('id'+"-tip").hide();
});
});
To summarise: I need the jQuery modified to show the div based on the parent div's ID + the string "-tip"
Hopefully that isn't too confusing. Any help GREATLY appreciated :)
Not sure I understand completely what you want, but maybe try something a little more like this:
$(".menu-item").hover(
function() {
$(this).find(".tip").fadeIn("fast").show(); //add 'show()'' for IE
},
function() { //hide tooltip when the mouse moves off of the element
$(this).find(".tip").hide();
}
);
Edit: If the tip element is not a child of the menu item div, this could work:
$(".menu-item").hover(
function() {
$('#' + this.id + '-tip').fadeIn("fast").show(); //add 'show()'' for IE
},
function() { //hide tooltip when the mouse moves off of the element
$('#' + this.id + '-tip').hide();
}
);
Instead of finding the name of the div in the PARENT of the thing you're hovered over, use jQuery to find the tooltip that is a CHILD of the thing you're hovered over...search down the DOM, instead of UP.
Use jQuery's $(this) operator...
$('.menu-item').hover(function(){
$(this).find('.tip).fadeIn();
},
function() {
$(this).find('.tip).fadeOut();
});
I'm not 100% clear on the goal here but you can get your div by ID as shown here:
$(".menu-item").hover(function()
{
$(this).find(".tip").fadeIn("fast").show();
});
Or in CSS:
.menu-item .tip
{
display: none;
}
.menu-item .tip:hover,
.menu-item:hover .tip
{
display: auto;
}
I have a Q&A list with "Open All/Close All" at the top with individual open and close image buttons that toggle when clicked. That works fine.
Then follow individual Q&As, and each has its own open and close image.
If you click on "Open All/Close All" first, as soon as the page loads, and then click on the individual Q&A open/close images, all works fine. But if after page load you click on the individual Q&A open/close images, bypassing "Open All/Close All," they display the inappropriate open or close image.
Here is page code:
<div class="answersee"><span>Open All</span><img src="assets/open.gif" border="0" alt="" /></div>
<div class="answerhide"><span>Close All</span><img src="assets/close.gif" border="0" alt="" /></div>
<div class="qa">
<div><img src="open.gif" border="0" alt="" /><span class="question">Question.</span></div>
<div class="answer"><p>Answer.</p></div>
</div>
Here's the script (also uses Jquery):
$(function () {
$(".qa").click(function () {
$(this).find("div").next().slideToggle("fast");
if ($(this).find("div:eq(0)").find("img").attr("src") == "open.gif") {
$(this).find("div:eq(0)").find("img").attr("src", "close.gif");
}
else {
$(this).find("div:eq(0)").find("img").attr("src", "open.gif");
}
});
$(".answersee").click(function () {
$(".answer").show("fast");
$(".qa > div > img").attr("src", "close.gif");
$(".answerhide").show();
$(".answersee").hide();
})
$(".answerhide").click(function () {
$(".answer").hide("fast");
$(".qa > div > img").attr("src", "open.gif");
$(".answersee").show();
$(".answerhide").hide();
})
});
I don't think it's a CSS problem, or I'd include that code here. Do I need to initialize the script in some way? Or did I make a mistake in the above script?
Here's how I would do it.
Working Demo →
EDIT:
Update the code to have simple open/close link.
Code with comments which explains my approach:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
<style>
body
{
font-family: "Verdana";
font-size: 12px;
}
.question
{
background-color: #ccc;
cursor: pointer;
padding: 5px;
margin-bottom: 10px;
border-bottom: 1px solid #000;
}
.answer {
padding: 5px;
}
</style>
<script>
$(document).ready(
function()
{
//Hide all the answers on page load.
$('.answer').hide();
//For all questions, add 'open'/'close' text.
//You can replace it with an image if you like.
//This way, you don't need to specify img tag in your HTML for each question.
$('.question')
.append(' <span>[ open ]</span>');
//Now there are two ways to toggle the visibility of answer.
//Either click on the question OR click on Open All / Close All link.
//To use the same code for both instances, we will create
//a function which will take the 'question' div and toggle the answer for it.
//Advantage of this approach is that the code to toggle the answer is in
//one place.
//By default, this function will try to toggle the status of the answer
//i.e. if it's visible, hide it otherwise show it.
//This function will take a second argument called 'showAnswer'.
//If this argument is passed, it overrides the toggle behavior.
//If 'showAnswer' is true, answer is shown.
//If it's false, answer is hidden.
//This second parameter will be used by the 'openAll', 'closeAll' links.
var toggleAnswer = function toggleAnswer(question, showAnswer)
{
//The way I have structured the HTML, answer DIV is right after
//question DIV.
var $answer = $(question).next('div');
//Animation callback, after the animation is done, we want to
//switch the 'text' to display what could the user do with the question.
//Once again, you can change this code to show open/close image.
var updateText = function()
{
var text = $answer.is(':visible') ? ' [close] ' : ' [open] ';
$(question).find('span').html(text);
}
var method = null;
if(arguments.length > 1)
{
//If the function was called with two arguments, use the second
//argument to decide whether to show or hide.
method = showAnswer === true ? 'show' : 'hide';
}
else
{
//Second argument was not passed, simply toggle the answer.
method = $answer.is(':visible') ? 'hide' : 'show';
}
$answer[method]('fast', updateText);
};
//On each question click, toggle the answer.
//If you have noticed, I didn't enclose both Q&A inside one DIV.
//The way you have done if user clicks on the answer, answer will collapse.
//This may not be desirable as user may want to copy the answer
//and he won't be able to.
$('.question').click(function(){ toggleAnswer(this);});
//We will reuse the same toggleAnswer method in openAll, closeAll
//handling. This way, if you want to change behavior of how the question/answers
//are toggled, you can do it in one place.
$('#openClose').click(
function()
{
var showAnswer = $(this).html().toLowerCase().indexOf('open') != -1 ? true : false;
$('.question').each(function() { toggleAnswer(this, showAnswer); });
$(this).html(showAnswer ? 'Close All' : 'Open All');
return false;
}
);
}
);
</script>
<html>
<head>
<title>simple document</title>
</head>
<body>
<a id='openClose' href='#'>Open All</a>
<br /><br />
<div class='question'>Question 1</div>
<div class='answer'>Answer 1</div>
<div class='question'>Question 2</div>
<div class='answer'>Answer 2</div>
<div class='question'>Question 3</div>
<div class='answer'>Answer 3</div>
</body>
</html>
You need to use the callbacks because your animation will not have finished by the time to check for which image is being shown.
$(".qa").click(function() {
$(this).find("div").next().slideToggle("fast", toggleImage);
}
function toggleImage(){
var $img = $(this).find("img");
$img.attr('src') == "open.gif" ? $img.attr('src', "close.gif") : $img.attr('src', "open.gif");
}
N.B There are better ways to do this but lets get you working first and then see if you want to refactor it some more.
Thank you for taking the time to provide this. I will try this later today and report back. In my version, I toggle the Open All/Close All feature. It's a cleaner look and easier to use, since you don't have to move your mouse.
Redsquare and Solution Yogi:
Thanks. I will reply again later and also post a working demo so you can see the problem more clearly. Sorry, I should have done that before.
Liz