Hover out delay for unintended action - javascript

I am trying to delay or stop the menu from slideUp action when a user hover off the menu by accident and then hovering again. I am trying to prevent the menu from sliding up when a user unintentionally rolls off the hover area. I want the user to hover back within a split second and not have the menu to slide up.
I used the delay function below as this does not prevent the menu from sliding up. Thanks.
$(document).ready(function() {
$('#nav li').hover(
function () {
//show its submenu
$('ul', this).slideDown(250);
},
function () {
//hide its submenu
$('ul', this).delay(1000).slideUp(500);
}
);
});
Demo: http://jsfiddle.net/D3A5g/
Here is a suggestion Nelson posted. It work on jsfiddle but not on my pages. Can anyone tell me what is preventing from working on my page?
Working Demo: http://jsfiddle.net/xwAdG/6/
Below code does not work when I test it. Any ideas why it's not working?
<html>
<head>
<style type="text/css">
#nav {
padding: 40px;
border: solid #999 1px;
}
#nav ul {
margin: 0;
padding: 0;
display: none;
background-color: #CCC;
}
#nav ul li {
margin: 0;
list-style: none;
list-style-type: none;
padding: 5px;
width: 40px;
}
#nav a {
color: black;
text-decoration: none;
padding: 5px;
}
#nav a:hover {
text-decoration: none;
background-color: yellow;
}​
</style>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<script type="text/javascript" src="http://cherne.net/brian/resources/jquery.hoverIntent.js"></script>
<script>
var config = {
over: function () { //onMouseOver callback (REQUIRED)
$('ul', this).slideDown(250);//show its submenu
},
timeout: 500, // milliseconds delay before onMouseOut (default 0)
out: function () { // function = onMouseOut callback (REQUIRED)
$('ul', this).slideUp(500); //hide its submenu
}
};
$('#nav li').hoverIntent(config);
</script>
</head>
<body>
<ul id="nav">
<li >Main
<ul>
<li>AAAAA</li>
<li>BBBBB</li>
<li>CCCCC</li>
<li>DDDDD</li>
<li>FFFFF</li>
</ul>
</li>
</ul>
</body>
</html>
UPDATE: I found out that I needed to wrap the code with $(document).ready. By doing this, it worked in a html page.
<script>
$(document).ready(function() {
var config = {
over: function () { //onMouseOver callback (REQUIRED)
$('ul', this).slideDown(250);//show its submenu
},
timeout: 500, // milliseconds delay before onMouseOut (default 0)
out: function () { // function = onMouseOut callback (REQUIRED)
$('ul', this).slideUp(500); //hide its submenu
}
};
$('#nav li').hoverIntent(config);
});​
</script>

I recommend you the hoverIntent plugin for that, I've use it in some projects and very happy so far.
Your posted code would be used with the plugin like this:
var config = {
over: function () { //onMouseOver callback (REQUIRED)
$('ul', '#nav li').slideDown(250);//show its submenu
},
timeout: 0, // milliseconds delay before onMouseOut (default 0)
out: function () { // function = onMouseOut callback (REQUIRED)
$('ul', '#nav li').slideUp(500); //hide its submenu
}
};
$('#nav li').hoverIntent(config);

Related

How to prevent continuous clicks on the element?

I want to prevent continuous clicks on the button .toggler. When I click on it div is toggling properly, but if I click on it continuously many times div toggles many times until all the click events have not been completed.
The expectation is that if I click the button, its click event should be off until the div has not been toggled properly. After that its click should be on.
Click the button continuously many times to see the issue.
$(document).ready(function() {
$('.toggler').on('click', function(event) {
event.preventDefault();
$('.main-div').slideToggle('slow');
});
});
* {
margin: 0px;
box-sizing: border-box;
}
.main-div {
width: 80%;
float: right;
height: 200px;
background: #ddd;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button type="button" class="toggler">Toggle</button>
<div class="main-div"></div>
The jQuery code I have tried is:
$(document).ready(function() {
$('.toggler').on('click', function(event) {
event.preventDefault();
var thisEement = $(this);
thisEement.off('click');
$('.main-div').slideToggle('slow', function(){
thisEement.on('click');
});
});
});
But that does not work as expected.
Any help would be appreciated <3.
The slideToggle has a callback function which is invoked when the operation is completed. So, you can introduce a new boolean variable that will be set to false when the operation starts and changed back to true when the toggle is completed.
$(document).ready(function() {
var flag = false;
$('.toggler').on('click', function(event) {
event.preventDefault();
if(!flag){
flag = true;
$('.main-div').slideToggle( "slow", function() {
flag = false;
});
}
});
});
* {margin: 0px; box-sizing: border-box;}
.main-div {width: 80%; float: right; height: 200px; background: #ddd;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button type="button" class="toggler">Toggle</button>
<div class="main-div"></div>
Try this,
$(document).ready(function() {
$('.toggler').on('click', function(event) {
event.preventDefault
$(".toggler").prop('disabled', true); // disable first
$('.main-div').slideToggle("slow", function() { // when slidetoggle ends
$(".toggler").prop('disabled', false); // enable button again.
});
});
});
jsfiddle demo
Hope helps,
Just use a boolean that will toggle when the slide starts and stops.
var inMotion = false;
$('.toggler').on('click', function(event) {
event.preventDefault();
if (inMotion == false) {
inMotion = true;
$('.main-div').slideToggle('slow', function() {
inMotion = false;
});
}
});
When the slideToggle() function finishes, that callback will run. The callback will set the boolean to false, allowing it to fire again.
Add the disabled attribute on click then remove it once the animation completes.
$(document).ready(function() {
$('.toggler').on('click', function(event) {
$(this).attr('disabled', 'disabled');
event.preventDefault();
$('.main-div').slideToggle('slow', function(){
$('.toggler').removeAttr('disabled');
});
});
});
* {margin: 0px; box-sizing: border-box;}
.main-div {width: 80%; float: right; height: 200px; background: #ddd;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button type="button" class="toggler">Toggle</button>
<div class="main-div"></div>
You can simply filter out the element while it's being animated and thus never queue up multiple toggles on it:
$('.main-div').not(':animated').slideToggle('slow');
No point in keeping track of this state yourself in some boolean when jQuery does it for you and lets you write functionally!
Full code (your original example modified):
$(document).ready(function() {
$('.toggler').on('click', function(event) {
event.preventDefault();
$('.main-div').not(':animated').slideToggle('slow');
});
});
FYI, your attempt would've worked if you properly re-bound the event handler function, but this is a much cleaner solution.
You can try this way...
$(document).ready(function() {
$('.toggler').on('click', function(event) {
$("#togglerButton").attr("disabled", "true");
$('.main-div').slideToggle('slow', function() {
$("#togglerButton").removeAttr("disabled");
});
});
});
* {
margin: 0px;
box-sizing: border-box;
}
.main-div {
width: 80%;
float: right;
height: 200px;
background: #ddd;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button type="button" class="toggler" id="togglerButton">Toggle</button>
<div class="main-div"></div>
You can also do this by using event object pass to the click event. you can get count for number of time the click event performed. based on which you can set condition in javascript code and prevent multiple clicks like code given below.
$(document).ready(function() {
$('.toggler').on('click', function(event) {
if (!event.originalEvent.detail || event.originalEvent.detail == 1) {
$('.main-div').slideToggle('slow');
}
});
});
$(document).ready(function() {
var res = false;
$('.toggler').on('click', function(event) {
event.preventDefault();
if(!res){
res = true;
$('.main-div').slideToggle( "slow", function() {
res = false;
});
}
});
});
* {margin: 0px; box-sizing: border-box;}
.main-div {width: 80%; float: right; height: 200px; background: #ddd;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button type="button" class="toggler">Toggle</button>
<div class="main-div"></div>

How to make this bootstrap nav submenu always open?

I have a code to make bs nav, but I don't understand how to make submenu always open without clicking menu name.
This is the code:
http://jsfiddle.net/6hrmodok/2/
and please answer this question with the new code.
To make the submenu always open in bootstrap navbar, you just need to add a class "open" like this <li class="dropdown open"> this will make your bootstrap's navbar submenu always open and it will toggle also.
.gw-nav-list>li.always-active>a,
.gw-nav-list>li.always-active>a:hover,
.gw-nav-list>li.always-active>a:focus,
.gw-nav-list>li.always-active>a:active {
background-color: #fff;
color: #2574A9;
font-weight: bold;
font-size: 13px;
}
.gw-nav-list>li.always-active:before {
display: inline-block;
content: "";
position: absolute;
left: 0px;
top: -1px;
bottom: 0;
z-index: 1;
border: 2px solid #2574A9;
border-width: 0 0 0 5px;
}
.always-active .gw-submenu,
.gw-nav-list>li.always-active .gw-submenu {
display:block;
}
And for JavaScript;
$('.gw-nav > li:not(.always-active) > a').click(function () {
....
Updated fiddle
you can open the submenu on page load with simple jquery code as below in your script file.
var pageload = function()
{
$(".gw-nav > li").each(function ()
{
var checkElement = $(this);
var ulDom = checkElement.find('.gw-submenu')[0];
if (ulDom != undefined) {
checkElement.addClass('active');
checkElement.find('ul').slideDown(300);
return;
}
});
}();
check the fiddler here.
http://jsfiddle.net/o1jw4txg/

Is there a Better way to handle Same callback function but different input params?

I have a callback function to delete an li element.
function deleteLi(liElement) {
liElement.remove()
}
Two buttons does the same operation. On hovering the liElement, I get a edit & delete option. On clicking the edit option, it opens a dialog which also has a delete option. So both the buttons, does the same and hence I am calling the same function.
But it looks like this
$('.edit').on('click', function() {
currentField = $(this).parents('li');
openDialog();
});
$('.delete1').on('click', function() {
deleteLi($(this).parents('li'));
});
$('.delete2').on('click', function() {
deleteLi(currentField)
});
So is there any other best way to handle this?
You can simply give a single class to both delete button 'delete1' and use following code
$('.delete1').on('click', function() {
deleteLi($(this).parents('li'));
});
If your css if different for that delete button then multiple class selector in jQuery.
Edited the code as per the comments:
$('.delete1, .delete2').on('click', function() {
if(currentField == null) {
currentField = $(this).parents('li');
}
deleteLi(currentField);
});
With this HTML:
<ul class="editableList">
<li>
<span>Stuff here</span>
-
e
</li>
<li>
<span>Other stuff here</span>
-
e
</li>
</ul>
And this J:
$('.editableList').on('click', '.delete', function(e){
e.preventDefault();
$(this).parent('li').remove()
}).on('click', '.edit', function(e){
e.preventDefault();
editLi(this);
});
function editLi(elt) {
// Code to edit "li > span" element
console.log('editing element', elt);
}
You can avoid thee global variable by adding a class (or a data attribute, i'm using a class here for the visual feedback) to the selected <li> on click of edit, and remove it once you close the edit popup:
$('.edit').on('click', function () { // open edit popup
$(this).closest('li').addClass("active"); // mark the current <li>
$("#editPopup").show();
});
$("#editPopup span").on("click", function () { // close edit popup
$(".active").removeClass("active"); // unselect it
$("#editPopup").hide();
});
$('.delete').on('click', function () { // inline delete option
$(this).closest('li').remove();
});
$('#delete').on('click', function () { // delete option in popup
$(".active").remove();
$("#editPopup").hide();
});
* {
margin:0;
padding:0;
}
ul {
list-style-type:none;
}
li {
border-bottom:1px solid;
background:silver;
height:50px;
line-height:50px;
}
li a {
display:none;
float:right;
margin:0 5px;
}
li:hover a {
display:inline-block;
}
li.active {
background:dodgerblue;
}
#editPopup {
display:none;
position:absolute;
top:0;
right:0;
bottom:0;
left:0;
width:200px;
height:50px;
margin:auto;
background:#fff;
box-shadow:0px 0px 5px 0px rgba(0, 0, 0, 0.5);
}
#editPopup span {
position:absolute;
right:5px;
cursor:pointer;
color:red;
}
#editPopup a {
margin:5px;
vertical-align:bottom;
}
li:first-child span{
padding:3px;
font-family: arial;
font-size: 14px;
color:#0077CC;
outline:1px solid grey;
background:white;
}
li:first-child span:hover{
text-decoration:underline;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="editableList">
<li> The <span>Full page</span> button is messing with my options!
x
edit
</li>
<li> <span>Item 2</span>
x
edit
</li>
<li> <span> Hover Me!</span>
x
edit
</li>
</ul>
<div id="editPopup"> <span>x</span><br/>
edit
delete
</div>
I'd use callback approach. When Edit button is hit, you define the currentField variable, and then define anonymous callback, which is called from openDialog's deleteButton.
$('.delete1').on('click', function () {
deleteLi($(this).parents('li'));
});
$('.edit').on('click', function () {
var currentField = $(this).parents('li');
openDialog({
onDelete: function () {
deleteLi(currentField);
}
});
});
function openDialog(args) {
//... open dialog here ...
$('.delete2').on('click', args.onDelete);
}

Using Jquery to remove/add border on hover

I know there's several other threads with similar questions answered although I believe my question is slightly different.
Within my navigation the page you are currently on has a bottom border on the nav link. I'm trying to use Jquery to make it so that when you hover over any of the other links all borders are removed except for a new border on the hovered link. So within the example in JSFiddle when I hover over "About" the underline on "Home" would be replaced with an underline on "About" and then returned to "Home" when the mouseleaves.
http://jsfiddle.net/6Ucmq/
Anybody have any suggestions? All help greatly appreciated!
$(document).ready(function() {
$(".navigation a").hover(
function() { $(this).removeClass("hoverEffectSelect"); }
function() { $(this).addClass(".hoverEffect"); },
function() { $(this).removeClass(".hoverEffect"); }
);
});
Try
$(document).ready(function () {
var $home = $(".navigation a.hoverEffectSelect");
$(".navigation a").hover(function () {
$home.removeClass("hoverEffectSelect");
$(this).addClass("hoverEffectSelect");
},function () {
$(this).removeClass("hoverEffectSelect");
$home.addClass("hoverEffectSelect");
});
});
Demo: Fiddle
No jQuery necessary: JSFiddle
The idea is to apply the border-bottom to the active element and to the hovered one, but when the entire navigation is hovered over it should hide the border from the active element.
HTML:
<div class="headingTop">
<div class="navigation">
<a class="hoverEffect active" href=".html">HOME</a>
<a class="hoverEffect" href=".html">ABOUT</a>
<a class="hoverEffect" href=".html">PROJECTS</a>
<a class="hoverEffect" href="r.html">CONTACT</a>
</div><!-- DIV navigation -->
</div><!-- DIV headingTop -->
CSS:
.navigation a {
color: black;
text-decoration: none;
font-size: 20px;
font-family: 'Roboto Condensed', 'Alef', sans-serif;
margin-left: 20px;
border-bottom: 0px solid transparent;
}
.hoverEffect {
transition: border-bottom 300ms linear;
}
.navigation:hover>.active {
border-bottom: 0px solid transparent;
}
.hoverEffect.active, .navigation>.hoverEffect:hover {
border-bottom: 2px solid #EBCD37;
}
Try:
$(".navigation a").hover(function() {
$(".navigation a").css('border-width', '0');
$(this).css('border', '3px solid black');
});
In this case you will remove the borders first, then set it as you want.
You can do like this:
$(document).ready(function () {
var index = $('a.hoverEffectSelect').index();
$(".navigation a").hover(function () {
$(".navigation a").removeClass("hoverEffectSelect");
$(this).addClass("hoverEffect");
}, function () {
$(this).removeClass("hoverEffect");
$('.navigation a').eq(index).addClass('hoverEffectSelect');
});
});
Fiddle Demo
Try this
$(document).ready(function () {
var olda = $('.navigation a.hoverEffectSelect').index();
$(".navigation a").hover(function (olda) {
$('.navigation a').removeClass("hoverEffectSelect");
$(this).addClass("hoverEffect");
}, function () {
$('.navigation a:eq(' + olda + ')').addClass("hoverEffectSelect");
});
});
DEMO

Add bullet controls to a tabbed slideshow

Here's hoping someone know how to do this. I am new to programming and haven't been able to figure it out or find the answer anywhere else. What i am trying to do is add a secondary control to an existing tabbed slideshow. The secondary control will be linked bullets that become active and inactive just like the existing links do as the slideshow plays and on click.
You can see an example of what I have here http://jsfiddle.net/j08691/ZSPX3/1/. The jquery code follows. Thanks in advance for any help.
var HM = {
//tab
jqs_slideList: '.slideList',
jqs_tabList: '.slides .carouselLinks',
init: function() {
//init sliders
var aSliders = $(this.jqs_slideList);
if (aSliders.length > 0) {
this.slideShow(aSliders);
}
//init the carousels that are lists of links
$('.carousel.icons').hellmannsCrsl({
rotateSpeed: 5000,
viewport: '.carouselLinks'
});
},
slideShow: function(eSlideListParam) {
var slideList = eSlideListParam,
slides = slideList.find('li'),
tabList = slideList.siblings('.carouselLinks'),
tabs = tabList.find('li'),
speed = 500;
tabs.on('click', 'a', function(e) {
$(this).trigger('slides.swap');
e.preventDefault();
});
//make it automatic, but this doesn't work properly, I'm stuck...
setInterval(function() {
var current = parseInt($('li.selected a').data('links-to').split('_')[1],10);
var idx=current-1;
var max = $('.carouselLinks li a').length;
idx = (current<max) ? (idx+1):0;
$('a:eq('+idx+')').trigger('click');
}, 3000);
/**
* This is where the animation, i.e. fade, is performing.
* I find it quite convenient to use bind/trigger principle as it's easier to maintain
*/
tabs.find('a').bind('slides.swap', function() {
var self = $(this),
selfIndex = self.parent().index(),
targetSlide = slides.eq(selfIndex);
//fade in/out slides
slides.filter('.active').stop(true, false).fadeOut(speed, function() {
$(this).removeClass('active');
});
targetSlide.stop(true, false).fadeIn(speed).addClass('active');
tabs.removeClass('selected');
self.parent().addClass('selected');
});
}
};
HM.init();
Here's a Fiddle
HTML
<!-- bullet ctrl -->
<div class="bulletLinks">
<ul>
<li><a data-links-to="slide_1" href="#">1</a></li>
<li class="selected"><a data-links-to="slide_2" href="#">2</a></li>
<li><a data-links-to="slide_3" href="#">3</a></li>
<li><a data-links-to="slide_4" href="#">4</a></li>
</ul>
</div>
<!-- /bullet ctrl -->
CSS
.bulletLinks a {
background: #900; // Or bullet background image
display: block;
float: left;
width: 20px;
height: 20px;
margin-right: 7px;
text-align: center;
text-decoration: none;
color: #fff;
border-radius: 50%;
transition: all 0.2s linear;
}
.bulletLinks a:hover {
background: #999;
color: #fff;
}
jQuery Code edits
tabList = slideList.siblings('.carouselLinks, .bulletLinks'),

Categories