someone have a an idea about lazy loading. It doesn't seems to work on my page.
I did something wrong ?
here is my page -> http://500milligrammes.com/fmzz/final/test.html
here is my html part:
<img class="lazy img-responsive" src="...jpg" data-original="...jpg" alt=""/>
here is my js part:
$(function() {
$("img.lazy").lazyload({
effect : "fadeIn"
});
here is my jquery.lazyload.js page:
/*!
* Lazy Load - jQuery plugin for lazy loading images
*
* Copyright (c) 2007-2015 Mika Tuupola
*
* Licensed under the MIT license:
* http://www.opensource.org/licenses/mit-license.php
*
* Project home:
* http://www.appelsiini.net/projects/lazyload
*
* Version: 1.9.5
*
*/
(function($, window, document, undefined) {
var $window = $(window);
$.fn.lazyload = function(options) {
var elements = this;
var $container;
var settings = {
threshold : 0,
failure_limit : 0,
event : "scroll",
effect : "show",
container : window,
data_attribute : "original",
skip_invisible : false,
appear : null,
load : null,
placeholder : "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC"
};
function update() {
var counter = 0;
elements.each(function() {
var $this = $(this);
if (settings.skip_invisible && !$this.is(":visible")) {
return;
}
if ($.abovethetop(this, settings) ||
$.leftofbegin(this, settings)) {
/* Nothing. */
} else if (!$.belowthefold(this, settings) &&
!$.rightoffold(this, settings)) {
$this.trigger("appear");
/* if we found an image we'll load, reset the counter */
counter = 0;
} else {
if (++counter > settings.failure_limit) {
return false;
}
}
});
}
if(options) {
/* Maintain BC for a couple of versions. */
if (undefined !== options.failurelimit) {
options.failure_limit = options.failurelimit;
delete options.failurelimit;
}
if (undefined !== options.effectspeed) {
options.effect_speed = options.effectspeed;
delete options.effectspeed;
}
$.extend(settings, options);
}
/* Cache container as jQuery as object. */
$container = (settings.container === undefined ||
settings.container === window) ? $window : $(settings.container);
/* Fire one scroll event per scroll. Not one scroll event per image. */
if (0 === settings.event.indexOf("scroll")) {
$container.bind(settings.event, function() {
return update();
});
}
this.each(function() {
var self = this;
var $self = $(self);
self.loaded = false;
/* If no src attribute given use data:uri. */
if ($self.attr("src") === undefined || $self.attr("src") === false) {
if ($self.is("img")) {
$self.attr("src", settings.placeholder);
}
}
/* When appear is triggered load original image. */
$self.one("appear", function() {
if (!this.loaded) {
if (settings.appear) {
var elements_left = elements.length;
settings.appear.call(self, elements_left, settings);
}
$("<img />")
.bind("load", function() {
var original = $self.attr("data-" + settings.data_attribute);
$self.hide();
if ($self.is("img")) {
$self.attr("src", original);
} else {
$self.css("background-image", "url('" + original + "')");
}
$self[settings.effect](settings.effect_speed);
self.loaded = true;
/* Remove image from array so it is not looped next time. */
var temp = $.grep(elements, function(element) {
return !element.loaded;
});
elements = $(temp);
if (settings.load) {
var elements_left = elements.length;
settings.load.call(self, elements_left, settings);
}
})
.attr("src", $self.attr("data-" + settings.data_attribute));
}
});
/* When wanted event is triggered load original image */
/* by triggering appear. */
if (0 !== settings.event.indexOf("scroll")) {
$self.bind(settings.event, function() {
if (!self.loaded) {
$self.trigger("appear");
}
});
}
});
/* Check if something appears when window is resized. */
$window.bind("resize", function() {
update();
});
/* With IOS5 force loading images when navigating with back button. */
/* Non optimal workaround. */
if ((/(?:iphone|ipod|ipad).*os 5/gi).test(navigator.appVersion)) {
$window.bind("pageshow", function(event) {
if (event.originalEvent && event.originalEvent.persisted) {
elements.each(function() {
$(this).trigger("appear");
});
}
});
}
/* Force initial check if images should appear. */
$(document).ready(function() {
update();
});
return this;
};
/* Convenience methods in jQuery namespace. */
/* Use as $.belowthefold(element, {threshold : 100, container : window}) */
$.belowthefold = function(element, settings) {
var fold;
if (settings.container === undefined || settings.container === window) {
fold = (window.innerHeight ? window.innerHeight : $window.height()) + $window.scrollTop();
} else {
fold = $(settings.container).offset().top + $(settings.container).height();
}
return fold <= $(element).offset().top - settings.threshold;
};
$.rightoffold = function(element, settings) {
var fold;
if (settings.container === undefined || settings.container === window) {
fold = $window.width() + $window.scrollLeft();
} else {
fold = $(settings.container).offset().left + $(settings.container).width();
}
return fold <= $(element).offset().left - settings.threshold;
};
$.abovethetop = function(element, settings) {
var fold;
if (settings.container === undefined || settings.container === window) {
fold = $window.scrollTop();
} else {
fold = $(settings.container).offset().top;
}
return fold >= $(element).offset().top + settings.threshold + $(element).height();
};
$.leftofbegin = function(element, settings) {
var fold;
if (settings.container === undefined || settings.container === window) {
fold = $window.scrollLeft();
} else {
fold = $(settings.container).offset().left;
}
return fold >= $(element).offset().left + settings.threshold + $(element).width();
};
$.inviewport = function(element, settings) {
return !$.rightoffold(element, settings) && !$.leftofbegin(element, settings) &&
!$.belowthefold(element, settings) && !$.abovethetop(element, settings);
};
/* Custom selectors for your convenience. */
/* Use as $("img:below-the-fold").something() or */
/* $("img").filter(":below-the-fold").something() which is faster */
$.extend($.expr[":"], {
"below-the-fold" : function(a) { return $.belowthefold(a, {threshold : 0}); },
"above-the-top" : function(a) { return !$.belowthefold(a, {threshold : 0}); },
"right-of-screen": function(a) { return $.rightoffold(a, {threshold : 0}); },
"left-of-screen" : function(a) { return !$.rightoffold(a, {threshold : 0}); },
"in-viewport" : function(a) { return $.inviewport(a, {threshold : 0}); },
/* Maintain BC for couple of versions. */
"above-the-fold" : function(a) { return !$.belowthefold(a, {threshold : 0}); },
"right-of-fold" : function(a) { return $.rightoffold(a, {threshold : 0}); },
"left-of-fold" : function(a) { return !$.rightoffold(a, {threshold : 0}); }
});
})(jQuery, window, document);
First Issue:
You need to close down the ready function.
$(function() {
$("img.lazy").lazyload({
effect : "fadeIn"
});
});
Second Issue:
Here is the usage on how to implement the lazy load on the site:
<img class="lazy" data-original="img/example.jpg" width="640" height="480">
Now with this you have to store it within a data attribute (the image itself). What you are doing is calling the image within the src and also within the data attribute. Now when the page loads, it actually starts the process of loading the images with src and then the lazy load happens.
I would recommend not to use an img tag as placeholder. The src attribute is mandatory and so you generate invalid HTML.
And I also wouldn't use jQuery for such a tiny functionality.
The following justlazy plugin provides valid HTML without jQuery.
1. Define a placeholder
<span data-src="default/image" data-alt="some alt text"
class="justlazy-placeholder">
</span>
2. Register lazy loading
$(function() {
Justlazy.registerLazyLoadByClass("justlazy-placeholder");
});
Related
The default behaviour of the discuss module in Odoo 9 is:
Last message at the bottom
Scrollbar at the bottom
I need to change this behaviour to:
Last message on top
Scrollbar on top
I think all this can be changed in odoo/addons/mail/static/src/js/thread.js
The order of messages is changed with:
init: function (parent, options) {
this._super.apply(this, arguments);
this.options = _.defaults(options || {}, {
//display_order: ORDER.ASC,
display_order: ORDER.DESC,
display_needactions: true,
display_stars: true,
display_document_link: true,
display_avatar: true,
shorten_messages: true,
squash_close_messages: true,
display_reply_icon: false,
});
this.expanded_msg_ids = [];
this.selected_id = null;
},
But then the user always has to scroll up so I also need to modify the behaviour of the scrollbar.
In this thread: Set scroll position I found it could be done with:
window.scrollTo(0, 0); // values are x,y-offset
or
var el = document.getElementById("myel"); // Or whatever method to get the element
// To set the scroll
el.scrollTop = 0;
el.scrollLeft = 0;
This is some code I found in odoo/addons/mail/static/src/js/thread.js:
/**
* Scrolls the thread to a given message or offset if any, to bottom otherwise
* #param {int} [options.id] optional: the id of the message to scroll to
* #param {int} [options.offset] optional: the number of pixels to scroll
*/
scroll_to: function (options) {
window.alert("In function scroll_to");
options = options || {};
if (options.id !== undefined) {
var $target = this.$('.o_thread_message[data-message-id=' + options.id + ']');
if (options.only_if_necessary) {
var delta = $target.parent().height() - $target.height();
var offset = delta < 0 ? 0 : delta - ($target.offset().top - $target.offsetParent().offset().top);
offset = - Math.min(offset, 0);
this.$el.scrollTo("+=" + offset + "px", options);
} else if ($target.length) {
this.$el.scrollTo($target);
}
} else if (options.offset !== undefined) {
this.$el.scrollTop(options.offset);
} else {
window.alert("55555555555");
window.alert("55555555555" + this.el.scrollHeight);
//this.$el.scrollTop(this.el.scrollHeight);
this.$el.scrollTop(20);
}
},
get_scrolltop: function () {
return this.$el.scrollTop();
},
is_at_bottom: function () {
window.alert("777777777777777");
return this.el.scrollHeight - this.$el.scrollTop() - this.$el.outerHeight() < 5;
},
unselect: function () {
this.$('.o_thread_message').removeClass('o_thread_selected_message');
this.selected_id = null;
},
});
I've put some alertboxes to see what happens when the page is loaded.
It seems it goes straight to the part with "5555555".
I've tried some changes there to adjust the scrollbar but nothing happens.
Does anyone have an idea on how to get the scrollbar on top as default?
Hi: Last message on top you can see this page:
Change message order in discuss odoo 9
I have test it at Odoo10 And it run well:
display_order set as DESC
init: function (parent, options) {
this._super.apply(this, arguments);
this.options = _.defaults(options || {}, {
display_order: ORDER.DESC,
},
through an friend's Help,Now I'm OK
share the code :
scroll_to: function (options) {
options = options || {};
if (options.id !== undefined) {
var $target = this.$('.o_thread_message[data-message-id="' + options.id + '"]');
if (options.only_if_necessary) {
var delta = $target.parent().height() - $target.height();
var offset = delta < 0 ? 0 : delta - ($target.offset().top - $target.offsetParent().offset().top);
offset = - Math.min(offset, 0);
this.$el.scrollTo("+=" + offset + "px", options);
} else if ($target.length) {
this.$el.scrollTo($target);
}
} else if (options.offset !== undefined) {
this.$el.scrollTop(options.offset);
} else {
// this.$el.scrollTop(this.el.scrollHeight);
this.$el.scrollTop();
console.log("flag 4");
}
},
I'm having some problems with the access of this methods and variables, and then i just got return undefined.
Im trying for example:
var slider = animateSlider();
slider.init();
slider.current;
I just want to have the access of all this function's value to manipulate the plugin with his callbacks.
(function($,window,document,undefined)
{
var Arrow = function (pages) {
this.pages = pages;
if(this.pages === 1) {
$('.prev').css({"opacity": "0", "z-index": "-1"});
} else {
$('.prev').css({"opacity": "1", "z-index": "1"});
}
if(this.pages < $('.anim-slider > .anim-slide').length) {
$('.next').css({"opacity": "1", "z-index": "1"});
} else {
$('.next').css({"opacity": "0", "z-index": "-1"});
}
};
/**
* [Create the contructor of animateSlider Plugin]
* #param {object} element [the element the plugin is chain to]
* #param {object} options [plugin's configuration object]
*/
var animateSlider = function(element,options)
{
this.element = element;
this.$element = $(element);
this.options = options;
};
animateSlider.prototype =
{
/**
* [Initialize the plugin]
*/
init : function()
{
//Use Modernizr
this.cssAnimations = Modernizr.cssanimations;
this.cssTransitions = Modernizr.csstransitions;
if (!this.cssAnimations || !this.cssTransitions)
{
throw new Error("Your broswer does not support CSS3 Animations or Transitions");
}
this.config = $.extend({},this.defaults,this.options);
this.slides = this.$element.children(".anim-slide");
this.slidesCount = this.slides.length;
this.interval = [];//Ovveride config.interval
this.current = 0; //first slide
$('.contador').html(parseInt(this.current + 1) + ' de ' + this.slidesCount);
var $dots = $("<div class=\"anim-dots\"></div>");
var temp = this.slidesCount;
while ( temp --)
{
$dots.append("<span></span>");
}
$dots.appendTo(this.$element);
this.slides.eq(this.current).addClass("anim-slide-this");
this.$dots = this.$element.find(".anim-dots>span");
this.$navNext = $(".anim-arrows-next");
this.$navPrev = $(".anim-arrows-prev");
this.loadEvents();
this.navigate(this.current);
this.updateDots();
this.autoplay();
},
/**
* [Go to current slide and set the proper classes to animate the elements]
* #param {number} page [current slide]
*/
navigate : function(page)
{
//Classes created from animate.css, you can add your own here.
var classes = 'bounce flash pulse rubberBand shake swing tada wobble bounceIn bounceInDown bounceInRight bounceInUp bounceOut bounceOutDown bounceOutLeft bounceOutRight bounceOutUp fadeIn fadeInDown fadeInDownBig fadeInLeft fadeInLeftBig fadeInRight fadeInRightBig fadeInUp fadeInUpBig fadeOut fadeOutDown fadeOutDownBig fadeOutLeft fadeOutLeftBig fadeOutRight fadeOutRightBig fadeOutUp fadeOutUpBig flipInX flipInY flipOutX flipOutY lightSpeedIn lightSpeedOut rotateIn rotateInDownLeft rotateInDownRight rotateInUpLeft rotateInUpRight rotateOut rotateOutDownLeft rotateOutDownRight rotateOutUpLeft rotateOutUpRight slideInDown slideInLeft slideInRight slideOutLeft slideOutRight slideOutUp slideInUp slideOutDown hinge rollIn rollOut fadeInUpLarge fadeInDownLarge fadeInLeftLarge fadeInRightLarge fadeInUpLeft fadeInUpLeftBig fadeInUpLeftLarge fadeInUpRight fadeInUpRightBig fadeInUpRightLarge fadeInDownLeft fadeInDownLeftBig fadeInDownLeftLarge fadeInDownRight fadeInDownRightBig fadeInDownRightLarge fadeOutUpLarge fadeOutDownLarge fadeOutLeftLarge fadeOutRightLarge fadeOutUpLeft fadeOutUpLeftBig fadeOutUpLeftLarge fadeOutUpRight fadeOutUpRightBig fadeOutUpRightLarge fadeOutDownLeft fadeOutDownLeftBig fadeOutDownLeftLarge fadeOutDownRight fadeOutDownRightBig fadeOutDownRightLarge bounceInBig bounceInLarge bounceInUpBig bounceInUpLarge bounceInDownBig bounceInDownLarge bounceInLeft bounceInLeftBig bounceInLeftLarge bounceInRightBig bounceInRightLarge bounceInUpLeft bounceInUpLeftBig bounceInUpLeftLarge bounceInUpRight bounceInUpRightBig bounceInUpRightLarge bounceInDownLeft bounceInDownLeftBig bounceInDownLeftLarge bounceInDownRight bounceInDownRightBig bounceInDownRightLarge bounceOutBig bounceOutLarge bounceOutUpBig bounceOutUpLarge bounceOutDownBig bounceOutDownLarge bounceOutLeftBig bounceOutLeftLarge bounceOutRightBig bounceOutRightLarge bounceOutUpLeft bounceOutUpLeftBig bounceOutUpLeftLarge bounceOutUpRight bounceOutUpRightBig bounceOutUpRightLarge bounceOutDownLeft bounceOutDownLeftBig bounceOutDownLeftLarge bounceOutDownRight bounceOutDownRightBig bounceOutDownRightLarge zoomIn zoomInUp zoomInUpBig zoomInUpLarge zoomInDown zoomInDownBig zoomInDownLarge zoomInLeft zoomInLeftBig zoomInLeftLarge zoomInRight zoomInRightBig zoomInRightLarge zoomInUpLeft zoomInUpLeftBig zoomInUpLeftLarge zoomInUpRight zoomInUpRightBig zoomInUpRightLarge zoomInDownLeft zoomInDownLeftBig zoomInDownLeftLarge zoomInDownRight zoomInDownRightBig zoomInDownRightLarge zoomOut zoomOutUp zoomOutUpBig zoomOutUpLarge zoomOutDown zoomOutDownBig zoomOutDownLarge zoomOutLeft zoomOutLeftBig zoomOutLeftLarge zoomOutRight zoomOutRightBig zoomOutRightLarge zoomOutUpLeft zoomOutUpLeftBig zoomOutUpLeftLarge zoomOutUpRight zoomOutUpRightBig zoomOutUpRightLarge zoomOutDownLeft zoomOutDownLeftBig zoomOutDownLeftLarge zoomOutDownRight zoomOutDownRightBig zoomOutDownRightLarge flipInTopFront flipInTopBack flipInBottomFront flipInBottomBack flipInLeftFront flipInLeftBack flipInRightFront flipInRightBack flipOutTopFront flipOutTopBack flipOutBottomFront flipOutBottomback flipOutLeftFront flipOutLeftBack flipOutRightFront flipOutRightBack strobe shakeX shakeY spin spinReverse slingshot slingshotReverse pulsate heartbeat panic';
var classShow,classHide,delayShow,$next,$current,currentAnimate,nextAnimate;
$current = this.slides.eq(this.current);
currentAnimate = this.elemAnimate(this.current,this.config);
this.current = page;
$next = this.slides.eq(this.current);
nextAnimate = this.elemAnimate(this.current,this.config);
/*=========================================*/
$current.removeClass(" anim-slide-this "+classes);
$current.find("*").removeClass(classes);
//Iterate through a javascript plain object of current and next Slide
$.each(currentAnimate,function(index)
{
if ( index == $current.prop("tagName").toLowerCase() )
{
classHide = $current.data("classHide");
delayShow = $current.data("delayShow");
$current.removeClass(delayShow);
$current.addClass(classHide+" animated");
return false;
}
else
{
classHide = $current.find(index).data("classHide");
delayShow = $current.find(index).data("delayShow");
$current.find(index).removeClass(delayShow);
$current.find(index).addClass(classHide+" animated");
}
});
$.each(nextAnimate,function(index)
{
if ( index == $current.prop("tagName").toLowerCase() )
{
classShow = $next.data("classShow") ;
delayShow = $next.data("delayShow");
$next.removeClass(classes);
$next.addClass(classShow+" "+delayShow+" animated");
return false;
}
else
{
classShow = $next.find(index).data("classShow");
delayShow = $next.find(index).data("delayShow");
$next.find(index).removeClass(classes);
$next.find(index).addClass(classShow+" "+delayShow+" animated ");
}
});
$next.addClass(" anim-slide-this");
/*=========================================*/
this.updateDots();
},
/**
* [Update the dots to the current slide]
*/
updateDots : function()
{
this.$dots.removeClass("anim-dots-this");
this.$dots.eq(this.current).addClass("anim-dots-this");
},
/**
* [If the dots are clicked the autoplay procedure stops
* and you navigate to the current slide]
* #param {number} page [current slide]
*/
dots : function(page)
{
if ( page >= this.slidesCount || page < 0)
{
return false;
}
if (this.config.autoplay)
{
clearTimeout(this.autoplay);
this.config.autoplay = false;
}
this.navigate(page);
},
/**
* [Get the configuration object for each slide element and attach it to elements with $.data]
* #param {number} page [current slide]
* #param {object} config [configuration object]
*/
elemAnimate : function(page,config)
{
if ( typeof config.animations == "object" )
{
if ( this.slidesCount !== Object.keys(config.animations).length )
{
throw new SyntaxError("Slides length and animation Object length must be equal.");
}
//Get the selected Slide configuration object
var animations = config.animations[page];
var $current = this.slides.eq(page);
return $.each(animations,function(index,value)
{
if ( index == $current.prop("tagName").toLowerCase() )
{
if ( $current.data("classShow") == null )
{
if ( typeof value.show === "string" ) { $current.data("classShow",value.show); } else { $current.data("classShow",""); }
if ( typeof value.hide === "string" ) { $current.data("classHide",value.hide); } else { $current.data("classHide",""); }
if ( typeof value.delayShow === "string" ) { $current.data("delayShow",value.delayShow); } else { $current.data("delayShow"," "); }
}
return false;
}
else
{
if ( !$current.find(index)[0] )
{
throw new TypeError("The element \'"+index+"\' does not exist.");
}
if ( $current.find(index).data("classShow") == null )
{
if( typeof value.show === "string" ) { $current.find(index).data("classShow",value.show); } else { $current.find(index).data("classShow"," "); }
if( typeof value.hide === "string" ) { $current.find(index).data("classHide",value.hide); } else { $current.find(index).data("classHide"," "); }
if( typeof value.delayShow === "string" ) { $current.find(index).data("delayShow",value.delayShow); } else { $current.find(index).data("delayShow"," "); }
}
}
});
}
},
/**
* [Call the animDuration for each slide and if the animation time of current slide is bigger than
* config.interval replace it with this.inteval, else leave config.interval with the default value]
*/
autoplay : function()
{
if (this.config.autoplay)
{
var page = this.current;
var that = this;
var loop = function()
{
page = ( page >= that.slidesCount -1 || page < 0 ) ? 0 : page + 1;
that.navigate(page);
that.autoplay();
};
if ( this.interval.length === this.slidesCount )
{
this.autoplayTime = setTimeout(loop,this.interval[page]);
return;
}
this.animDuration(page).done(function(animationTime)
{
if( animationTime >= that.config.interval )
{
that.interval[page] = animationTime;
that.autoplayTime = setTimeout(loop,0);
}
else if( animationTime < that.config.interval )
{
that.interval[page] = that.config.interval;
that.autoplayTime = setTimeout(loop,that.config.interval-animationTime);
}
});
}
},
/**
* [Find the total animation time for the current slide]
* #param {number} page [current slide]
* #return {object} promise [jQuery's Promises to make asynchronous call]
*/
animDuration: function(page)
{
var $slideAnimations = this.slides.eq(page);
var slideAnimationsCount = $slideAnimations.children("*.animated").length;
var animationStart = +new Date();
var promise = new $.Deferred();
var animationTime,count = 0;
$slideAnimations.on("animationend webkitAnimationEnd oanimationend MSAnimationEnd",function()
{
var animationEnd = +new Date();
animationTime = Math.ceil((animationEnd -animationStart)/1000)*1000;
count++;
if (count == slideAnimationsCount)
{
promise.resolve(animationTime);
}
});
return promise;
},
/**
* [Attach events handlers to specific tasks]
*/
loadEvents : function()
{
var that = this;
this.$navNext.on("click",function(event)
{
if(parseInt(that.current + 1) < that.slidesCount) {
if (that.config.autoplay)
{
clearTimeout(that.autoplay);
that.config.autoplay = false;
}
var page = (that.current >= that.slidesCount - 1 ) ? 0 : that.current + 1 ;
that.navigate(page,"next");
Arrow(parseInt(page + 1));
// contador de paginas
$('.contador').html(parseInt(page + 1) + ' de ' + that.slidesCount);
}
event.preventDefault();
});
this.$navPrev.on("click",function(event)
{
if(parseInt(that.current + 1) !== 1) {
if (that.config.autoplay)
{
clearTimeout(that.autoplay);
that.config.autoplay = false;
}
var page = ( that.current === 0 )? that.slidesCount - 1 : that.current - 1;
that.navigate(page,"prev");
Arrow(parseInt(page + 1));
// contador de paginas
$('.contador').html(parseInt(page + 1) + ' de ' + that.slidesCount);
}
event.preventDefault();
});
this.$dots.on("click.slide",function(event)
{
var page = $(this).index();
that.dots(page);
event.preventDefault();
});
},
defaults :
{
autoplay : true,
interval : 5000
}
};
/**
* [Attach the plugin to jQuery's prototype]
* #param {object} options [plugin's configuration object]
* #return {object} this [the jQuery wrapper]
*/
$.fn.animateSlider = function(options)
{
return this.each(function()
{
var instance = $.data(this,"animateSlider");
if (!instance)
{
$.data(this,"animateSlider",new animateSlider(this,options).init());
}
});
};
})(jQuery);
The plugin you are trying to use is this.
README file clearly mentions how to use the plugin.
$(<jquerySelector>).animateSlider();
You cannot just pick and choose the functions you want to access from an IIFE unless it puts variables onto the global scope in case of jquery plugins they usually attach themselves onto the $ scope via $.fn in this case $.fn.animateSlider which means you can only access them via the above syntax.
But if you adamant on accessing variables inside an IIFE.
I will give the steps to access Arrow variable:
Change var Arrow = function (pages) { to Arrow = function (pages).
In main js file. Create an Instance var obj_name = new Arrow(1);
Though I cant think of why you would want to do that and if this is the only way then your design is wrong.
I'm trying to use the jQuery appear plugin. I'm having trouble making it work. I tried to attach it to the (window).scroll event but it makes the page slow. If I don't use the scroll, it only fires once. I need it to work again whenever the element becomes visible. Can you give me some tips on how to make it work.
Here's my code:
jQuery('.home-section-1').appear(function(){
jQuery('.page-scroll-indicator .fa.fa-circle').removeClass('active-ind');
jQuery('.page-scroll-indicator .section-1').addClass('active-ind');
});
As ɴ-ᴀ-ᴛ-ʜ said in his comment, you need to be using .on to listen for the appear event.
jQuery('.home-section-1').on('appear', function(){
jQuery('.page-scroll-indicator .fa.fa-circle').removeClass('active-ind');
jQuery('.page-scroll-indicator .section-1').addClass('active-ind');
});
Here's a code snippit showing it working, you'll notice that your method (Method 1) doesn't fire, while the method above (Method 2) does:
/*
* jQuery appear plugin
*
* Copyright (c) 2012 Andrey Sidorov
* licensed under MIT license.
*
* https://github.com/morr/jquery.appear/
*
* Version: 0.3.4
*/
(function($) {
var selectors = [];
var check_binded = false;
var check_lock = false;
var defaults = {
interval: 250,
force_process: false
}
var $window = $(window);
var $prior_appeared;
function process() {
check_lock = false;
for (var index = 0, selectorsLength = selectors.length; index < selectorsLength; index++) {
var $appeared = $(selectors[index]).filter(function() {
return $(this).is(':appeared');
});
$appeared.trigger('appear', [$appeared]);
if ($prior_appeared) {
var $disappeared = $prior_appeared.not($appeared);
$disappeared.trigger('disappear', [$disappeared]);
}
$prior_appeared = $appeared;
}
}
// "appeared" custom filter
$.expr[':']['appeared'] = function(element) {
var $element = $(element);
if (!$element.is(':visible')) {
return false;
}
var window_left = $window.scrollLeft();
var window_top = $window.scrollTop();
var offset = $element.offset();
var left = offset.left;
var top = offset.top;
if (top + $element.height() >= window_top &&
top - ($element.data('appear-top-offset') || 0) <= window_top + $window.height() &&
left + $element.width() >= window_left &&
left - ($element.data('appear-left-offset') || 0) <= window_left + $window.width()) {
return true;
} else {
return false;
}
}
$.fn.extend({
// watching for element's appearance in browser viewport
appear: function(options) {
var opts = $.extend({}, defaults, options || {});
var selector = this.selector || this;
if (!check_binded) {
var on_check = function() {
if (check_lock) {
return;
}
check_lock = true;
setTimeout(process, opts.interval);
};
$(window).scroll(on_check).resize(on_check);
check_binded = true;
}
if (opts.force_process) {
setTimeout(process, opts.interval);
}
selectors.push(selector);
return $(selector);
}
});
$.extend({
// force elements's appearance check
force_appear: function() {
if (check_binded) {
process();
return true;
};
return false;
}
});
})(jQuery);
// Your method
jQuery('.home-section-1').appear(function(){
alert('Method 1');
});
// Using .on
jQuery('.home-section-1').on('appear', function(){
alert('Method 2');
});
.home-section-1 {
margin-top: 2000px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="home-section-1">Hello World</div>
I'm having a few problems with my portfolio - if/when viewed on an iPad in vertical orientation, scrolling down seems to pull you back to the top. I'm not entirely sure if this is a css/js issue, or something else entirely. Resizing the browser on my computer to the same dimensions doesn't appear to replicate the problem so.. at a bit of a loss.
Has anyone encountered this issue?
Problem site in question:
http://alexandermasters.com/portfolio/weddings/20110827
This is an edited version of the theme template (template was designed strictly to scroll horizontally) but on the pages with the template untouched (http://alexandermasters.com/portfolio/travel/20100928) the issue persists.
Suggestions?
Edit: the offending code (within main.js) is below:
;(function ($, window, $window, $document, isUndefined) {
$(function () {
var $html = $('html'),
$main = $('#main'),
$header = $('#header'),
$footer = $('#footer'),
// Components
$sidebar = $('.sidebar'),
$keyRight = $('#key-right'),
$keyLeft = $('#key-left'),
$navTip = $('.nav-tip'),
$scrollContainer = $('.scroll-container'),
mobileNav,
// Functions
getHorizontalPageHeight,
pageResizer,
// Gloal variables
allowUpscale = $html.is('.upscale');
if (iPadWithIOS4()) {
$html.addClass('ipad-ios4');
}
getHorizontalPageHeight = function () {
return $window.height() - $header.outerHeight() - $footer.outerHeight();
};
/**
* Fixes iOS 7.0~7.0.2 Safari bug. Safari reports $window.height() to be 692, which is not correct.
* Also there's a permanent scrollbar which allows users to scroll 20px, to prevent that we just scroll back to the
* top. This is only required in landscape mode.
*/
if (!!navigator.platform.match(/iPad/) && $html.is('.horizontal-page')) {
var _getHorizontalPageHeight = getHorizontalPageHeight,
IOS7PreventVerticalScroll = function () {
if ($(window).scrollTop() > 0) {
$('body').animate({ scrollTop: 0 }, 200);
}
};
getHorizontalPageHeight = function () {
if ($window.height() == 692) {
return window.innerHeight - $header.outerHeight() - $footer.outerHeight();
}
return _getHorizontalPageHeight();
};
$document.on('scroll', _.debounce(IOS7PreventVerticalScroll, 100));
$window.on('orientationchange.ios7-safari-bug.fluxus', function () {
setTimeout(function () {
if ($window.height() == 692) {
IOS7PreventVerticalScroll();
}
}, 200);
});
}
$('.horizontal-page').each(function () {
var resizer = function () {
var windowWidth = $window.width(),
windowHeight = $window.height(),
// The header is position:fixed we have to calculate the offset for main page dynamically.
headerHeight = $header.outerHeight();
footerHeight = $footer.outerHeight();
// If we are on a small screen
if (windowWidth <= 480) {
if ($html.is('.no-scroll')) {
$main.css({
height: windowHeight - headerHeight,
top: 0
});
} else {
$main.css({
height: 'auto',
top: 0
});
}
} else {
$main.css({
height: getHorizontalPageHeight(),
top: headerHeight
});
}
};
$window.on('resize.horizontal-page.fluxus', _.debounce(resizer));
resizer();
$window.on('orientationchange.horizontal-page.fluxus', function () {
setTimeout(resizer, 10);
});
$main.transition({
opacity: 1
}, 100);
});
/**
* General size adjustments on window resize.
*/
pageResizer = function () {
/**
* Update tinyscrollbar values.
*/
$scrollContainer.each(function () {
var $t = $(this),
tsb = $t.data('tsb');
$t.find('.scrollbar, .track').css('height', $t.height());
tsb && tsb.update();
});
if ($window.width() <= 768) {
// Initialize mobile menu only if we have a small sceen size.
if (!mobileNav) {
// Make mobile menu item array.
var $siteNavigation = $('.site-navigation'),
$mobileNavItems = $siteNavigation.find('a').filter(function () {
var $t = $(this),
level = $t.parents('ul').length;
$t.data('level', level);
if (level == 1) {
return true;
} else {
if ($t.closest('.current-menu-item, .current_page_ancestor').length) {
return true;
}
}
return false;
});
/**
* Initialize mobile menu.
*/
mobileNav = new MobileNav($mobileNavItems, {
openButtonTitle: $siteNavigation.data('menu'),
active: $siteNavigation.find('.current-menu-item > a')
});
}
}
/**
* Trigger vertical center plugin.
*/
setTimeout(function () {
$('.js-vertical-center').verticalCenter();
}, 100);
};
$window.on('resize.page-resizer.fluxus', _.debounce(pageResizer));
pageResizer();
/**
* Arrows and mousewheel navigation plugin.
*/
globalNav = new Navigation({
onSetItems: function () {
this.$items.length && $navTip.show();
}
});
/**
* Full page slider
*/
$('.slider').each(function () {
var $slider = $(this),
slider;
$slider.fluxusSlider({
onNextSlide: function () {
globalNav.options.onNextItem();
},
onPreviousSlide: function () {
globalNav.options.onPreviousItem();
}
});
slider = $slider.data('slider');
slider.slideCount > 1 && $navTip.show();
globalNav.disableKeyboard();
$keyRight.click(function (e) {
slider.next();
e && e.preventDefault();
});
$keyLeft.click(function (e) {
slider.previous();
e && e.preventDefault();
});
});
/**
* Appreciate plugin
*/
var $appreciate = $('.btn-appreciate');
$appreciate.appreciate();
/**
* Sharrre plugin
*/
$('#sharrre-footer').each(function () {
var $el = $(this),
services = {},
buttonsTitle = $el.data('buttons-title');
if (!$el.data('services')) {
return;
}
// retrieve social networks from DOM element.
$.each($el.data('services').split(','), function () {
services[this] = true;
});
$el.sharrre({
share: services,
buttonsTemplate: buttonsTitle ? '<b>' + buttonsTitle + '</b>' : '',
urlCurl: $el.data('curl'),
template: '<b class="share">{title}</b>' +
'<span class="counts">' +
(services.facebook ? '<b class="count-facebook">{facebook}</b>' : '') +
(services.twitter ?'<b class="count-twitter">{twitter}</b>' : '') +
(services.googlePlus ?'<b class="count-plus">{plus}</b>' : '') +
'</span>',
render: function(self, options) {
var html = this.template.replace('{title}', options.title);
html = html.replace('{facebook}', options.count.facebook);
html = html.replace('{twitter}', options.count.twitter);
html = html.replace('{plus}', options.count.googlePlus);
$(self.element).html(html);
$el.show();
}
});
});
$('#sharrre-project').each(function () {
var $el = $(this),
services = {},
buttonsTitle = $el.data('buttons-title');
if (!$el.data('services')) {
return;
}
// retrieve social networks from DOM element.
$.each($el.data('services').split(','), function () {
services[this] = true;
});
$el.sharrre({
share: services,
buttonsTemplate: buttonsTitle ? '<div class="arrow"></div><b>' + buttonsTitle + '</b>' : '',
urlCurl: $el.data('curl'),
template: '<span class="icon"></span><div class="box">' +
'<a class="share" href="#">{title}</a>' +
'<b class="count-total">{total}</b>' +
'</div>',
render: function(self, options) {
var total = options.shorterTotal ? self.shorterTotal(options.total) : options.total,
html = this.template.replace('{title}', options.title).replace('{total}', total);
$(self.element).html(html);
$el.css('display', 'inline-block');
},
afterLoadButtons: function () {
var index = 0,
$buttons = this.$el.find('.button'),
count = $buttons.each( function () {
index++;
$(this).addClass('button-' + index);
}).length;
this.$el.addClass('social-services-' + count);
}
});
});
/**
* Fixes menu issue, when popup is outside the screen.
*/
$('.site-navigation .has-children').hover(function () {
var $submenu = $(this).children('.sub-menu');
if ($submenu.length) {
// if popup is outside the screen, then align it by the right side of the screen.
if ($submenu.offset().left + $submenu.outerWidth() - $(document).scrollLeft() > $window.width()) {
$submenu.addClass('sub-menu-right');
}
}
}, function () {
$(this).children('.sub-menu').removeClass('sub-menu-right');
});
/**
* If our page has a horizontal layout.
*/
if ($html.is('.horizontal-page')) {
/**
* Enable tinyscrollbar plugin.
*/
$scrollContainer.tinyscrollbar({
axis: 'y'
});
/**
* Enable keyboard navigation.
*/
globalNav.options.onNextItem = function () {
$keyRight.addClass('flash');
setTimeout(function () {
$keyRight.removeClass('flash');
}, 200);
};
globalNav.options.onPreviousItem = function () {
$keyLeft.addClass('flash');
setTimeout(function () {
$keyLeft.removeClass('flash');
}, 200);
};
$keyRight.click(function (e) {
globalNav.nextItem();
e && e.preventDefault();
});
$keyLeft.click(function (e) {
globalNav.previousItem();
e && e.preventDefault();
});
}
According to Intheme, the author of the Fluxus Template, the following fix has been released that should solve the issue.
By modifying the following line of code in js/main.js
if (!!navigator.platform.match(/iPad/)) {
to this
if (!!navigator.platform.match(/iPad/) && $html.is('.horizontal-page')) {
For some reason my gallery isn't working on Mobile devices including iPad, works fine on desktop. Instead of allowing a user to click through, all images appear stacked. The link to my site. The code is
located here
// scroll gallery init
function initCarousel() {
var isTouchDevice = /MSIE 10.*Touch/.test(navigator.userAgent) || ('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch;
jQuery('div.view-gallery').scrollGallery({
mask: 'div.frame',
slider: '>ul',
slides: '>li',
btnPrev: 'a.btn-prev',
btnNext: 'a.btn-next',
pagerLinks: '.pagination li',
circularRotation: false,
autoRotation: false,
switchTime: 3000,
animSpeed: 500,
onInit: function(obj){
obj.resizeFlag = true;
obj.win = jQuery(window);
//obj.win.unbind('resize orientationchange load', obj.onWindowResize);
obj.resizeSlides = function(){
obj.slideOffset = obj.slides.eq(0).outerWidth(true) - obj.slides.eq(0).width();
if(!obj.resizeFlag) obj.slides.css({width: ''});
else obj.slides.css({width: obj.mask.width()/2 - obj.slideOffset});
obj.calculateOffsets();
obj.refreshPosition();
obj.refreshState();
}
if(isTouchDevice){
ResponsiveHelper.addRange({
'..767': {
on: function(){
setTimeout(function(){
obj.resizeFlag = true;
obj.resizeSlides();
obj.win.bind('resize orientationchange load', obj.resizeSlides);
}, 100);
}
},
'768..': {
on: function(){
obj.resizeFlag = false;
obj.win.unbind('resize orientationchange load', obj.resizeSlides);
obj.resizeSlides();
}
}
});
}
}
});
jQuery('.scrollable-gallery').scrollableGallery();
}
/*
* scrollableGallery
*/
;(function($) {
function ScrollableGallery(options) {
this.options = {
scrollableArea: '.frame',
listItems: '.list-items',
btnPrev: '.btn-prev',
btnNext: '.btn-next',
animSpeed: 500
}
$.extend(this.options, options);
this.init();
}
ScrollableGallery.prototype = {
init: function() {
this.findElements()
this.setStructure();
this.addEvents();
},
findElements: function() {
this.holder = $(this.options.holder);
this.scrollableArea = this.holder.find(this.options.scrollableArea);
this.listItems = this.scrollableArea.find(this.options.listItems);
this.items = this.listItems.children();
this.lastItem = this.items.last();
this.btnPrev = this.holder.find(this.options.btnPrev);
this.btnNext = this.holder.find(this.options.btnNext);
this.scrollAPI = new jcf.modules.customscroll({
replaces: this.scrollableArea[0]
});
},
setStructure: function() {
var that = this;
if (that.listItems.css('position') === 'static') {
that.listItems.css('position', 'relative');
}
setTimeout(function() {
that.refreshState();
}, 50);
},
refreshState: function() {
this.listItems.css('width', 32700);
this.listItems.css('width', this.lastItem.position().left + this.lastItem.outerWidth(true) + 1);
this.scrollableArea.add(this.scrollableArea.parent()).css({
width: '',
height: ''
});
this.scrollAPI.refreshState();
},
addEvents: function() {
var that = this;
that.btnPrev.bind('click', function(e) {
e.preventDefault();
that.prevSlide();
});
that.btnNext.bind('click', function(e) {
e.preventDefault();
that.nextSlide();
});
win.bind('resize orientationchange load', function() {
that.refreshState();
});
},
nextSlide: function() {
var that = this;
var curPos = this.scrollableArea.scrollLeft();
var pos;
for (var i = 0; i < that.items.length; i++) {
pos = that.items.eq(i).position().left;
if (pos > curPos) {
that.scrollAnimate(curPos, pos);
break;
}
}
},
prevSlide: function() {
var that = this;
var curPos = this.scrollableArea.scrollLeft();
var pos;
for (var i = that.items.length - 1; i >= 0; i--) {
pos = that.items.eq(i).position().left;
if (pos < curPos) {
that.scrollAnimate(curPos, pos);
break;
}
}
},
scrollAnimate: function(from, to) {
var that = this;
var start = new Date().getTime();
setTimeout(function() {
var now = (new Date().getTime()) - start;
var progress = now / that.options.animSpeed;
var result = (to - from) * progress + from;
that.scrollAPI.hScrollBar.scrollTo(result);
if (progress < 1) {
setTimeout(arguments.callee, 10);
} else {
that.scrollAPI.hScrollBar.scrollTo(to);
}
}, 10);
}
}
var win = $(window);
$.fn.scrollableGallery = function(options) {
return this.each(function() {
if (!$(this).data('ScrollableGallery')) {
$(this).data('ScrollableGallery', new ScrollableGallery($.extend({}, {holder: this}, options)));
}
});
}
}(jQuery));
After looking through your code, there were numerous errors with syntax. I have cleaned them up as best as I could, this should help you out.
http://jsfiddle.net/wvWrY/1/
For example, this area was missing a semicolon (no way to call the findElements function, as JS will simply skip to the next line without a semicolon there.)
init: function() {
this.findElements()
this.setStructure();
this.addEvents();
Run your code through a linter, it will greatly improve your syntax structure and ensure little leave out errors like semicolons and commas and brackets aren't omitted.
EDIT: Ok, having looked at your code it appears this is actually due to the !importants in your allmobile.css file. The width and height are set to max-width: 100% (this breaks it because the way the slider works is to extend the gallery as far off screen as possible) and the height to auto (this breaks it because it allows the images to just keep piling on). Once you remove those for the page, it become much much much better and actually works.