JavaScript + jQuery + Angular: Element is not found - javascript

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();
});

Related

How to disable method call if instance of object doesn't exist (javascript)

Is there a way to not call a method from the function object (instance of it) if that instance doesn't exist?
This is my function for sticky sidebar and it has 2 methods;
init() and updateSticky();
function stickySideBar(element, options = {}) {
var _this = this;
_this.init = function () {}
_this.updateSticky = function (timeout) {
//this is actually just a debouncer that calls init method
}
}
I want to use this updateSticky on window resize
$(window).on("resize", function () {
newsletterBlog.updateSticky();
sideBarBlog.updateSticky();
if ($(productsSticky.element).length > 0) {
productsSticky.updateSticky();
}
});
now I use if loop to check if an element exists but I would like to do that inside of the instance of that function
if i dont have if loop i get "Uncaught TypeError: e.updateSticky is not a function".
cheers
EDIT
here is the function
function stickySideBar(element, options = {}) {
var _this = this;
console.log("_this :>> ", _this);
//declared element
_this.debouncer;
_this.element = element;
if ($(_this.element).length === 0) {
return;
}
// declared options
_this.parentElementClass = options.parentElementClass;
_this.wrapClass = options.wrapClass;
_this.activeStickyClass = options.activeStickyClass;
_this.top = options.top;
_this.width = options.width;
_this.activeBottomClass = options.activeBottomClass;
_this.disableOnMobile = options.disableOnMobile ? options.disableOnMobile : true;
_this.breakpoint = 992;
_this.init = function () {
};
_this.updateSticky = function (timeout) {
if ($(_this.element).length === 0) return;
var timeoutVal = timeout ? timeout : 100;
clearTimeout(_this.debouncer);
_this.debouncer = setTimeout(function () {
_this.init();
}, timeoutVal);
};
return _this.init();
}

Appending DOM Loses Menu Drop Down Functionality

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

jquery object - function undefined error

In the following function, my objects inside floatShareBar function is undefined. Do I have to init or define a var before the functions? it throws me js error : .float - function undefined.
(function($) {
.
.
.
$("body").on("ab.snap", function(event) {
if (event.snapPoint >= 768) {
floatShareBar.float()
} else {
floatShareBar.unfloat();
}
});
var floatShareBar = function() {
var fShareBar = $('#article-share');
this.float = function() {
console.log(
};
this.unfloat = function() {
console.log("unfloat");
};
};
.
.
.
})(jQuery);
You need to get an instance of that function with a self instantiating call:
var floatShareBar = (function() {
var fShareBar = $('#article-share');
this.float = function() {
console.log('float');
};
this.unfloat = function() {
console.log("unfloat");
};
return this;
})();
UPDATE 1: I modified it to create an object within the function to attach those functions to, since in the previous example this refers to the window object
var floatShareBar = (function() {
var fShareBar = $('#article-share');
var instance = {};
instance.float = function() {
console.log('float');
};
instance.unfloat = function() {
console.log("unfloat");
};
return instance;
})();
UPDATE 2: You can actually just use the new keyword as well, look here for more info
var floatShareBar = new (function() {
var fShareBar = $('#article-share');
this.float = function() {
console.log('float');
};
this.unfloat = function() {
console.log("unfloat");
};
})();
Change you function to this:
$("body").on("ab.snap", function(event) {
if (event.snapPoint >= 768) {
(new floatShareBar()).float()
} else {
(new floatShareBar()).unfloat();
}
});
function floatShareBar () {
var fShareBar = $('#article-share');
this.float = function() {
console.log(
};
this.unfloat = function() {
console.log("unfloat");
};
};
you should declare functions when using var before you call them.

Trying to use a jQuery file in Wordpress, which requires noConflict, but now my Object [object Object] has no method

I'm trying to include stickem in a Wordpress theme I'm building. It is right here on GitHub, with a demo and some documentation: https://github.com/davist11/jQuery-Stickem
The .js file uses $, which is known to conflict in Wordpress, so I replaced every instance of $ with jQuery, and called jQuery.noConflict(); at the top.
Before I called noConflict, my error console told me "Uncaught TypeError: Property '$' of object [object Object] is not a function." Now that message has been replaced by "Uncaught TypeError: Object [object Object] has no method 'stickem'" and stickem still isn't working.
You can see my wordpress instance here:
http://lehuagray.com/trendsnap/
Here is my altered code:
jQuery.noConflict();
jQuery('.container').stickem({
item: '.stickem',
container: '.stickem-container',
stickClass: 'stickit',
endStickClass: 'stickit-end',
offset: 0,
onStick: null,
onUnstick: null
});
;(function(jQuery, window, document, undefined) {
var Stickem = function(elem, options) {
this.elem = elem;
this.jQueryelem = jQuery(elem);
this.options = options;
this.metadata = this.jQueryelem.data("stickem-options");
this.jQuerywin = jQuery(window);
};
Stickem.prototype = {
defaults: {
item: '.stickem',
container: '.stickem-container',
stickClass: 'stickit',
endStickClass: 'stickit-end',
offset: 0,
start: 0,
onStick: null,
onUnstick: null
},
init: function() {
var _self = this;
//Merge options
_self.config = jQuery.extend({}, _self.defaults, _self.options, _self.metadata);
_self.setWindowHeight();
_self.getItems();
_self.bindEvents();
return _self;
},
bindEvents: function() {
var _self = this;
_self.jQuerywin.on('scroll.stickem', jQuery.proxy(_self.handleScroll, _self));
_self.jQuerywin.on('resize.stickem', jQuery.proxy(_self.handleResize, _self));
},
destroy: function() {
var _self = this;
_self.jQuerywin.off('scroll.stickem');
_self.jQuerywin.off('resize.stickem');
},
getItem: function(index, element) {
var _self = this;
var jQuerythis = jQuery(element);
var item = {
jQueryelem: jQuerythis,
elemHeight: jQuerythis.height(),
jQuerycontainer: jQuerythis.parents(_self.config.container),
isStuck: false
};
//If the element is smaller than the window
if(_self.windowHeight > item.elemHeight) {
item.containerHeight = item.jQuerycontainer.outerHeight();
item.containerInner = {
border: {
bottom: parseInt(item.jQuerycontainer.css('border-bottom'), 10) || 0,
top: parseInt(item.jQuerycontainer.css('border-top'), 10) || 0
},
padding: {
bottom: parseInt(item.jQuerycontainer.css('padding-bottom'), 10) || 0,
top: parseInt(item.jQuerycontainer.css('padding-top'), 10) || 0
}
};
item.containerInnerHeight = item.jQuerycontainer.height();
item.containerStart = item.jQuerycontainer.offset().top - _self.config.offset + _self.config.start + item.containerInner.padding.top + item.containerInner.border.top;
item.scrollFinish = item.containerStart - _self.config.start + (item.containerInnerHeight - item.elemHeight);
//If the element is smaller than the container
if(item.containerInnerHeight > item.elemHeight) {
_self.items.push(item);
}
} else {
item.jQueryelem.removeClass(_self.config.stickClass + ' ' + _self.config.endStickClass);
}
},
getItems: function() {
var _self = this;
_self.items = [];
_self.jQueryelem.find(_self.config.item).each(jQuery.proxy(_self.getItem, _self));
},
handleResize: function() {
var _self = this;
_self.getItems();
_self.setWindowHeight();
},
handleScroll: function() {
var _self = this;
if(_self.items.length > 0) {
var pos = _self.jQuerywin.scrollTop();
for(var i = 0, len = _self.items.length; i < len; i++) {
var item = _self.items[i];
//If it's stuck, and we need to unstick it
if(item.isStuck && (pos < item.containerStart || pos > item.scrollFinish)) {
item.jQueryelem.removeClass(_self.config.stickClass);
//only at the bottom
if(pos > item.scrollFinish) {
item.jQueryelem.addClass(_self.config.endStickClass);
}
item.isStuck = false;
//if supplied fire the onUnstick callback
if(_self.config.onUnstick) {
_self.config.onUnstick(item);
}
//If we need to stick it
} else if(item.isStuck === false && pos > item.containerStart && pos < item.scrollFinish) {
item.jQueryelem.removeClass(_self.config.endStickClass).addClass(_self.config.stickClass);
item.isStuck = true;
//if supplied fire the onStick callback
if(_self.config.onStick) {
_self.config.onStick(item);
}
}
}
}
},
setWindowHeight: function() {
var _self = this;
_self.windowHeight = _self.jQuerywin.height() - _self.config.offset;
}
};
Stickem.defaults = Stickem.prototype.defaults;
jQuery.fn.stickem = function(options) {
//Create a destroy method so that you can kill it and call it again.
this.destroy = function() {
this.each(function() {
new Stickem(this, options).destroy();
});
};
return this.each(function() {
new Stickem(this, options).init();
});
};
})(jQuery, window , document);
Of course you can't use a function before it has been defined. Right now, your call to stickem is before the definition of stickem. You need to put your code inside a jQuery(function() { }); block to defer execution until the DOM is ready (which, as a side effect, also allows the stickem function to be defined before you attempt to use it.)
jQuery(function() {
jQuery('.container').stickem({
item: '.stickem',
container: '.stickem-container',
stickClass: 'stickit',
endStickClass: 'stickit-end',
offset: 0,
onStick: null,
onUnstick: null
});
});
Wrap your functions and jQuery code in this:
;(function ($) {
//Code in here
})(jQuery);
This assigns the $ to jQuery only. Doing this prevents conflicts with other libraries/code that also use the $. Also leading this code with a ; protects your function from unclosed scripts. I wouldn't rely on the noConflict() method.
<script type="text/javascript">
;(function ($, window, document, undefined) {
//You can do it like this too
//Make sure to replace all your 'jQuery' referecens to '$'
//jQuery.extend({}, _self.defaults, _self.options, _self.metadata)
$.extend({}, _self.defaults, _self.options, _self.metadata)
})(jQuery, window, document);
</script>
You need to use the no conflict mode only when you want to release $ for other libraries.
jQuery.noConflict();
// Release $ for other js libraries.
Try to wrap your jQuery code like so:
(function($) {
// Inside this function $ is jQuery
$(document).ready({
// jQuery code goes here.
})
})(jQuery);

problem with simple tween class in javascript

I'm trying to build a simple Tween class in javascript. The code reads something like:
function Tween(object, parameters) { // constructor-class def.
this.object = object;
this.parameters = parameters;
this.isRunning = true;
this.frameRate = some value;
this.timeElapsed = some value;
this.duration = some value;
}
Tween.prototype.drawFrame = function () {
var self = this;
this.nextFrame();
if (this.isRunning)
setTimeout( function () { self.drawFrame() } , 1000 / frameRate);
}
Tween.prototype.nextFrame = function () {
if (this.timeElapsed < this.duration) {
// calculate and update the parameters of the object
} else
this.isRunning = false;
}
Tween.prototype.start = function () {
this.isRunning = true;
this.drawFrame();
}
This is then called by another script, say main.js :
window.onload = init;
init = function() {
var tweenDiv = document.createElement('div');
tweenDiv.id = 'someDiv';
document.body.appendChild(tweenDiv);
var myTween = new Tween(document.getElementById('someDiv').style, 'left', parameters);
myTween.start();
}
Unfortunately, this doesnt work. If I examine my site with Google Chrome developer tools, someDiv has its left-style-attribute set to the number of pixels set in the parameters. But it doesn't move on the screen.
Anybody know what I'm doing wrong? Why isn't someDiv being redrawn?
Much Obliged
You have to set the position style to absolute, fixed or relative for the left style to have any effect.

Categories

Resources