Appending DOM Loses Menu Drop Down Functionality - javascript

I am appending dynamic DOM elements (after Ajax calls to gather the data) as seen below. I have narrowed the code down to what I believe is most important:
<!-- SideMenu HTML -->
<div id="sidebar-menu">
<ul id="folders">
<!-- AJAX DATA POPULATES MENU HERE -->
<!-- HTML File calling JS function -->
<script>
$(document).ready(function() {
getParentFolders('parentFolderTitle');
});
</script>
// JS File function...
var parentFolders; // Values retrieved from AJAX calls
function buildFolderMenu(index) {
var markup = '<li class="has_sub">' +
'<a ... > parentFolders[index].Name + '</a>' +
'<ul ...>' +
'<li> SUB FOLDER TEST <li>' +
'</ul>' +
'</li>';
$(#folders').append(markup);
}
EDIT: My code is interacting with a 3rd party template, after reading the replies, I was able to track down the file which handles the 'click events'. However, based on my own code shown above, I am not sure how to adjust the template code to work with my dynamically appended DOM.
Here is the template code handling the click: (I can see the 'menuItemClick' function is where this is likely handled, but how do I apply the '.on('', function())' adjustments here, based on how this file is written?)
/**
* Theme: Adminto Admin Template
* Author: Coderthemes
* Module/App: Main Js
*/
!function($) {
"use strict";
var Sidemenu = function() {
this.$body = $("body"),
this.$openLeftBtn = $(".open-left"),
this.$menuItem = $("#sidebar-menu a")
};
Sidemenu.prototype.openLeftBar = function() {
$("#wrapper").toggleClass("enlarged");
$("#wrapper").addClass("forced");
if($("#wrapper").hasClass("enlarged") && $("body").hasClass("fixed-left")) {
$("body").removeClass("fixed-left").addClass("fixed-left-void");
} else if(!$("#wrapper").hasClass("enlarged") && $("body").hasClass("fixed-left-void")) {
$("body").removeClass("fixed-left-void").addClass("fixed-left");
}
if($("#wrapper").hasClass("enlarged")) {
$(".left ul").removeAttr("style");
} else {
$(".subdrop").siblings("ul:first").show();
}
toggle_slimscroll(".slimscrollleft");
$("body").trigger("resize");
},
//menu item click
Sidemenu.prototype.menuItemClick = function(e) {
if(!$("#wrapper").hasClass("enlarged")){
if($(this).parent().hasClass("has_sub")) {
}
if(!$(this).hasClass("subdrop")) {
// hide any open menus and remove all other classes
$("ul",$(this).parents("ul:first")).slideUp(350);
$("a",$(this).parents("ul:first")).removeClass("subdrop");
$("#sidebar-menu .pull-right i").removeClass("md-remove").addClass("md-add");
// open our new menu and add the open class
$(this).next("ul").slideDown(350);
$(this).addClass("subdrop");
$(".pull-right i",$(this).parents(".has_sub:last")).removeClass("md-add").addClass("md-remove");
$(".pull-right i",$(this).siblings("ul")).removeClass("md-remove").addClass("md-add");
}else if($(this).hasClass("subdrop")) {
$(this).removeClass("subdrop");
$(this).next("ul").slideUp(350);
$(".pull-right i",$(this).parent()).removeClass("md-remove").addClass("md-add");
}
}
},
//init sidemenu
Sidemenu.prototype.init = function() {
var $this = this;
var ua = navigator.userAgent,
event = (ua.match(/iP/i)) ? "touchstart" : "click";
//bind on click
this.$openLeftBtn.on(event, function(e) {
e.stopPropagation();
$this.openLeftBar();
});
// LEFT SIDE MAIN NAVIGATION
$this.$menuItem.on(event, $this.menuItemClick);
// NAVIGATION HIGHLIGHT & OPEN PARENT
$("#sidebar-menu ul li.has_sub a.active").parents("li:last").children("a:first").addClass("active").trigger("click");
},
//init Sidemenu
$.Sidemenu = new Sidemenu, $.Sidemenu.Constructor = Sidemenu
}(window.jQuery),
function($) {
"use strict";
var FullScreen = function() {
this.$body = $("body"),
this.$fullscreenBtn = $("#btn-fullscreen")
};
//turn on full screen
// Thanks to http://davidwalsh.name/fullscreen
FullScreen.prototype.launchFullscreen = function(element) {
if(element.requestFullscreen) {
element.requestFullscreen();
} else if(element.mozRequestFullScreen) {
element.mozRequestFullScreen();
} else if(element.webkitRequestFullscreen) {
element.webkitRequestFullscreen();
} else if(element.msRequestFullscreen) {
element.msRequestFullscreen();
}
},
FullScreen.prototype.exitFullscreen = function() {
if(document.exitFullscreen) {
document.exitFullscreen();
} else if(document.mozCancelFullScreen) {
document.mozCancelFullScreen();
} else if(document.webkitExitFullscreen) {
document.webkitExitFullscreen();
}
},
//toggle screen
FullScreen.prototype.toggle_fullscreen = function() {
var $this = this;
var fullscreenEnabled = document.fullscreenEnabled || document.mozFullScreenEnabled || document.webkitFullscreenEnabled;
if(fullscreenEnabled) {
if(!document.fullscreenElement && !document.mozFullScreenElement && !document.webkitFullscreenElement && !document.msFullscreenElement) {
$this.launchFullscreen(document.documentElement);
} else{
$this.exitFullscreen();
}
}
},
//init sidemenu
FullScreen.prototype.init = function() {
var $this = this;
//bind
$this.$fullscreenBtn.on('click', function() {
$this.toggle_fullscreen();
});
},
//init FullScreen
$.FullScreen = new FullScreen, $.FullScreen.Constructor = FullScreen
}(window.jQuery),
//main app module
function($) {
"use strict";
var App = function() {
this.VERSION = "1.5.0",
this.AUTHOR = "Coderthemes",
this.SUPPORT = "coderthemes#gmail.com",
this.pageScrollElement = "html, body",
this.$body = $("body")
};
//on doc load
App.prototype.onDocReady = function(e) {
FastClick.attach(document.body);
resizefunc.push("initscrolls");
resizefunc.push("changeptype");
$('.animate-number').each(function(){
$(this).animateNumbers($(this).attr("data-value"), true, parseInt($(this).attr("data-duration")));
});
//RUN RESIZE ITEMS
$(window).resize(debounce(resizeitems,100));
$("body").trigger("resize");
// right side-bar toggle
$('.right-bar-toggle').on('click', function(e){
$('#wrapper').toggleClass('right-bar-enabled');
});
},
//initilizing
App.prototype.init = function() {
var $this = this;
//document load initialization
$(document).ready($this.onDocReady);
//init side bar - left
$.Sidemenu.init();
//init fullscreen
$.FullScreen.init();
},
$.App = new App, $.App.Constructor = App
}(window.jQuery),
//initializing main application module
function($) {
"use strict";
$.App.init();
}(window.jQuery);
/* ------------ some utility functions ----------------------- */
//this full screen
var toggle_fullscreen = function () {
}
function executeFunctionByName(functionName, context /*, args */) {
var args = [].slice.call(arguments).splice(2);
var namespaces = functionName.split(".");
var func = namespaces.pop();
for(var i = 0; i < namespaces.length; i++) {
context = context[namespaces[i]];
}
return context[func].apply(this, args);
}
var w,h,dw,dh;
var changeptype = function(){
w = $(window).width();
h = $(window).height();
dw = $(document).width();
dh = $(document).height();
if(jQuery.browser.mobile === true){
$("body").addClass("mobile").removeClass("fixed-left");
}
if(!$("#wrapper").hasClass("forced")){
if(w > 990){
$("body").removeClass("smallscreen").addClass("widescreen");
$("#wrapper").removeClass("enlarged");
}else{
$("body").removeClass("widescreen").addClass("smallscreen");
$("#wrapper").addClass("enlarged");
$(".left ul").removeAttr("style");
}
if($("#wrapper").hasClass("enlarged") && $("body").hasClass("fixed-left")){
$("body").removeClass("fixed-left").addClass("fixed-left-void");
}else if(!$("#wrapper").hasClass("enlarged") && $("body").hasClass("fixed-left-void")){
$("body").removeClass("fixed-left-void").addClass("fixed-left");
}
}
toggle_slimscroll(".slimscrollleft");
}
var debounce = function(func, wait, immediate) {
var timeout, result;
return function() {
var context = this, args = arguments;
var later = function() {
timeout = null;
if (!immediate) result = func.apply(context, args);
};
var callNow = immediate && !timeout;
clearTimeout(timeout);
timeout = setTimeout(later, wait);
if (callNow) result = func.apply(context, args);
return result;
};
}
function resizeitems(){
if($.isArray(resizefunc)){
for (i = 0; i < resizefunc.length; i++) {
window[resizefunc[i]]();
}
}
}
function initscrolls(){
if(jQuery.browser.mobile !== true){
//SLIM SCROLL
$('.slimscroller').slimscroll({
height: 'auto',
size: "7px"
});
$('.slimscrollleft').slimScroll({
height: 'auto',
position: 'right',
size: "7px",
color: '#828e94',
wheelStep: 5
});
}
}
function toggle_slimscroll(item){
if($("#wrapper").hasClass("enlarged")){
$(item).css("overflow","inherit").parent().css("overflow","inherit");
$(item). siblings(".slimScrollBar").css("visibility","hidden");
}else{
$(item).css("overflow","hidden").parent().css("overflow","hidden");
$(item). siblings(".slimScrollBar").css("visibility","visible");
}
}
// === following js will activate the menu in left side bar based on url ====
$(document).ready(function() {
$("#sidebar-menu a").each(function() {
var pageUrl = window.location.href.split(/[?#]/)[0];
if (this.href == pageUrl) {
$(this).addClass("active");
$(this).parent().addClass("active"); // add active to li of the current link
$(this).parent().parent().prev().addClass("active"); // add active class to an anchor
$(this).parent().parent().prev().click(); // click the item to make it drop
}
});
});
var resizefunc = [];

This could because of the redraw event not firing on the browser implicitly after your DOM manipulation. Refer this post on how to redraw so your generated DOM is refreshed on the UI
Force DOM redraw/refresh on Chrome/Mac
If this doesn't work please share your CSS and the before DOM and after DOM generation screenshot

Related

JavaScript + jQuery + Angular: Element is not found

I have a JavaScript function defined. Inside this function, I define variables of type jQuery elements. So, the variables refer to divs on the HTML. This function returns an object that has a single function init().
In the $(document).ready function, I call init() function.
The problem is when the script loads, the DOM is not ready and hence the variables referring to jQuery items are being set to undefined.
Later, I call the init() function inside Angular ngOnInit() to make sure things are well initialized, so nothing is happening as the variables above are undefined and they are not being re-calculated again.
Seems, when a function in JavaScript is defined, its body runs, and hence the variables are run and set to undefined as the HTML elements were not in the DOM yet.
How can I re-calculate the variables when init() runs? I cannot get my mind on this thing.
Thanks
var mQuickSidebar = function() {
var topbarAside = $('#m_quick_sidebar');
console.log('Function: ', Date.now());
var topbarAsideTabs = $('#m_quick_sidebar_tabs');
var topbarAsideClose = $('#m_quick_sidebar_close');
var topbarAsideToggle = $('#m_quick_sidebar_toggle');
var topbarAsideContent = topbarAside.find('.m-quick-sidebar__content');
var initMessages = function() {
var messenger = $('#m_quick_sidebar_tabs_messenger');
if (messenger.length === 0) {
return;
}
var messengerMessages = messenger.find('.m-messenger__messages');
var init = function() {
var height = topbarAside.outerHeight(true) -
topbarAsideTabs.outerHeight(true) -
messenger.find('.m-messenger__form').outerHeight(true) - 120;
// init messages scrollable content
messengerMessages.css('height', height);
mApp.initScroller(messengerMessages, {});
}
init();
// reinit on window resize
mUtil.addResizeHandler(init);
}
var initSettings = function() {
var settings = $('#m_quick_sidebar_tabs_settings');
if (settings.length === 0) {
return;
}
// init dropdown tabbable content
var init = function() {
var height = mUtil.getViewPort().height - topbarAsideTabs.outerHeight(true) - 60;
// init settings scrollable content
settings.css('height', height);
mApp.initScroller(settings, {});
}
init();
// reinit on window resize
mUtil.addResizeHandler(init);
}
var initLogs = function() {
// init dropdown tabbable content
var logs = $('#m_quick_sidebar_tabs_logs');
if (logs.length === 0) {
return;
}
var init = function() {
var height = mUtil.getViewPort().height - topbarAsideTabs.outerHeight(true) - 60;
// init settings scrollable content
logs.css('height', height);
mApp.initScroller(logs, {});
}
init();
// reinit on window resize
mUtil.addResizeHandler(init);
}
var initOffcanvasTabs = function() {
initMessages();
initSettings();
initLogs();
}
var initOffcanvas = function() {
topbarAside.mOffcanvas({
class: 'm-quick-sidebar',
overlay: true,
close: topbarAsideClose,
toggle: topbarAsideToggle
});
// run once on first time dropdown shown
topbarAside.mOffcanvas().one('afterShow', function() {
mApp.block(topbarAside);
setTimeout(function() {
mApp.unblock(topbarAside);
topbarAsideContent.removeClass('m--hide');
initOffcanvasTabs();
}, 1000);
});
}
return {
init: function() {
console.log('Inside Init(): ', Date.now());
console.log($('#m_quick_sidebar')); // topbarAside is undefined here!
if (topbarAside.length === 0) {
return;
}
initOffcanvas();
}
}; }();
$(document).ready(function() {
console.log('document.ready: ', Date.now());
mQuickSidebar.init();
});
The problem is that you immediately invoke your function mQuickSidebar not
Seems, when a function in JavaScript is defined, its body runs
var mQuickSidebar = function() {
var topbarAside = $('#m_quick_sidebar');
console.log('Function: ', Date.now());
var topbarAsideTabs = $('#m_quick_sidebar_tabs');
var topbarAsideClose = $('#m_quick_sidebar_close');
var topbarAsideToggle = $('#m_quick_sidebar_toggle');
var topbarAsideContent = topbarAside.find('.m-quick-sidebar__content');
...
}(); // <---- this runs the function immediately
So those var declarations are run and since the DOM is not ready those selectors don't find anything. I'm actually surprised that it does not throw a $ undefined error of some sort
This looks like a broken implementation of The Module Pattern
I re-wrote your code in the Module Pattern. The changes are small. Keep in mind that everything declared inside the IIFE as a var are private and cannot be accessed through mQuickSidebar. Only the init function of mQuickSidebar is public. I did not know what you needed to be public or private. If you need further clarity just ask.
As a Module
var mQuickSidebar = (function(mUtil, mApp, $) {
console.log('Function: ', Date.now());
var topbarAside;
var topbarAsideTabs;
var topbarAsideClose;
var topbarAsideToggle;
var topbarAsideContent;
var initMessages = function() {
var messenger = $('#m_quick_sidebar_tabs_messenger');
if (messenger.length === 0) {
return;
}
var messengerMessages = messenger.find('.m-messenger__messages');
var init = function() {
var height = topbarAside.outerHeight(true) -
topbarAsideTabs.outerHeight(true) -
messenger.find('.m-messenger__form').outerHeight(true) - 120;
// init messages scrollable content
messengerMessages.css('height', height);
mApp.initScroller(messengerMessages, {});
};
init();
// reinit on window resize
mUtil.addResizeHandler(init);
};
var initSettings = function() {
var settings = $('#m_quick_sidebar_tabs_settings');
if (settings.length === 0) {
return;
}
// init dropdown tabbable content
var init = function() {
var height = mUtil.getViewPort().height - topbarAsideTabs.outerHeight(true) - 60;
// init settings scrollable content
settings.css('height', height);
mApp.initScroller(settings, {});
};
init();
// reinit on window resize
mUtil.addResizeHandler(init);
};
var initLogs = function() {
// init dropdown tabbable content
var logs = $('#m_quick_sidebar_tabs_logs');
if (logs.length === 0) {
return;
}
var init = function() {
var height = mUtil.getViewPort().height - topbarAsideTabs.outerHeight(true) - 60;
// init settings scrollable content
logs.css('height', height);
mApp.initScroller(logs, {});
};
init();
// reinit on window resize
mUtil.addResizeHandler(init);
};
var initOffcanvasTabs = function() {
initMessages();
initSettings();
initLogs();
};
var initOffcanvas = function() {
topbarAside.mOffcanvas({
class: 'm-quick-sidebar',
overlay: true,
close: topbarAsideClose,
toggle: topbarAsideToggle
});
// run once on first time dropdown shown
topbarAside.mOffcanvas().one('afterShow', function() {
mApp.block(topbarAside);
setTimeout(function() {
mApp.unblock(topbarAside);
topbarAsideContent.removeClass('m--hide');
initOffcanvasTabs();
}, 1000);
});
};
return {
init: function() {
console.log('Inside Init(): ', Date.now());
console.log($('#m_quick_sidebar')); // topbarAside is undefined here!
topbarAside = $('#m_quick_sidebar');
topbarAsideTabs = $('#m_quick_sidebar_tabs');
topbarAsideClose = $('#m_quick_sidebar_close');
topbarAsideToggle = $('#m_quick_sidebar_toggle');
topbarAsideContent = topbarAside.find('.m-quick-sidebar__content');
if (topbarAside.length === 0) {
return;
}
initOffcanvas();
}
};
})(mUtil, mApp, $);
$(document).ready(function() {
console.log('document.ready: ', Date.now());
mQuickSidebar.init();
});

Create two jQuery plugins that can talk to each other

My head is a mess right now. I want to create two jQuery plugins :
A tab plugin
A slider plugin.
This plugins has to talk to each other, for example, if I click on a tab, this tab will activate the correct index in the associated slider.
If i click on a slide, this will activate the correct tab too.
I started to create events listeners and triggers for that, when my tab was clicked, an event tabChanged is triggered, and in my slider plugin I'm listening to it.
But here is the trouble, my sliders can be loaded before my tabs, so the listeners is not attached correctly...
I tried to trigger another event on the document this time, called tabsLoaded and waiting for that response, it works but it start to be a bit confusing.
I was wondering if someone has a better solution for this ?
Tabs and sliders can work as standalone too, it might be possible to have only tabs without slider associated.
This is my tab plugin:
(function($) {
let pluginName = 'Tabs';
function Tabs(element, options) {
let settings = {};
this.element = element;
this.$element = $(this.element);
this.settings = $.extend({}, settings, options);
this.children = null;
this.activeTabIndex = 0;
this.nbTabs = 0;
this.init();
}
$.extend(Tabs.prototype, {
init: function() {
this.children = this.$element.children();
this.nbTabs = this.children.length;
// Listeners
this.children.on('click', {
tabs: this
}, this.onTabChange); // Click on a tab
$(this).on('tabChange', this.setActive);
// On Init, active the first tab
if (this.children && this.nbTabs > 0) {
$(this).trigger({
type: 'tabChange',
tab: this.children.first().index(),
});
}
$(document).trigger({
type: 'tabLoaded',
tabs: this,
});
},
setActive: function(event) {
this.activeTabIndex = event.tab;
this.children.eq(this.activeTabIndex).addClass('is-active');
},
onTabChange: function(event) {
event.preventDefault();
const tabs = event.data.tabs;
// Reset active classes
tabs.children.removeClass('is-active');
// Launch changeTab
$(tabs).trigger({
type: 'tabChange',
tab: tabs.children.index(event.currentTarget),
});
}
});
$.fn[pluginName] = function(options) {
return this.each(function() {
if (!$.data(this, pluginName)) {
$.data(this, pluginName, new Tabs(this, options));
}
});
};
})(jQuery);
jQuery(document).ready(function($) {
$('.js-tabs').Tabs();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
And this is my slider plugin listening to tabs :
(function($) {
let pluginName = 'Slider';
function Slider(element, options) {
let settings = {};
this.element = element;
this.$element = $(this.element);
this.settings = $.extend({}, settings, options);
this.id = null;
this.tabs = null;
this.children = null;
this.activeSlideIndex = 0;
this.nbSlides = 0;
this.init();
}
$.extend(Slider.prototype, {
init: function() {
this.id = this.$element.attr('id');
this.children = this.$element.children();
this.nbSlides = this.children.length;
// Listeners
// Click on slide
this.children.on('click', {
slider: this
}, this.onSlideChange);
// On slide change
$(this).on('slideChange', {
slider: this
}, this.onSlideChange);
$(this).on('change', this.update);
// On Init, active the first tab
if (this.children && this.nbSlides > 0) {
$(this).trigger({
type: 'slideChange',
slide: this.children.first().index(),
});
}
$(document).trigger({
type: 'sliderLoaded',
slider: this,
});
},
update: function() {
// if Slider has an associated Tabs
if (this.tabs) {
$(this.tabs).on('tabChange', {
slider: this
}, this.onTabChange);
}
},
onSlideChange: function(event) {
event.preventDefault();
const slider = event.data.slider;
const slide = event.slide;
// Reset active classes
slider.children.removeClass('is-active');
slider.activeSlideIndex = slide ? slide : event.currentTarget;
console.log(slider.activeSlideIndex);
slider.children.eq(slider.activeSlideIndex).addClass('is-active');
},
// TABS
onTabChange: function(event) {
const slider = event.data.slider;
const tabIndex = event.tab;
if ($(slider.children).eq(tabIndex).length >= 0) {
$(slider).trigger({
type: 'slideChange',
slide: tabIndex,
});
}
}
});
$.fn[pluginName] = function(options) {
return this.each(function() {
if (!$.data(this, pluginName)) {
$.data(this, pluginName, new Slider(this, options));
}
});
};
})(jQuery);
jQuery(document).ready(function($) {
$('.js-slider').Slider();
});
// On Tabs loaded, insert it into slider
jQuery(document).on('tabLoaded', function(event) {
const tabs = event.tabs;
const sliderId = jQuery(tabs.element).data('slider-id');
if (jQuery('#' + sliderId).first().data('Slider')) {
const slider = jQuery('#' + sliderId).first().data('Slider');
slider.tabs = tabs;
slider.update();
}
});
I followed #Anton's advices and i split my tabs and sliders and it's working nice :)
First, i removed my plugins' inits from plugins' files.
Then i put every inits into another file that i called "app.js"
My App.js looks like this :
jQuery(document).ready(function ($) {
let $sliders = $('.js-slider').Slider();
let $tabs = $('.js-tabs').Tabs();
$sliders.on('slideChanged', function (event) {
const sliderId = $(this).attr('id');
const slide = event.slide;
$tabs.filter('[data-slider-id=' + sliderId + ']').data('Tabs').select(slide);
});
$tabs.on('tabChanged', function (event) {
const sliderId = $(this).data('slider-id');
const tab = event.tab;
$sliders.filter('#' + sliderId).data('Slider').select(tab);
});
});
I'm listening every events sent like 'slideChanged', or 'tabChanged' then i get the right tabs or slider instance by their matching IDs.
Here my code for tabs :
(function($) {
let pluginName = 'Tabs';
function Tabs(element, options) {
let settings = {};
this.element = element;
this.$element = $(this.element);
this.settings = $.extend({}, settings, options);
this.children = null;
this.activeTabIndex = 0;
this.nbTabs = 0;
this.init();
}
$.extend(Tabs.prototype, {
init: function() {
this.children = this.$element.children();
this.nbTabs = this.children.length;
// Listeners
this.children.on('click', {
tabs: this
}, this.onTabClick); // Click on a tab
$(this).on('tabChanged', this.onTabClick);
// On Init, active the first tab
if (this.children && this.nbTabs > 0) {
this.children.first().click();
}
},
select: function(tab) {
// Reset active classes
this.children.removeClass('is-active');
this.activeTabIndex = tab;
this.children.eq(tab).addClass('is-active');
},
onTabClick: function(event) {
event.preventDefault();
const tabs = event.data.tabs;
const tab = tabs.children.index(event.currentTarget);
tabs.select(tab);
// Launch changeTab
$(tabs.element).trigger({
type: 'tabChanged',
tab: tab,
});
}
});
$.fn[pluginName] = function(options) {
return this.each(function() {
if (!$.data(this, pluginName)) {
$.data(this, pluginName, new Tabs(this, options));
}
});
};
})(jQuery);
and slider :
(function($) {
let pluginName = 'Slider';
function Slider(element, options) {
let settings = {};
this.element = element;
this.$element = $(this.element);
this.settings = $.extend({}, settings, options);
this.id = null;
this.tabs = null;
this.children = null;
this.activeSlideIndex = 0;
this.nbSlides = 0;
this.init();
}
$.extend(Slider.prototype, {
init: function() {
this.id = this.$element.attr('id');
this.children = this.$element.children();
this.nbSlides = this.children.length;
// Listeners
// Click on slide
this.children.on('click', {
slider: this
}, this.onSlideClick);
// On slide change
$(this).on('slideChanged', this.onSlideClick);
// On Init, active the first tab
if (this.children && this.nbSlides > 0) {
this.children.first().click();
}
},
select: function(slide) {
// Reset active classes
this.children.removeClass('is-active');
this.activeSlideIndex = slide;
this.children.eq(this.activeSlideIndex).addClass('is-active');
},
onSlideClick: function(event) {
event.preventDefault();
const slider = event.data.slider;
const slide = slider.children.index(event.currentTarget);
slider.select(slide);
// Launch changeTab
$(slider.element).trigger({
type: 'slideChanged',
slide: slide,
});
},
});
$.fn[pluginName] = function(options) {
return this.each(function() {
if (!$.data(this, pluginName)) {
$.data(this, pluginName, new Slider(this, options));
}
});
};
})(jQuery);

Uncaught TypeError: $(...).find(...).once is not a function in bootstrap/js/bootstrap.js?

I have installed bootstrap theme for building responsive theme then I installed jquery_update module as documentation in theme project and everything seems ok expect below js error appears in inspect elements console:
Uncaught TypeError: $(...).find(...).once is not a function in
bootstrap/js/bootstrap.js?o5l669
Any one please can help me?
this is the bootstrap.js:
/**
* #file
* bootstrap.js
*
* Provides general enhancements and fixes to Bootstrap's JS files.
*/
var Drupal = Drupal || {};
(function($, Drupal){
"use strict";
Drupal.behaviors.bootstrap = {
attach: function(context) {
// Provide some Bootstrap tab/Drupal integration.
$(context).find('.tabbable').once('bootstrap-tabs', function () {
var $wrapper = $(this);
var $tabs = $wrapper.find('.nav-tabs');
var $content = $wrapper.find('.tab-content');
var borderRadius = parseInt($content.css('borderBottomRightRadius'), 10);
var bootstrapTabResize = function() {
if ($wrapper.hasClass('tabs-left') || $wrapper.hasClass('tabs-right')) {
$content.css('min-height', $tabs.outerHeight());
}
};
// Add min-height on content for left and right tabs.
bootstrapTabResize();
// Detect tab switch.
if ($wrapper.hasClass('tabs-left') || $wrapper.hasClass('tabs-right')) {
$tabs.on('shown.bs.tab', 'a[data-toggle="tab"]', function (e) {
bootstrapTabResize();
if ($wrapper.hasClass('tabs-left')) {
if ($(e.target).parent().is(':first-child')) {
$content.css('borderTopLeftRadius', '0');
}
else {
$content.css('borderTopLeftRadius', borderRadius + 'px');
}
}
else {
if ($(e.target).parent().is(':first-child')) {
$content.css('borderTopRightRadius', '0');
}
else {
$content.css('borderTopRightRadius', borderRadius + 'px');
}
}
});
}
});
}
};
/**
* Bootstrap Popovers.
*/
Drupal.behaviors.bootstrapPopovers = {
attach: function (context, settings) {
if (settings.bootstrap && settings.bootstrap.popoverEnabled) {
var elements = $(context).find('[data-toggle="popover"]').toArray();
for (var i = 0; i < elements.length; i++) {
var $element = $(elements[i]);
var options = $.extend(true, {}, settings.bootstrap.popoverOptions, $element.data());
$element.popover(options);
}
}
}
};
/**
* Bootstrap Tooltips.
*/
Drupal.behaviors.bootstrapTooltips = {
attach: function (context, settings) {
if (settings.bootstrap && settings.bootstrap.tooltipEnabled) {
var elements = $(context).find('[data-toggle="tooltip"]').toArray();
for (var i = 0; i < elements.length; i++) {
var $element = $(elements[i]);
var options = $.extend(true, {}, settings.bootstrap.tooltipOptions, $element.data());
$element.tooltip(options);
}
}
}
};
/**
* Anchor fixes.
*/
var $scrollableElement = $();
Drupal.behaviors.bootstrapAnchors = {
attach: function(context, settings) {
var i, elements = ['html', 'body'];
if (!$scrollableElement.length) {
for (i = 0; i < elements.length; i++) {
var $element = $(elements[i]);
if ($element.scrollTop() > 0) {
$scrollableElement = $element;
break;
}
else {
$element.scrollTop(1);
if ($element.scrollTop() > 0) {
$element.scrollTop(0);
$scrollableElement = $element;
break;
}
}
}
}
if (!settings.bootstrap || !settings.bootstrap.anchorsFix) {
return;
}
var anchors = $(context).find('a').toArray();
for (i = 0; i < anchors.length; i++) {
if (!anchors[i].scrollTo) {
this.bootstrapAnchor(anchors[i]);
}
}
$scrollableElement.once('bootstrap-anchors', function () {
$scrollableElement.on('click.bootstrap-anchors', 'a[href*="#"]:not([data-toggle],[data-target])', function(e) {
this.scrollTo(e);
});
});
},
bootstrapAnchor: function (element) {
element.validAnchor = element.nodeName === 'A' && (location.hostname === element.hostname || !element.hostname) && element.hash.replace(/#/,'').length;
element.scrollTo = function(event) {
var attr = 'id';
var $target = $(element.hash);
if (!$target.length) {
attr = 'name';
$target = $('[name="' + element.hash.replace('#', '') + '"');
}
var offset = $target.offset().top - parseInt($scrollableElement.css('paddingTop'), 10) - parseInt($scrollableElement.css('marginTop'), 10);
if (this.validAnchor && $target.length && offset > 0) {
if (event) {
event.preventDefault();
}
var $fakeAnchor = $('<div/>')
.addClass('element-invisible')
.attr(attr, $target.attr(attr))
.css({
position: 'absolute',
top: offset + 'px',
zIndex: -1000
})
.appendTo(document);
$target.removeAttr(attr);
var complete = function () {
location.hash = element.hash;
$fakeAnchor.remove();
$target.attr(attr, element.hash.replace('#', ''));
};
if (Drupal.settings.bootstrap.anchorsSmoothScrolling) {
$scrollableElement.animate({ scrollTop: offset, avoidTransforms: true }, 400, complete);
}
else {
$scrollableElement.scrollTop(offset);
complete();
}
}
};
}
};
})(jQuery, Drupal);
I have same issue and my solution is exclude bootstrap.js on my custom theme.
also you can alter bootstrap.js
Maybe The problem is because of two version ov jquery load on your page, inspect your javascript and if there is two version of jquery, let one exist and remove another.
In my case, there are 2 jquery files (core, theme). I removed it from theme. it works perfectly fine.

"Uncaught TypeError: undefined is not a function" console error appearing

I'm getting a console error (Uncaught TypeError: undefined is not a function) on line 156 on load and I can't figure it out for the life of me. I've provided the line in question and the full context its in below. Also, I added the site link in case it helps. I would appreciate any and all help/advice.
Site link
Here is the line in question (156): if (!$imgs.length) {return $.Deferred.resolve().promise();}
Here is the full code: http://pastebin.com/Ext4TwdP#
//*********************************************************
// Let's start, shall we?
//*********************************************************
jQuery(document).ready(function($) {
//*********************************************************
// Global variables
//*********************************************************
// Morphing icons
var myIcons = new SVGMorpheus('#iconset', {
duration: 250,
rotation: 'none'
});
//*********************************************************
// Turn off all Ajax caching (IE caches $.load)
//*********************************************************
$.ajaxSetup({
cache: false
});
//*********************************************************
// Preloader
//*********************************************************
window.addEventListener('DOMContentLoaded', function() {
$('#projects-list, footer p').hide();
new QueryLoader2(document.querySelector("body"), {
barColor: "#f30",
backgroundColor: "#000",
barHeight: 1,
minimumTime: 200,
fadeOutTime: 0,
onComplete: function() {
$('.site-overlay').remove();
$('#masthead').slideDown(100, function(){
$('#projects-list, footer p').show().addClass('fadeInUp');
});
// Set a timeout because 100ms is too quick
$(function() {
setTimeout(function() {
$('#projects-list, footer p').removeClass('fadeInUp');
}, 500);
});
}
});
});
//*********************************************************
// Small features
//*********************************************************
// Set top margin for #content to always match the height of the top header
function resize() {
var headerTop = $('#masthead').outerHeight();
(headerTop != parseInt($('#content').css('margin-top').slice(0, -2))) ? $('#content').stop().animate({'margin-top': headerTop}, 150) : console.log('');
}
resize();
window.onresize = resize;
// Hide header when scrolling down and show header when scrolling up
var lastScrollTop = 0;
$(window).scroll(function(event){
var st = $(this).scrollTop();
if (st < lastScrollTop || st === 0){
$('#masthead').removeClass('unpinned');
} else {
$('#masthead').addClass('unpinned');
}
lastScrollTop = st;
});
//*********************************************************
// Project hovers
//*********************************************************
$('#content').on('mouseenter', 'article.project', function(){
// If loading icon doesn't exist in the DOM...
if ( !$('.overlay').find('.loading-icon').length) {
// And if the project wrapper is activated...
if ( $(this).closest('#main').find('#project-wrapper').hasClass('activated') ) {
$(this).addClass('hover');
} else {
$(this).addClass('hover grayscale grayscale-fade');
}
// If loading icon exists in the DOM...
} else {
$(this).find('.post-link').hide();
}
// Dirty fix for 1px white flicker on hover (Chrome)
var overlayWidth = $('article.project').outerWidth();
$('.overlay').css({
marginLeft: -1,
width: overlayWidth + 2
});
}).on('mouseleave', 'article.project', function(){
// If #project-wrapper is activated...
if ( $(this).closest('#main').find('#project-wrapper').hasClass('activated') ) {
$(this).removeClass('hover');
$(this).find('.post-link').show();
// If #project-wrapper is not activated...
} else {
// If loading icon is present...
if ( $(this).find('.loading-icon').length ) {
// Only remove the 'hover' class
$(this).removeClass('hover');
// If loading icon is not present...
} else {
// Remove all classes
$(this).removeClass('hover grayscale grayscale-fade');
$(this).find('.post-link').show();
}
}
});
// Adjust the project titles so they always fit the container nicely
function adjustTitle() {
var thumbWidth = $('article.project > img').outerWidth();
if (thumbWidth <= 220) {
$('.overlay > h3').addClass('mobile');
} else {
$('.overlay > h3').removeClass('mobile');
}
}
$(window).on('resize', adjustTitle);
//*********************************************************
// Projects
//*********************************************************
(function($) {
// Function to allow an event to fire after all images are loaded
$.fn.imagesLoaded = function () {
$imgs = this.find('img[src!=""]');
// if there's no images, just return an already resolved promise
if (!$imgs.length) {return $.Deferred.resolve().promise();}
// for each image, add a deferred object to the array which resolves when the image is loaded
var dfds = [];
$imgs.each(function(){
var dfd = $.Deferred();
dfds.push(dfd);
var img = new Image();
img.onload = function(){dfd.resolve();}
img.src = this.src;
});
// return a master promise object which will resolve when all the deferred objects have resolved
// IE - when all the images are loaded
return $.when.apply($,dfds);
}
// Function for additional styling
function projectStyles() {
// Check the first slide input
$('#slider input:first').attr('checked', 'checked');
$('#project-wrapper').addClass('activated');
// Make the articles grey again after activation
$('article.project').addClass('grayscale grayscale-fade').css('opacity', '0.4');
// CSS effects
$('.post-container').addClass('fadeInUp');
$('.close-button').addClass('fadeInDown');
// Remove pesky, sticky 'hover' class
$('article.project').removeClass('hover');
}
// Open the project container
function openProject() {
var post_id = $(this).data('id'), // data-id attribute for .post-link
ajaxURL = site.custom_ajax; // Ajax URL localized from functions.php
// Add a loading icon
$('<span class="loading-icon"></span>').insertBefore(this);
// Add the 'active' class to make sure the div stays dark while loading
$(this).closest('article.project').addClass('active');
// Make all the articles grey when an article is clicked
$('article.project').addClass('grayscale grayscale-fade').css('opacity', '0.4');
// Remove the corner ribbon
$('article').removeClass('current');
$('.corner-ribbon').remove();
// Get the response from the Ajax function
$.ajax({
type: 'POST',
url: ajaxURL,
context: this,
data: {'action': 'load-content', post_id: post_id },
success: function(response) {
// Add a corner ribbon to note the current activated project
$(this).closest('article.project').removeClass('active').addClass('current');
$('<div class="corner-ribbon">Current</div>').prependTo('article.current');
// Wait until all images are loaded
$('#project-container').html(response).imagesLoaded().then(function() {
// Remove the loading icon
$('.loading-icon').remove();
// If the user has scrolled...
if ($(window).scrollTop() !== 0) {
// First scroll the page to the top
$('html, body').animate({
scrollTop : 0
},400, function() {
// Make the max-height of the container exact for a smoother transition
function matchContainerHeight() {
var containerHeight = $('#project-container').outerHeight();
$('#project-wrapper.activated').css('max-height', containerHeight);
}
setTimeout(matchContainerHeight, 100);
$(window).on('resize', matchContainerHeight);
projectStyles();
});
// If the user has not scrolled...
} else {
// Make the max-height of the container exact for a smoother transition
function matchContainerHeight() {
var containerHeight = $('#project-container').outerHeight();
$('#project-wrapper.activated').css('max-height', containerHeight);
}
setTimeout(matchContainerHeight, 100);
$(window).on('resize', matchContainerHeight);
projectStyles();
}
return false;
});
}
});
}
// User event
$('#content').on('click', '.post-link', function(e) {
e.preventDefault();
var projectTitle = $(this).data('title'), // data-title attribute for .post-link
projectSlug = $(this).data('slug') // data-slug attribute for .post-link
// Calls openProject() in context of 'this' (.post-link)
openProject.call(this);
$('head').find('title').text(projectTitle + ' | Keebs');
});
})(jQuery);
//*********************************************************
// Close button
//*********************************************************
(function($) {
// Close the project container
function closeProject() {
// Remove classes
$(this).removeClass('fadeInDown');
$('#project-wrapper').removeClass('activated').css('max-height', '');
$('article.project').removeClass('grayscale grayscale-fade').css('opacity', '1');
$('.post-container').removeClass('fadeInUp');
$('article').removeClass('current');
// Remove the corner ribbon since no projects are currently activated
$('.corner-ribbon').remove();
// Set the height of the project wrapper back to 0
$('body.single #project-wrapper').css('max-height', 0);
// Change the title of the document
$('head').find('title').text(site.title);
}
// User event
$('#content').on('click', '.close-button', function(e) {
e.preventDefault();
closeProject();
});
})(jQuery);
//*********************************************************
// Home button
//*********************************************************
(function($) {
// Load the Home page
function loadHome() {
var contactButton = $('#contact-button');
$('#content').fadeOut(50, function() {
$('<span class="loading-icon page-loading-icon"></span>').insertBefore('#content');
}).load(site.url + '/ #primary', function() {
$('.page-loading-icon').remove();
$(this).fadeIn(50);
$('body').removeClass('contact');
$('#contact-info, #clients').removeClass('fadeInUp');
$('#projects-list').addClass('fadeInUp');
$('body.single #project-wrapper').css('max-height', 0);
});
// Change the Projects button to 'Contact'
if ($('body').hasClass('contact')) {
$(contactButton).removeClass('project-button').addClass('contact-button').attr('data-title', 'Get in touch').css('width', '96px').text('Get in touch').shuffleLetters();
myIcons.to('mail');
}
// Change the title of the document
$('head').find('title').text(site.title);
}
// User event
$('.site-title a').on('click', function(e) {
e.preventDefault();
// Prevent accidental double clicks
if (!$(this).data('isClicked')) {
var link = $(this);
loadHome();
link.data('isClicked', true);
setTimeout(function() {
link.removeData('isClicked')
}, 1000);
}
});
})(jQuery);
//*********************************************************
// Contact button
//*********************************************************
(function($) {
var contactButton = $('#contact-button');
// Load the Contact page
function loadContact() {
$('#content').fadeOut(50, function() {
$('<span class="loading-icon page-loading-icon"></span>').insertBefore('#content');
}).load(site.url + '/contact/ #contact-keebs', function() {
$('.page-loading-icon').remove();
$(this).fadeIn(50);
$('body').addClass('contact');
$('#projects-list').removeClass('fadeInUp');
$('#contact-info, #clients').addClass('fadeInUp');
});
// Change the Contact button to 'Projects'
$(contactButton).removeClass('contact-button').addClass('project-button').attr('data-title', 'Projects').css('width', '71px').text('Projects').shuffleLetters();
myIcons.to('work');
// Change the title of the document
$('head').find('title').text('Contact | Keebs');
}
// Load the Projects page
function loadProjects() {
$('#content').fadeOut(50, function() {
$('<span class="loading-icon page-loading-icon"></span>').insertBefore('#content');
}).load(site.url + '/ #primary', function() {
$('.page-loading-icon').remove();
$(this).fadeIn(50);
$('body').removeClass('contact');
$('#contact-info, #clients').removeClass('fadeInUp');
$('#projects-list').addClass('fadeInUp');
$('body.single #project-wrapper').css('max-height', 0);
});
// Change the Projects button to 'Contact'
$(contactButton).removeClass('project-button').addClass('contact-button').attr('data-title', 'Get in touch').css('width', '96px').text('Get in touch').shuffleLetters();
myIcons.to('mail');
// Change the title of the document
$('head').find('title').text(site.title);
}
// User event
$('#mail-wrap').on('click', function(e) {
e.preventDefault();
// Prevent accidental double clicks
if (!$(this).data('isClicked')) {
var link = $(this);
if (!contactButton.hasClass('project-button')) {
loadContact();
} else {
loadProjects();
}
link.data('isClicked', true);
setTimeout(function() {
link.removeData('isClicked')
}, 500);
}
});
})(jQuery);
//*********************************************************
// Single template
//*********************************************************
// Check the first slide input
$('body.single #slider input:first').attr('checked', 'checked');
// Set the height of the project container
$('body.single #project-container').imagesLoaded().then(function() {
var containerHeight = $('#project-container').outerHeight();
$('body.single #project-wrapper').css('max-height', containerHeight);
});
// Make the projects list grayscale if the project wrapper is activated
if ( $('body.single #project-wrapper').hasClass('activated') ) {
$('article.project').addClass('grayscale grayscale-fade').css('opacity', '0.4');
}
//*********************************************************
// Shuffle Letters by Martin Angelov
//*********************************************************
(function($){
$.fn.shuffleLetters = function(prop){
var options = $.extend({
"step" : 8, // How many times should the letters be changed
"fps" : 60, // Frames Per Second
"text" : "", // Use this text instead of the contents
"callback" : function(){} // Run once the animation is complete
},prop)
return this.each(function(){
var el = $(this),
str = "";
// Preventing parallel animations using a flag;
if(el.data('animated')){
return true;
}
el.data('animated',true);
if(options.text) {
str = options.text.split('');
}
else {
str = el.text().split('');
}
// The types array holds the type for each character;
// Letters holds the positions of non-space characters;
var types = [],
letters = [];
// Looping through all the chars of the string
for(var i=0;i<str.length;i++){
var ch = str[i];
if(ch == " "){
types[i] = "space";
continue;
}
else if(/[a-z]/.test(ch)){
types[i] = "lowerLetter";
}
else if(/[A-Z]/.test(ch)){
types[i] = "upperLetter";
}
else {
types[i] = "symbol";
}
letters.push(i);
}
el.html("");
// Self executing named function expression:
(function shuffle(start){
// This code is run options.fps times per second
// and updates the contents of the page element
var i,
len = letters.length,
strCopy = str.slice(0); // Fresh copy of the string
if(start>len){
// The animation is complete. Updating the
// flag and triggering the callback;
el.data('animated',false);
options.callback(el);
return;
}
// All the work gets done here
for(i=Math.max(start,0); i < len; i++){
// The start argument and options.step limit
// the characters we will be working on at once
if( i < start+options.step){
// Generate a random character at thsi position
strCopy[letters[i]] = randomChar(types[letters[i]]);
}
else {
strCopy[letters[i]] = "";
}
}
el.text(strCopy.join(""));
setTimeout(function(){
shuffle(start+1);
},1000/options.fps);
})(-options.step);
});
};
function randomChar(type){
var pool = "";
if (type == "lowerLetter"){
pool = "abcdefghijklmnopqrstuvwxyz0123456789";
}
else if (type == "upperLetter"){
pool = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
}
else if (type == "symbol"){
pool = ",.?/\\(^)![]{}*&^%$#'\"";
}
var arr = pool.split('');
return arr[Math.floor(Math.random()*arr.length)];
}
})(jQuery);
//*********************************************************
// iPad fix for slider
//*********************************************************
var iPadLabels = function () {
function fix() {
var labels = document.getElementsByTagName('label'),
target_id,
el;
for (var i = 0; labels[i]; i++) {
if (labels[i].getAttribute('for')) {
labels[i].onclick = labelClick;
}
}
}
function labelClick() {
el = document.getElementById(this.getAttribute('for'));
if (['radio', 'checkbox'].indexOf(el.getAttribute('type')) != -1) {
el.setAttribute('selected', !el.getAttribute('selected'));
} else {
el.focus();
}
}
return {
fix: fix
}
}();
window.onload = function () {
iPadLabels.fix();
}
//*********************************************************
// Annnd, we're done!
//*********************************************************
});
There were a couple problems with this.
1) I didn't declare the imgs variable.
2) I didn't include the () after $.Deferred.
So here's the updated code block:
// Function to allow an event to fire after all images are loaded
$.fn.imagesLoaded = function () {
var imgs = this.find('img[src!=""]');
// If there are no images, just return an already resolved promise
if (!imgs.length) {
return $.Deferred().resolve().promise();
}
// For each image, add a deferred object to the array which resolves when the image is loaded
var dfds = [];
imgs.each(function(){
var dfd = $.Deferred();
dfds.push(dfd);
var img = new Image();
img.onload = function(){dfd.resolve();};
img.src = this.src;
});
// Return a master promise object which will resolve when all the deferred objects have resolved
// IE - when all the images are loaded
return $.when.apply($, dfds);
};

SinglePage navigation

My website uses onePageNav and scrollTo jquery code. I would like to insert code which correct my position on the website when i click on the same link in the navigation (i scroll mouse up or down but current button (hover) in navigation has not moved yet on to the next one).
OnePageNav code:
;
(function ($, window, document, undefined) {
// our plugin constructor
var OnePageNav = function (elem, options) {
this.elem = elem;
this.$elem = $(elem);
this.options = options;
this.metadata = this.$elem.data('plugin-options');
this.$nav = this.$elem.find('a');
this.$win = $(window);
this.sections = {};
this.didScroll = false;
this.$doc = $(document);
this.docHeight = this.$doc.height();
};
// the plugin prototype
OnePageNav.prototype = {
defaults: {
currentClass: 'current',
changeHash: true,
easing: 'swing',
filter: '',
scrollSpeed: 750,
scrollOffset: 0,
scrollThreshold: 0.5,
begin: false,
end: false,
scrollChange: false
},
init: function () {
var self = this;
// Introduce defaults that can be extended either
// globally or using an object literal.
self.config = $.extend({}, self.defaults, self.options, self.metadata);
//Filter any links out of the nav
if (self.config.filter !== '') {
self.$nav = self.$nav.filter(self.config.filter);
}
//Handle clicks on the nav
self.$nav.on('click.onePageNav', $.proxy(self.handleClick, self));
//Get the section positions
self.getPositions();
//Handle scroll changes
self.bindInterval();
//Update the positions on resize too
self.$win.on('resize.onePageNav', $.proxy(self.getPositions, self));
return this;
},
adjustNav: function (self, $parent) {
self.$elem.find('.' + self.config.currentClass).removeClass(self.config.currentClass);
$parent.addClass(self.config.currentClass);
},
bindInterval: function () {
var self = this;
var docHeight;
self.$win.on('scroll.onePageNav', function () {
self.didScroll = true;
});
self.t = setInterval(function () {
docHeight = self.$doc.height();
//If it was scrolled
if (self.didScroll) {
self.didScroll = false;
self.scrollChange();
}
//If the document height changes
if (docHeight !== self.docHeight) {
self.docHeight = docHeight;
self.getPositions();
}
}, 250);
},
getHash: function ($link) {
return $link.attr('href').split('#')[1];
},
getPositions: function () {
var self = this;
var linkHref;
var topPos;
var $target;
self.$nav.each(function () {
linkHref = self.getHash($(this));
$target = $('#' + linkHref);
if ($target.length) {
topPos = $target.offset().top;
self.sections[linkHref] = Math.round(topPos) - self.config.scrollOffset;
}
});
},
getSection: function (windowPos) {
var returnValue = null;
var windowHeight = Math.round(this.$win.height() * this.config.scrollThreshold);
for (var section in this.sections) {
if ((this.sections[section] - windowHeight) < windowPos) {
returnValue = section;
}
}
return returnValue;
},
handleClick: function (e) {
var self = this;
var $link = $(e.currentTarget);
var $parent = $link.parent();
var newLoc = '#' + self.getHash($link);
if (!$parent.hasClass(self.config.currentClass)) {
//Start callback
if (self.config.begin) {
self.config.begin();
}
//Change the highlighted nav item
self.adjustNav(self, $parent);
//Removing the auto-adjust on scroll
self.unbindInterval();
//Scroll to the correct position
$.scrollTo(newLoc, self.config.scrollSpeed, {
axis: 'y',
easing: self.config.easing,
offset: {
top: -self.config.scrollOffset
},
onAfter: function () {
//Do we need to change the hash?
if (self.config.changeHash) {
window.location.hash = newLoc;
}
//Add the auto-adjust on scroll back in
self.bindInterval();
//End callback
if (self.config.end) {
self.config.end();
}
}
});
}
e.preventDefault();
},
scrollChange: function () {
var windowTop = this.$win.scrollTop();
var position = this.getSection(windowTop);
var $parent;
//If the position is set
if (position !== null) {
$parent = this.$elem.find('a[href$="#' + position + '"]').parent();
//If it's not already the current section
if (!$parent.hasClass(this.config.currentClass)) {
//Change the highlighted nav item
this.adjustNav(this, $parent);
//If there is a scrollChange callback
if (this.config.scrollChange) {
this.config.scrollChange($parent);
}
}
}
},
unbindInterval: function () {
clearInterval(this.t);
this.$win.unbind('scroll.onePageNav');
}
};
OnePageNav.defaults = OnePageNav.prototype.defaults;
$.fn.onePageNav = function (options) {
return this.each(function () {
new OnePageNav(this, options).init();
});
};
})(jQuery, window, document);
$(function () { // this is the shorthand for document.ready
$(window).scroll(function () { // this is the scroll event for the document
scrolltop = $(window).scrollTop(); // by this we get the value of the scrolltop ie how much scroll has been don by user
if (parseInt(scrolltop) >= 80) // check if the scroll value is equal to the top of navigation
{
$("#navbar").css({
"position": "fixed",
"top": "0"
}); // is yes then make the position fixed to top 0
} else {
$("#navbar").css({
"position": "absolute",
"top": "80px"
}); // if no then make the position to absolute and set it to 80
}
}); //here
}); //here

Categories

Resources