Как заставить animatescroll.js работать в Phonegap/Cordova/AppBuilder
Я пытался заставить animScroll.js Рама Сварупа работать с AppBuilder от Telerik.
Мне нужно хорошее детальное управление animateScroll, такое как обработка событий до и после прокрутки, замедление анимации и управляемая скорость прокрутки (!). Тем не менее, независимо от того, что я делаю, поведение прокрутки на самом деле не произойдет, даже несмотря на то, что код анимации jquery, выполняющий работу (строка 162) в animateScroll , похоже, запускается настолько близко, насколько я могу судить, работая с console.log.,
Чтобы понять, какое поведение мне нужно, это метод animatescroll, в котором вы прокручиваете существующий элемент, а не поведение по умолчанию прокрутки всей страницы. Прокрутка внутри элемента достигается путем обращения к содержащему элементу в качестве параметра. По сути, этот подход превращает произвольное содержащее div в "скроллер", и его можно увидеть в демоверсии под разделом параметров.
У меня большой проект appbuilder, поэтому я сделал практически пустой проект appbuilder из демонстрационных шаблонов Telerik, и я получил тот же результат. Я предполагаю, что эта проблема также затронет телефон и Кордову, поскольку они очень и очень похожи. Если кто-нибудь сможет помочь с этим, я сделаю все возможное, чтобы представить измененную версию под той же лицензией MIT в различные каталоги плагинов cordova/phonegap. Это действительно хороший скроллер - если я смогу заставить его работать в контексте гибридного мобильного приложения.
Любые предложения или помощь приветствуются. Далее следует HTML-код из неработающего демонстрационного проекта, а затем полный исходный код плагина animatescroll.
Спасибо Дэйв Гердинг
<div data-role="view" data-title="Home" data-layout="main" data-model="APP.models.home">
<h1 data-bind="html: title"></h1>
<div>
For Example:<br />
<div id="element-demo">
<p>
<button onclick="$('#last-paragraph').animatescroll({element:'#element-demo',padding:20});">Click here</button> to scroll to the last paragraph within this "div" element
</p>
<p>
This "div" element has a class-name "element-demo" which is the value passed for "element" option while calling the plugin.
</p>
<p>
Compzets.com is India's first open source software and freeware publishing site, Download and Upload Open source software and Freeware relevant to the Paid ones for PC,Mac and Linux.
</p>
<p>
It also makes its own Cloud Applications for making tasks easy. Recently it has launched a new Plugin Showcase too.
</p>
<p>
This website is your source of unprecedented access to all kinds of pc,mac or linux software (Open Source or Freeware only) with detailed coverage of tech infos along with multiple screen shots and moreover you can not only download your favorite gadgets but you can also UPLOAD your own software to reach thousand of audience. Stay connected to all the latest happenings in the gadget world,with regular updates on new software and announcements with the help of our RSS Feed,just at a few clicks!
</p>
<p id="last-paragraph">
The word "Compzets" does not have a literal meaning,it is just derived from the word Gadget which is related to Electronic devices where as Compzets is related to Computer software which are nothing but gadgets for computer.
</p>
<p>
Thanks to <a href="https://plus.google.com/114685591029748634833" target="_blank">Ronan DMP</a> for asking this feature!
</p>
</div>
</div>
И код плагина animatescroll для Ram:
/*
* @build : 20-07-2013
* @author : Ram swaroop
* @site : Compzets.com
*/
(function ($) {
// defines various easing effects
$.easing['jswing'] = $.easing['swing'];
$.extend($.easing,
{
def: 'easeOutQuad',
swing: function (x, t, b, c, d) {
return $.easing[$.easing.def](x, t, b, c, d);
},
easeInQuad: function (x, t, b, c, d) {
return c * (t /= d) * t + b;
},
easeOutQuad: function (x, t, b, c, d) {
return -c * (t /= d) * (t - 2) + b;
},
easeInOutQuad: function (x, t, b, c, d) {
if ((t /= d / 2) < 1) return c / 2 * t * t + b;
return -c / 2 * ((--t) * (t - 2) - 1) + b;
},
easeInCubic: function (x, t, b, c, d) {
return c * (t /= d) * t * t + b;
},
easeOutCubic: function (x, t, b, c, d) {
return c * ((t = t / d - 1) * t * t + 1) + b;
},
easeInOutCubic: function (x, t, b, c, d) {
if ((t /= d / 2) < 1) return c / 2 * t * t * t + b;
return c / 2 * ((t -= 2) * t * t + 2) + b;
},
easeInQuart: function (x, t, b, c, d) {
return c * (t /= d) * t * t * t + b;
},
easeOutQuart: function (x, t, b, c, d) {
return -c * ((t = t / d - 1) * t * t * t - 1) + b;
},
easeInOutQuart: function (x, t, b, c, d) {
if ((t /= d / 2) < 1) return c / 2 * t * t * t * t + b;
return -c / 2 * ((t -= 2) * t * t * t - 2) + b;
},
easeInQuint: function (x, t, b, c, d) {
return c * (t /= d) * t * t * t * t + b;
},
easeOutQuint: function (x, t, b, c, d) {
return c * ((t = t / d - 1) * t * t * t * t + 1) + b;
},
easeInOutQuint: function (x, t, b, c, d) {
if ((t /= d / 2) < 1) return c / 2 * t * t * t * t * t + b;
return c / 2 * ((t -= 2) * t * t * t * t + 2) + b;
},
easeInSine: function (x, t, b, c, d) {
return -c * Math.cos(t / d * (Math.PI / 2)) + c + b;
},
easeOutSine: function (x, t, b, c, d) {
return c * Math.sin(t / d * (Math.PI / 2)) + b;
},
easeInOutSine: function (x, t, b, c, d) {
return -c / 2 * (Math.cos(Math.PI * t / d) - 1) + b;
},
easeInExpo: function (x, t, b, c, d) {
return (t == 0) ? b : c * Math.pow(2, 10 * (t / d - 1)) + b;
},
easeOutExpo: function (x, t, b, c, d) {
return (t == d) ? b + c : c * (-Math.pow(2, -10 * t / d) + 1) + b;
},
easeInOutExpo: function (x, t, b, c, d) {
if (t == 0) return b;
if (t == d) return b + c;
if ((t /= d / 2) < 1) return c / 2 * Math.pow(2, 10 * (t - 1)) + b;
return c / 2 * (-Math.pow(2, -10 * --t) + 2) + b;
},
easeInCirc: function (x, t, b, c, d) {
return -c * (Math.sqrt(1 - (t /= d) * t) - 1) + b;
},
easeOutCirc: function (x, t, b, c, d) {
return c * Math.sqrt(1 - (t = t / d - 1) * t) + b;
},
easeInOutCirc: function (x, t, b, c, d) {
if ((t /= d / 2) < 1) return -c / 2 * (Math.sqrt(1 - t * t) - 1) + b;
return c / 2 * (Math.sqrt(1 - (t -= 2) * t) + 1) + b;
},
easeInElastic: function (x, t, b, c, d) {
var s = 1.70158; var p = 0; var a = c;
if (t == 0) return b; if ((t /= d) == 1) return b + c; if (!p) p = d * .3;
if (a < Math.abs(c)) { a = c; var s = p / 4; }
else var s = p / (2 * Math.PI) * Math.asin(c / a);
return -(a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t * d - s) * (2 * Math.PI) / p)) + b;
},
easeOutElastic: function (x, t, b, c, d) {
var s = 1.70158; var p = 0; var a = c;
if (t == 0) return b; if ((t /= d) == 1) return b + c; if (!p) p = d * .3;
if (a < Math.abs(c)) { a = c; var s = p / 4; }
else var s = p / (2 * Math.PI) * Math.asin(c / a);
return a * Math.pow(2, -10 * t) * Math.sin((t * d - s) * (2 * Math.PI) / p) + c + b;
},
easeInOutElastic: function (x, t, b, c, d) {
var s = 1.70158; var p = 0; var a = c;
if (t == 0) return b; if ((t /= d / 2) == 2) return b + c; if (!p) p = d * (.3 * 1.5);
if (a < Math.abs(c)) { a = c; var s = p / 4; }
else var s = p / (2 * Math.PI) * Math.asin(c / a);
if (t < 1) return -.5 * (a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t * d - s) * (2 * Math.PI) / p)) + b;
return a * Math.pow(2, -10 * (t -= 1)) * Math.sin((t * d - s) * (2 * Math.PI) / p) * .5 + c + b;
},
easeInBack: function (x, t, b, c, d, s) {
if (s == undefined) s = 1.70158;
return c * (t /= d) * t * ((s + 1) * t - s) + b;
},
easeOutBack: function (x, t, b, c, d, s) {
if (s == undefined) s = 1.70158;
return c * ((t = t / d - 1) * t * ((s + 1) * t + s) + 1) + b;
},
easeInOutBack: function (x, t, b, c, d, s) {
if (s == undefined) s = 1.70158;
if ((t /= d / 2) < 1) return c / 2 * (t * t * (((s *= (1.525)) + 1) * t - s)) + b;
return c / 2 * ((t -= 2) * t * (((s *= (1.525)) + 1) * t + s) + 2) + b;
},
easeInBounce: function (x, t, b, c, d) {
return c - $.easing.easeOutBounce(x, d - t, 0, c, d) + b;
},
easeOutBounce: function (x, t, b, c, d) {
if ((t /= d) < (1 / 2.75)) {
return c * (7.5625 * t * t) + b;
} else if (t < (2 / 2.75)) {
return c * (7.5625 * (t -= (1.5 / 2.75)) * t + .75) + b;
} else if (t < (2.5 / 2.75)) {
return c * (7.5625 * (t -= (2.25 / 2.75)) * t + .9375) + b;
} else {
return c * (7.5625 * (t -= (2.625 / 2.75)) * t + .984375) + b;
}
},
easeInOutBounce: function (x, t, b, c, d) {
if (t < d / 2) return $.easing.easeInBounce(x, t * 2, 0, c, d) * .5 + b;
return $.easing.easeOutBounce(x, t * 2 - d, 0, c, d) * .5 + c * .5 + b;
}
});
$.fn.animatescroll = function (options) {
// fetches options
var opts = $.extend({}, $.fn.animatescroll.defaults, options);
// make sure the callback is a function
if (typeof opts.onScrollStart == 'function') {
// brings the scope to the callback
opts.onScrollStart.call(this);
}
if (opts.element == "html,body") {
// Get the distance of particular id or class from top
var offset = this.offset().top;
// Scroll the page to the desired position
$(opts.element).stop().animate({ scrollTop: offset - opts.padding }, opts.scrollSpeed, opts.easing);
}
else {
// Scroll the element to the desired position
$(opts.element).stop().animate({ scrollTop: this.offset().top - this.parent().offset().top + this.parent().scrollTop() - opts.padding }, opts.scrollSpeed, opts.easing);
}
setTimeout(function () {
// make sure the callback is a function
if (typeof opts.onScrollEnd == 'function') {
// brings the scope to the callback
opts.onScrollEnd.call(this);
}
}, opts.scrollSpeed);
};
// default options
$.fn.animatescroll.defaults = {
easing: "swing",
scrollSpeed: 800,
padding: 0,
element: "html,body"
};
}(jQuery));
1 ответ
Проблема, кажется, известная и довольно давняя ошибка в Android, где ScrollTop не совсем работает.
Дополнительные ссылки на Stackru:
Я смог заставить поведение animatescroll начать функционировать просто добавив
Самым простым обходным путем для меня было добавить встроенный стиль в контейнер div, поэтому element-demo во фрагменте кода выше выглядит так:
<div id="element-demo" style="height : 500px; overflow : auto;">
Надеюсь, я смогу заставить это работать с моими другими динамически генерируемыми битами... Я сообщу, если найду что-нибудь более полезное.
ДОПОЛНЕНИЕ К ОТВЕТУ. После еще нескольких попыток я нашел другую проблему и решил ее.
Я уверен, что есть ошибка в библиотеке animatescroll.js. В частности, параметр, позволяющий выполнять прокрутку относительно указанного элемента, а не поведение прокрутки по умолчанию в верхней части окна или документа. В текущем коде элемент option используется, но не полностью - animatescroll.js в настоящее время предполагает, что опция element является непосредственным родителем DOM элемента, на который вы прокручиваете. В моем случае я прокручивал до span, который был внутри элемента ap, который был внутри фактического элемента "скроллер" - содержащего div.
Итак, в animatescroll.js я изменил это:
$(opts.element).stop().animate({ scrollTop: this.offset().top - this.parent().offset().top + this.parent().scrollTop() - opts.padding }, opts.scrollSpeed, opts.easing);
к этому:
$(opts.element).stop().animate({ scrollTop: this.offset().top - $(opts.element).offset().top + $(opts.element).scrollTop() - opts.padding }, opts.scrollSpeed, opts.easing);
И теперь все действительно работает. Я уведомил автора animatescroll.js, чтобы он мог обновить репозиторий Git, если он согласен с этим подходом.