Bootstrap carousel brakes after hover the menu - javascript

I have a strange behaviour using a certain menu effect with Bootstrap carousel in the same page.
Basically, if I hover over the menu, Bootstrap carousel brakes, and give me the following error:
Chrome:
Cannot read property 'offsetWidth' of undefined
Firefox:
$next[0] is undefined
This is the Js Updated code i'm using for the effect:
var marker = $('#marker'),
current = $('.current');
// Initialize the marker position and the active class
current.addClass('active');
marker.css({
// Place the marker in the middle of the border
bottom: -(marker.height() / 2),
left: current.position().left,
width: current.outerWidth(),
display: "block"
});
if (Modernizr.csstransitions) {
console.log("using css3 transitions");
$('li.list').mouseover(function () {
var self = $(this),
offsetLeft = self.position().left,
// Use the element under the pointer OR the current page item
width = self.outerWidth() || current.outerWidth(),
// Ternary operator, because if using OR when offsetLeft is 0, it is considered a falsy value, thus causing a bug for the first element.
left = offsetLeft == 0 ? 0 : offsetLeft || current.position().left;
// Play with the active class
$('.active').removeClass('active');
self.addClass('active');
marker.css({
left: left,
width: width,
});
});
// When the mouse leaves the menu
$('ul.UlList').mouseleave(function () {
// remove all active classes, add active class to the current page item
$('.active').removeClass('active');
current.addClass('active');
// reset the marker to the current page item position and width
marker.css({
left: current.position().left,
width: current.outerWidth()
});
});
} else {
console.log("using jquery animate");
$('li.list').mouseover(function () {
var self = $(this),
offsetLeft = self.position().left,
// Use the element under the pointer OR the current page item
width = self.outerWidth() || current.outerWidth(),
// Ternary operator, because if using OR when offsetLeft is 0, it is considered a falsy value, thus causing a bug for the first element.
left = offsetLeft == 0 ? 0 : offsetLeft || current.position().left;
// Play with the active class
$('.active').removeClass('active');
self.addClass('active');
marker.stop().animate({
left: left,
width: width,
}, 300);
});
// When the mouse leaves the menu
$('ul.UlList').mouseleave(function () {
// remove all active classes, add active class to the current page item
$('.active').removeClass('active');
current.addClass('active');
// reset the marker to the current page item position and width
marker.stop().animate({
left: current.position().left,
width: current.outerWidth()
}, 300);
});
};
And here is a codepen that recreates the issue:
http://codepen.io/florinsimion/pen/AXaaOK

This is happening because $('li') will match all the li tags on your page, including the carousel ones. You need to select li tags of your menu:
$('ul > li').mouseover(....)
//^ add UL as parent for all your events
A better solution would be using a specific class for your menu:
current = $('.my-menu .current');
$('.my-menu li').mouseover(....);
$('ul.my-menu').mouseleave(....);
$('.my-menu .active').removeClass('active');
Don't forget your CSS, please take a look at this demo: http://codepen.io/anon/pen/AXaaap

Related

submenu is hidden behind google map

On home page (pocetna) when you go over "dizajn" vertical menu working fine, but the problem appears when you go in "kontakt" page, menu is just behind google map, and i dont know how to fix it. If someone know solutio i will be grateful. Thank you
code for javascript is like this ( this code was copied from video how to create vertical menu, because i dont know that much staff about coding. Thank you for understanding )
$("document").ready(function() {
// Function triggered when mouse hovers over a menu item
// Looking for a LI item that has a UL for a child element
// If it does trigger the function on mouseover
$('#sidebarmenu li a').parent().has('ul').mouseover(function() {
// offset() returns the top & left relative position on the doc for LI
tagOffset = $(this).offset();
/* I use the following to get the tag name for this
getTagName = $(this).get(0).tagName;
alert(getTagName); */
// Get distance from the left for the LI
offsetLeft = tagOffset.left;
// Get distance from the top for the LI
offsetTop = tagOffset.top;
// Move the new popup 180px to the left (Width of parent UL)
popOutOffsetLeft = offsetLeft + 226;
// Get the id for the first UL contained in the LI
closeParent = $(this).closest("ul").attr("id");
// Checking if the UL is a second level of third level popup menu
if (closeParent == 'sidebarmenu')
{
// Make menu visible and move it into position on the document
$(this).find('ul').first().css({'visibility' : 'visible', 'left' : popOutOffsetLeft + 'px', 'top' : offsetTop + 'px'});
} else {
// Find offset for the UL that surrounds the third level popup
secondOffset = $(this).find('ul').last().parent().offset();
// Subtract the top offset from the second menu to position properly
secondOffsetTop = secondOffset.top - offsetTop;
// Correct the positioning on offset left
secondOffsetLeft = offsetLeft - 10;
// Make menu visible and move it into position on the document
$(this).find('ul').last().css({'visibility' : 'visible', 'left' : secondOffsetLeft + 'px', 'top' : secondOffsetTop + 'px'});
}
});
// When the mouse moves off the menu hide everything
$('#sidebarmenu li a').parent().has('ul').mouseout(function() {
$(this).find('ul').css({'visibility' : 'hidden'});
});
});
Check out the console, you have not included jquery in kontakt page.
Insert this in your kontakt.php
<script src="js/vendor/jquery-1.10.1.min.js"></script>
Uncaught ReferenceError: $ is not defined Got this message while inspecting
jQuery File is missing in kontakt.php
Assign "z-index" css properties both for map and for menu containers, and the menu's one must be greater than map's one, e.g. 100 for menu and 99 for map.

Bootstrap affix dynamically on resize

I have a 100% height div with a nav underneath it and more content under that.
When the user scrolls passed the nav it sticks to the top of the page and when the user goes back to the 100% height div the nav is left behind.
As the div is 100% height the 'data-offset-top' for the nav needs to change dynamically.
The following code works for that:
$('#navigation').affix({
offset: {
top: $('#hero').height()
}
});
However when I resize the page the value of the offset does not get readded to the offset.
The following code checks for the page height to change and then gives the new height to the data-offset-top but it does not ` function affixChange()
{
$('#navigation').attr('data-offset-top', $('#hero').height());
$('#navigation').affix({
offset: {
top: $('#hero').height()
}
});
}
affixChange();
setInterval(function(){
affixChange();
console.log($('#hero').height());
}, 1000)
Why is my method not working?
Is there a better way to do this?
Bootstrap gives you the possibility to pass a function to calculate the offset dynamically:
$('#navigation').affix({
offset: {
top: function() { return $('#hero').height(); }
}
});
Unfortunately if you need data-offset-top to be set dynamically you need to handle this manually. While domachine provides the correct answer I wanted to offer here a way to re-calculate the value on page resize and also to add a space holder so that affixing runs smooth e.g. no page jumping when the contents gets affixed. This was an issue for me.
It re-calculates data-offset-top dynamically
It sets the offset space dynamically. The space will replace affix when affixed
So I use the following HTML:
<div class="my-affix" data-spy="affix" data-offset-top-dynamic="true" data-content-space-holder="#my-affix-space-holder"></div>
<div id="my-affix-space-holder"></div>
The following CSS:
.my-affix + #my-affix-space-holder {
display: none;
}
.my-affix.affix + #my-affix-space-holder {
display: block;
}
And a JS script:
var $dynamicAffixes = $('[data-offset-top-dynamic]');
$dynamicAffixes.each(function(){
// data-target is used for the element that should be affixed while data-spy is used to have some scroll breakpoint
var $thisAffix = $(this);
var $thisAffixMarginPlaceholder = $($thisAffix.attr('data-content-space-holder'));
var currentAffixHeight = $thisAffix.outerHeight();
// Assign the affix height to content placeholder - to add a margin in the page because of missing content
$thisAffixMarginPlaceholder.css('height', currentAffixHeight);
// Initialize affix height where it should trigger to become sticky
$thisAffix.affix({
offset: {
top: Math.round($(this).offset().top)
}
});
$(window).on('resize', function(){
var isAlreadyAffixed = false;
// Restore affix to its original position if scrolled already so we can calculate properly
if ($thisAffix.hasClass('affix')) {
$thisAffix.removeClass('affix');
isAlreadyAffixed = true;
}
var currentAffixPosition = Math.round($thisAffix.offset().top);
var currentAffixHeight = $thisAffix.outerHeight();
$thisAffix.data('bs.affix').options.offset.top = currentAffixPosition; // a hack
$thisAffixMarginPlaceholder.css('height', currentAffixHeight);
if (isAlreadyAffixed) {
$thisAffix.addClass('affix');
$thisAffix.affix('checkPosition');
}
});
});
Have you tried monitoring the window for a resize event?
$(window).resize(function() {
affixChange();
});

JS Move a Div by Scroll Location

I want to move a bootstrap "navbar" header off the page when the navbar's position on the page reaches 400px.
If you look at this jsfiddle, I want the .navbar to leave the top of the page when the blue block begins (at 400px). The navbar would stay on the page through the red div, then leave the top of the page when the blue block begins.
I have tried to do this with scrollorama (jquery plugin), but have not had success yet:
$(document).ready(function() {
var scrollorama = $.scrollorama({ blocks:'.scrollblock' });
scrollorama.animate('#fly-in',{ delay: 400, duration: 300, property:'top', start:-1400, end:0 });
});
I am looking for either a pure javascript solution, or with the scrollorama plugin. Thanks for any ideas!
I'm not very familiar with the scrollorama plugin but you can get this done simply with jQuery via the scroll() event:
$(window).scroll(function () {
var winTop = $(this).scrollTop();
var redHeight = $('#red').height();
if (winTop >= redHeight) {
/*if the scroll reaches the bottom of the red <div> make set '#move' element
position to absolute so it will move up with the red <div> */
$('#move').css({
'position': 'absolute',
'bottom': '0px',
'top': 'auto'
});
} else {
//else revert '#move' position back to fixed
$('#move').css({
'position': 'fixed',
'bottom': 'auto',
'top': '0px'
});
}
});
See this updated jsfiddle: jsfiddle.net/52VtD/1945/
Edit: make it so that the navbar disappears at the same point that the red div ends
I noticed that earlier as well but I'm having trouble locating the problem so I removed your imported style sheet and created a basic style for the navbar. To get the navbar disappears at the same point that the red div ends you need to subtract the navbar's height to the condition:
if (winTop >= redHeight - $('#move').height()) {
I've also restructured the markup to get this working properly. I've nested the navbar inside the red div and set the red div's position to relative.
See this jsfiddle: jsfiddle.net/52VtD/1981/
listen to the scroll event using jquery to find if the navbar overlaps with the red or blue div
Assign a class to the red div
<div class="redDiv" style="height:400px; background-color: red;">
Then listen to the scroll event and use the getBoundingClientRect() to find the co-ord of the navbar and the div in the view port to check for overlap
$(document).scroll(function(event)
{
var rect1 = $('.navbar').get(0).getBoundingClientRect();
var rect2 = $('.redDiv').get(0).getBoundingClientRect();
var overlap = !(rect1.right < rect2.left ||
rect1.left > rect2.right ||
rect1.bottom < rect2.top ||
rect1.top > rect2.bottom)
if(!overlap)
{
if ( $(".navbar").is(":visible") ) {
$('.navbar').hide();
}
}
else
{
if ( !$(".navbar").is(":visible") ) {
$('.navbar').show();
}
}
});
Here is a working fiddle
http://jsfiddle.net/SXzf7/

Jquery animate negative top and back to 0 - starts messing up after 3rd click

The site in question is this one:
http://www.pickmixmagazine.com/wordpress/
When you click on one of the posts (any of the boxes) an iframe will slide down from the top with the content in it. Once the "Home" button in the top left hand corner of the iframe is clicked, the iframe slides back up. This works perfectly the first 2 times, on the 3rd click on of a post, the content will slide down, but when the home button is clicked, the content slides back up normally but once it has slid all the way up to the position it should be in, the iframe drops straight back down to where it was before the home button was clicked, I click it again and then it works.
Here is the code I've used for both sliding up and sliding down functions:
/* slide down function */
var $div = $('iframe.primary');
var height = $div.height();
var width = parseInt($div.width());
$div.css({ height : height });
$div.css('top', -($div.width()));
$('.post').click(function () {
$('iframe.primary').load(function(){
$div.animate({ top: 0 }, { duration: 1000 });
})
return false;
});
/* slide Up function */
var elm = parent.document.getElementsByTagName('iframe')[0];
var jelm = $(elm);//convert to jQuery Element
var htmlElm = jelm[0];//convert to HTML Element
$('.homebtn').click(function(){
$(elm).animate({ top: -height }, { duration: 1000 });
return false;
})
Have you considered using Ajax, like load(), ready() in jquery to control them better?
I am also not sure what you are trying to do with this.
var height = $div.height();
$div.css({ height : height });
may be you want to get the height of the current window? Where you can get it this way
var $dDiv = $('iframe.primary');
var innerH = window.innerHeight;
$dDiv.height(innerH);
Also try avoiding naming your custom var with default names like height, width, div, etc... You will confuse yourself and make debugging a pain.

How to reposition a relative DIV using left/top?

I have a div with the attribute position: relative;. Now, there are three of these divs. They all get a unique ID etc.
Now if I click a div, I want it to animate to a certain position in the document. Although I cannot determine the left/top values since if I use "top" and "left", it will relatively set the left to its parents position.
Maybe a bit unclear, but here is what I got.
The CSS of the clickable DIV that will move.
div#left_hldr .switch_project {
z-index: 1001;
position: relative;
margin: 10px 0px 0px 0px;
cursor: pointer;
}
// Open project.
$(".switch_project").live('click', function() {
// Get the ID value.
var More_Id = $(this).attr("id");
// Explode the Id.
var Id_Split = More_Id.split("_");
// Get the project ID.
var Project_Id = Id_Split[2];
/*
Replacement of the switch project div.
1 ) Define the current position.
2 ) Define the new position.
3 ) Replace the DIV to the new position.
4 ) Fade the new page in.
5 ) Put the DIV back to its original position.
*/
// Current Position.
var Ori_Left = $(this).offset().left;
var Ori_Top = $(this).offset().top;
// New Position. [ Based on the content_hldr container ]
var New_Top = $("div#content_hldr").offset().top;
var New_Left = $("div#content_hldr").offset().left;
// Define the current div.
var Div_Rep = $(this);
// Hide the More Info tab.
$(Div_Rep).children(".more_info").fadeOut("fast");
// Fade content out.
$("div#content_hldr").fadeOut("fast");
// Replace the div.
$(Div_Rep).animate({
top: New_Top,
left: New_Left
}, "slow", function() {
// Load Home page in.
$("div#content_hldr").load("content/content.projects.php?id=" + Project_Id, function() {
// Re-define Cufon.
Cufon.replace('h2');
});
// Fade in the content.
$("div#content_hldr").fadeIn("fast", function() {
// Hide the replaced div.
$(Div_Rep).hide();
// Replace it back to its position.
$(Div_Rep).css({
top: Ori_Top,
left: Ori_Left
});
// Show the More Info tab again.
$(Div_Rep).children(".more_info").show();
// Fade back in.
$(Div_Rep).fadeIn("medium");
});
});
});
...it will relatively set the left to its parents position.
Actually, no. If you use left and top with a position: relative element, they'll offset it from where it otherwise would be if it weren't positioned (e.g., in the static flow), while continuing to reserve its space in the static flow. A subtle but important distinction (and hugely useful for drag-and-drop).
If you want to animate it to the top left of the document, you can figure out its offset (via offset), and then provide those as negative numbers for left and top, since of course if it's at (say) [100,50], then positioning it at [-100,-50] compared to its default position will...put it at [0,0].
Like this:
$("selector_for_your_divs").click(function() {
var pos, $this;
$this = $(this);
pos = $this.offset();
$this.animate({
left: "-" + pos.left + "px",
top: "-" + pos.top + "px"
});
});
Live example
Similarly, if you want to move it to be where another element is, simply subtract its position from the other element's position — that gives you the delta to apply:
$("selector_for_your_divs").click(function() {
var mypos, otherpos, $this;
// Move to the target element
$this = $(this);
pos = $this.offset();
otherpos = $('selector_for_other_element').offset();
pos.left = otherpos.left - pos.left;
pos.top = otherpos.top - pos.top;
$this.animate({
left: pos.left + "px",
top: pos.top + "px"
});
});
Live example

Categories