JQuery-UI side menu hover area too wide - javascript

I have an application with a side-menu built using jQuery-ui. It can be collapsed to show icons only or expanded to also include menu titles.
On mouse hover, the sub-menu pops up, its location adjusted for whether the menu is collapsed or expanded.
The problem is the width of the hover area. It works fine when expanded. When collapsed, the hover area width should match the collapsed menu width. But it is still causing the sub-menu to appear when the mouse hovers over the area where the expanded menu would be.
In the html below, the menu div has a width defined in the style attribute, and I suspect it's the source of my issue. But I have not been able to cause the hover area width to change in coordination with the expand/collapse state of the menu. How can I fix this behavior?
See JSFiddle.
The html:
<div id="main$main_menu$1" class="ui-state-hover ui-corner-all menuBar">
<div id="main$visibility" class="menuContent">
<input type='button' value='4' id='menuVisibility' class="menuToggler ui-state-default ui-corner-all" onclick="runEffect();">
</div>
<div id="main$help_menu$1" class="menuContent" style="background: none; border: none; width: 100px;">
<span class="menuIcon">s</span>
<span class="menu_hideable menuHidden" >Help</span>
<ul class="menu menuDropdown ui-menu ui-widget ui-widget-content" style="width: 79px; display: none;" id="ui-id-121" role="menu" tabindex="0">
<li class="ui-menu-item" id="ui-id-122" tabindex="-1" role="menuitem"><div id="main$help_button$1">Contents</div></li>
<li class="ui-menu-item" id="ui-id-124" tabindex="-1" role="menuitem"><div id="main$help_about_button$1">About</div></li>
</ul></div>
</div>
Some CSS styling:
.menuBar {
padding: 0px;
margin: 0px;
height: 99%;
z-index: 100;
position: absolute;
top: 0px;
left: 0px;
width: 1.3em;
font-size: 24pt;
}
.menuBar-Expanded {
width: auto;
}
.menuDropdown{
margin: -24px 0px 0px 36px;
text-align: left;
z-index:101; /* dropdown on top of main menu */
position:absolute; /* do not displace the main menu items */
}
.menuDropdown-Expanded {
margin: -24px 0px 0px 100px; /* position of pop-ip when menu bar is expanded */
}
.menuContent{
padding: 4px 4px 4px 4px;
}
.menu_hideable {
display: inline;
}
.menuHidden {
display: none;
}
.menuIcon {
font-family: webdings;
font-size: 24pt;
height: 24px;
width: 24px;
vertical-align:middle;
}
.menuToggler {
font-family: webdings;
font-size: 14pt;
width:20px;
height:20px;
}
Javascript functions:
var collapseIcon = '3';
var expandIcon = '4';
function runEffect() {
$(".menu_hideable").toggleClass("menuHidden");
$("div#main\\$main_menu\\$1").toggleClass("menuBar-Expanded");
$(".menuDropdown").toggleClass("menuDropdown-Expanded");
if ($("#menuVisibility").val() == expandIcon) {
$("#menuVisibility").prop('value', collapseIcon);
} else {
$("#menuVisibility").prop('value', expandIcon);
}
};
$(document).ready(function() { var menu = $("#main\\$help_menu\\$1 > ul.menu").menu();
menu.menu('widget').hide();
$('#main\\$help_menu\\$1').hover(function () {
var menubarWidth = $("div#main\\$help_menu\\$1").css("width");
$("div#main\\$help_menu\\$1").addClass("ui-state-active");
menu.menu('widget').show();
$("div#main\\$help_menu\\$1").css("width", menubarWidth);
}, function () {
menu.menu('widget').hide();
$("div#main\\$help_menu\\$1").removeClass("ui-state-active");
});
$(menu).hover(function () {
menu.menu('widget').show();
}, function () {;
menu.menu('widget').hide();
});
});

Ok so the problem is that you set your hover area to width 100px. Put it relative to it's container with width 100% ! Like so https://jsfiddle.net/peurhwam/4/
<div id="main$help_menu$1" class="menuContent" style="background: none; border: none; width: 100%;">
You may have trouble with your padding, soo try to put padding inside instead of in the hover area directly.
EDIT : https://jsfiddle.net/peurhwam/6/

I believe the issue is the selector being used to call the hover function is set to this '#main\$help_menu\$1'. This includes the hidden content and is activated when you hover over it even when it is hidden.
Change the following line:
$('#main\\$help_menu\\$1').hover(function () {
to this:
$('.menuIcon').hover(function () {

Related

Show/hide div on scroll from ID to ID

I need to show a fixed div when i scroll onto and ID and then hide it when it gets to another ID or when a i scroll back to top and pass by the ID that had triggered it.
At the moment my code is showing the div in the ID i want and it's hidding when i scroll back to top at the same ID position but im not beeing able to also hide it when the next ID appears.
This is a small example of my code
https://jsfiddle.net/wo45r3yv/2/
I want to show the .cscroll div on scroll down at id="show" and then on scroll top hide it again on id="show" (that's working), when it reaches id="last-div" i want it to disappear again but also to appear on scroll top when reaches the bottom of id=middle-div, basicly the main idea is to have the fixed bar appearing on id="middle-div" but trigered by div ID and not screen position
Hope someone can help me
Many thanks
var offsetTop = $("#show").offset().top;
$(window).scroll(function(){
var scrollTop = $(window).scrollTop();
if(scrollTop > offsetTop){
$(".sticky-section").slideDown('200');
$(".cscroll").fadeIn('200');
}
else {
$(".sticky-section").slideUp('200');
$(".cscroll").fadeOut('200');
}
});
#first-div {
height: 600px;
background-color: red;
}
#middle-div {
height: 1600px;
background-color: blue;
}
#last-div {
height: 2600px;
background-color: green;
}
.cscroll {
width : 100%;
}
.sticky-section {
position: fixed;
top: 0px;
z-index: 8;
background-color: white;
color: black;
padding-top: 10px;
padding-bottom: 5px;
display: none;
text-align: center;
box-shadow: 0px 12px 21px -8px rgba(0,0,0,0.32);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="first-div">
MASTER
</div>
<div id="show"></div>
<div class="cscroll sticky-section">
<h4>
sticky content headline
</h4>
<h5>
more texts
</h5>
</div>
<div id="middle-div">
NEW DIV
</div>
<div id="last-div">
LAST DIV
</div>

Using CSS Tooltips in a Multiple-Column DIV

I need to display tooltips for specific terms in a multiple-column div, and I need them to work across multiple browsers. I began with the w3schools CSS Tooltip example, which works great in a normal (single-column) container. But with multiple columns, Chrome has some serious (perhaps not deal-breaking) formatting issues, and Safari fails badly, cropping the tooltip to the column in which it should appear. Firefox works properly.
Firefox:
Chrome:
Safari:
I thought perhaps Safari was treating overflow as though it were set to hidden, but if so, I couldn't find any way to change its behavior. And I couldn't find any existing questions that address tooltip formatting problems in multi-column layouts.
Now I'm worried that I may have to bite the bullet and write the custom javascript to detect hover, grab the text of the tooltip, stuff the text into a div that floats above the content of my page, reveal the div properly positioned in relation to the link, and hide it again when the mouse moves off the link. Obviously, it would be a lot easier if I could make the w3schools tooltip code work with multiple columns. (Using a table or grid in place of multiple columns is not an for this project.)
Has anyone else encountered (and hopefully solved) this issue?
Here's my code; if you run the snippet you'll see that the upper div shows a normal single-column div that works fine across browsers; the lower div is the two-column div that generated the screenshots above.
/* Tooltip container */
.tooltip {
position: relative;
display: inline-block;
}
/* Tooltip text */
.tooltip .tooltiptext {
visibility: hidden;
width: 150px;
background-color: black;
color: #fff;
text-align: center;
padding: 5px;
border-radius: 6px;
/* Position the tooltip text */
position: absolute;
z-index: 1;
top: 160%;
left: 50%;
margin-left: -75px;
/* Use half of the width (150/2 = 75), to center the tooltip */
}
.tooltip .tooltiptext::after {
/* Add an arrow */
content: " ";
position: absolute;
bottom: 100%;
/* At the top of the tooltip */
left: 50%;
margin-left: -10px;
border-width: 10px;
border-style: solid;
border-color: transparent transparent black transparent;
}
/* Show the tooltip text when you mouse over the tooltip container */
.tooltip:hover .tooltiptext {
visibility: visible;
}
.contentDiv {
margin-left: 50px;
padding: 5px;
width: 100px;
border: 1px solid black;
}
.contentDiv p {
margin: 0;
}
.contentDiv.twoColumn {
width: 210px;
column-count: 2;
-moz-column-count: 2;
-webkit-column-count: 2;
column-rule: 1px solid black;
-moz-column-rule: 1px solid black;
-webkit-column-rule: 1px solid black;
}
<div class="contentDiv">
<p>
<span class="tooltip">Hover 1
<span class="tooltiptext">Tooltip text for Hover #1.</span>
</span>
</p>
<p>
<span class="tooltip">Hover 2
<span class="tooltiptext">Tooltip text for Hover #2.</span>
</span>
</p>
</div>
<div style="clear:both;"></div>
<br>
<div class="contentDiv twoColumn">
<p>
<span class="tooltip">Hover 3
<span class="tooltiptext">Tooltip text for Hover #3.</span>
</span>
</p>
<p>
<span class="tooltip">Hover 4
<span class="tooltiptext">Tooltip text for Hover #4.</span>
</span>
</p>
</div>
Link to JsFiddle
.tooltip .tooltiptext {
-webkit-column-break-inside: avoid;
-webkit-backface-visibility: hidden;
}
This can fix for the overflow part but i notice that the last item of the column, the tooltip will still go up instead of below it.
Feel like column overflow issue still haven't fix for chrome yet, maybe can try to use flex.
The incompatibilities among browsers have defeated my effort to find a css-only solution, so I bit the bullet, added a bit of javascript, and provide below a solution that works for me. This solution supports both text tooltips (which can include html markup) and picture tooltips.
$(function() {
var $tip;
function makeTip () {
$(document.body).append ("<div id='tooltip'></div>");
$tip = $("#tooltip");
}
$(".tipLink").hover (function () {
var st = $(this).data ("tip"),
rect = this.getBoundingClientRect(),
hasImage = st.match(/^<img/) ? true : false,
bottomPadding = hasImage ? "5px" : "10px";
if (!$tip) {
makeTip ();
}
// It'd be good to preload the image!
$tip.html (st);
// Center tooltip and arrow below link.
$tip.css ({"display":"block",
"top": window.pageYOffset + rect.bottom + 10 + "px",
"left": window.pageXOffset + rect.left + rect.width/2,
"padding-bottom": bottomPadding});
},
function () {
$tip.css ("display", "none");
});
});
#tooltip {
display: none;
background-color: #444;
font-family:"Times New Roman", Times, serif;
font-size: 1.2rem;
line-height: 1.3rem;
color: #fff;
text-align: center;
padding: 10px;
border-radius: 6px;
/* Position the tooltip text */
position: absolute;
z-index: 1;
max-width: 200px;
transform: translateX(-50%); /* translate left by half the tip width */
}
#tooltip::after { /* Add an arrow */
content: " ";
position: absolute;
bottom: 100%; /* At the top of the tooltip */
left: 50%; /* Centered horizontally */
margin-left: -10px;
border-width: 10px;
border-style: solid;
border-color: transparent transparent #444 transparent;
}
/* The styles below are for the demo, and aren't needed in actual use. */
.contentDiv {
margin-left: 100px;
padding: 5px;
width: 150px;
border: 1px solid black;
}
.contentDiv p {
margin: 0;
}
.contentDiv.twoColumn {
width: 300px;
column-count:2;
-moz-column-count: 2;
-webkit-column-count: 2;
column-rule: 1px solid black;
-moz-column-rule: 1px solid black;
-webkit-column-rule: 1px solid black;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<div class = "contentDiv">
<p>
Item 1: <span class="tipLink" data-tip="Tooltip text for Hover #1.">Hover 1</span>
</p>
<p>
Item 2: <span class="tipLink" data-tip="Tooltip text for Hover #2.">Hover 2</span>
</p>
</div>
<div style="clear:both;"></div>
<br>
<div class = "contentDiv twoColumn">
<p>
Item 3: <span class="tipLink" data-tip="Tooltip text for Hover #3.">Hover 3</span>
</p>
<p>
Item 4: <span class="tipLink" data-tip="<img src='https://upload.wikimedia.org/wikipedia/commons/thumb/archive/b/b3/20091118075632%21UN_flag.png/120px-UN_flag.png'>">Hover 4</span>
</p>
</div>
This solution (using jQuery) shows the tooltip text when you mouse over a tipLink element, such as this span:
<span class="tipLink" data-tip="Tooltip text">Link</span>
In this example, "Link" is the text on the page, and the contents of the data-tip are displayed as the tooltip when the user hovers over the word "Link".
Alternatively you can use the data-tip to specify an img element that will appear as the tip.
This code centers the tooltip below the tipLink element, and the tooltips appear properly in multi-column layouts on at least FireFox, Safari, and Chrome.
I hope others who want to make tooltips available in multi-column page elements may find this useful.

How can I make this div slide down from top with jQuery?

So I have 2 divs children of a display block parent. I would like to make div #2 (green) be on top of div #1 (red). With "on top" I'm not talking about z-index, I'm talking about literally being on top of the other. And then I was wondering if there could be a way to make div #2 slideDown()
As far as I tested, jQuery slideDown() or slideUp() works differently.
In the demo I made, when I run
$('.item-1').slideUp();
The item 2 is sliding up instead of item 1, why is that? I'm getting confused.
Any hints would be appreciated,
Thanks in advance.
window.slide = function() {
$('.item-1').slideUp();
}
.items-container {
height: 400px;
width: 240px;
background-color: #c3c3c3;
display: block;
/* overflow: hidden; */
}
.item {
height: 100%;
width: 240px;
position: relative;
font-size: 30px;
text-align: center;
vertical-alignment: middle;
}
.item-1 {
background-color: red;
}
.item-2 {
float: left;
position: relative;
background-color: green;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button onclick="slide()">
Click me!
</button>
<div class="items-container">
<div class="item item-1">
1
</div>
<div class="item item-2">
2
</div>
</div>
jQuery's slideUp() and slideDown() methods animate the height of the matched elements, not position as you seemed to want: http://api.jquery.com/slideUp/.
What you seem to want is to translate the div it so that it moves on top of the first one.
http://www.w3schools.com/css/css3_2dtransforms.asp
window.slideUp = function() {
$('.item-2').addClass('slideUp');
}
window.slideDown = function() {
$('.item-2').removeClass('slideUp');
}
.items-container {
height: 100px;
width: 240px;
background-color: #c3c3c3;
display: block;
/* overflow: hidden; */
}
.item {
height: 100%;
width: 240px;
position: relative;
font-size: 30px;
text-align: center;
vertical-alignment: middle;
}
.item-1 {
background-color: red;
}
.item-2 {
position: relative;
transition: transform linear 1s;
background-color: green;
}
.slideUp
{
transform: translate(0,-100%);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button onclick="slideUp()">
SlideUp!
</button>
<button onclick="slideDown()">
SlideDown!
</button>
<div class="items-container">
<div class="item item-1">
1
</div>
<div class="item item-2">
2
</div>
</div>
.slideUp() works by changing the height of the element. As that element gets shorter, following elements will move up the page.
As seen in the documentation:
The .slideUp() method animates the height of the matched elements. This causes lower parts of the page to slide up, appearing to conceal the items.
In your fiddle, item1 slides up as expected and as defined by the doc :
Description: Hide the matched elements with a sliding motion.
So your div slides up and disappears, and item2 doesn't "move", just fills the space in the DOM after item1 has been hidden.

Chrome 49 causing scroll when draggable element over scrollbar

This is a change in Chrome 49 from previous versions. In 49, if I have a draggable element, when I drag it over a vertical scrollbar it causes the horizontal scrollbar to scroll to the right, even when it's not accepted.
$(document).ready(function() {
$("#dragItem").bind("dragstart", function(e) {
e.originalEvent.dataTransfer.setData("Text", 'data');
});
});
#dropContainer {
border: 1px solid black;
overflow-x: auto;
overflow-y: auto;
width: 250px;
height: 250px;
display: inline-block;
}
#bigContent {
width: 1000px;
height: 1000px;
}
#dragSourceContainer {
display: inline-block;
vertical-align: top;
margin-top: 20px;
}
#dragItem {
border: 1px solid black;
cursor: pointer;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="dropContainer">
<div id="bigContent">
</div>
</div>
<div id="dragSourceContainer">
<div id="dragItem" draggable="true">
drag me to the left, over top the vertical scrollbar
</div>
</div>
JS Fiddle:
https://jsfiddle.net/a1qnbkeb/
My question is: how can I stop this behaviour without doing some crazy temporary scroll binding? The reason I ask this is because inside "dropContainer", I do allow things also to be dragged, and if they are dragged "within" drop container, I do want this behaviour.
I just don't want it when they're dragging new things in from outside.

Change 'Click' function to mouseover/mouseout

I am using the following sliding div script:
http://www.webdesignerwall.com/demo/jquery/simple-slide-panel.html
Currently, the slidetoggle function is activated when the .btn-slide button is clicked. This slides up the "panel" div.
Upon clicking the .btn-slide button a second time, the panel div is closed.
I am a complete newb at js, so any assistance would be appreciated. Here's what I am trying to do:
1) When the mouse moves over (as opposed to clicking) the .btn-slide class, i would like the panel to slide out.
2) Then, when the mouse moves out of either the .btn-slide or #panel, i would like the panel to close. (but if the mouse is over either one, the panel should stay open).
I was able to get it working to where the slidetoggle function would close either one, or the other, but not both.
Thank you in advance for the help.
Sincerely,
Mac
Here is the JS:
<script type="text/javascript">
jQuery(function($){
$(document).ready(function(){
$('.btn-slide').click(function() {
$("#panel").slideToggle("slow");
$(this).toggleClass("active"); return false;
});
});
});
</script>
here is the HTML currently being used:
<div id="prod_nav_tab">
<div id="panel">
This is where stuff goes!
</div>
<p class="slide"><a class="btn-slide">Table of Contents</a></p>
</div>
I have played with the CSS to fit my particular web site and is as follows (the original js, html, css can be obtained from the link above).
div#prod_nav_tab {
width: 200px;
height: 31px;
overflow: hidden;
background-color:#F00;
float: left;
margin: 0px 0px 0px 75px;
}
a:focus {
outline: none;
}
#panel {
background-color:#F00;
width: 200px;
height: 200px;
display: none;
position: absolute;
bottom: 0px;
}
.slide {
margin: 0;
padding: 0;
/* border-top: solid 4px #422410; **Adds a line at top of slide button to distibuish it */
background: url(images/btn-slide.gif) no-repeat center top;
}
.btn-slide {
background: #d8d8d8;
text-align: center;
width: 200px;
height: 31px;
padding: 0px 0px 0 0;
margin: 0 0 0 0;
display: block;
font: bold 12pt Arial, Helvetica, sans-serif;
color: #666;
text-decoration: none;
position: relative;
cursor: pointer;
/* background: url(images/white-arrow.gif) no-repeat right -50px; ** Controls Arrow up/down */
}
.active {
background-position: right 12px;
}
When you move away from the .btn-slide to the #panel it hides it now because it triggers the mouseleave event of the .btn-slide.
To prevent this you should do something like:
HTML:
<div id="trigger">
Slide down
<div id="panel">
Content of your panel
</div>
</div>
JQuery:
jQuery(function($) {
$(document).ready(function() {
$("#trigger").mouseenter(function() {
$("#panel").slideDown("slow");
$(this).addClass("active");
}).mouseleave(function() {
$("#panel").slideUp("slow");
$(this).removeClass("active");
});
});
});
Make sure in your CSS you then set the panel to be hidden from start...
div#panel {
display: none;
}

Categories

Resources