jQuery scrollstart, scrollstop and very quick scrolling issue - scroll

I'm having an issue with James Padolsey's custom events: scrollstart and scrolltop
When I use the mouse wheel to scroll one "notch" or I click the scroll bar somewhere far below or above its current position, causing sudden scroll by a large amount, I get the same scrollTop() values for scrollstart and scrolltop - I can't tell where the scroll started or in which direction the scroll has taken place. jsFiddle available here (note: if you have an extremely high resolution, you will have to add more text to the HTML so that a scroll bar appears in the Result window).
HTML:
<html>
<body>
<div id="scrollable">
<!-- insert lots of text here -->
</div>
</body>
</html>
CSS:
#scrollable {width: 120px;}
JavaScript:
var before = 0;
$(window).bind('scrollstart', function() {
before = $(window).scrollTop();
});
$(window).bind('scrollstop', function() {
alert('before: ' + before + "\nafter: " + $(window).scrollTop())
});
jsFiddle available here
Any ideas on how to retrieve the true scrollTop() value for the scrollstart event? Modifying the plugin is an option I guess, so all ideas welcome.

Instead of recording the before value when the scroll starts, I would suggest doing so in another event, for example mousemove()
jsFiddle of this idea working

Maybe I misunderstood your question (I haven't used that plugin), but I think you don't need to use every part of that plugin. If you only want to know the previous and current value of ScrollTop and its direction, take a look at this:
http://jsfiddle.net/C3ye7/
var currentScrollTop, temporalScroll = 0;
$(window).scroll(function(){
currentScrollTop = $(this).scrollTop();
console.log('Previous value: ' + temporalScroll)
if (currentScrollTop > temporalScroll) {
console.log('scroll down')
console.log('Current value: ' + currentScrollTop)
}
else {
console.log('scroll up');
console.log('Current value: ' + currentScrollTop)
}
temporalScroll = currentScrollTop;
});
In order to add the timing functionality, you can use only that part of that plugin (or simply, start a setTimeout to record a bigger change when scrolling).

Related

Kendo Window positioning

I am using bootstrap template and Kendo Window and so far positioning of modal kendo windows wasn't too hard.
But now as I a use a different layout for a certain area, I find myself having problems with that matter.
following code is expected to create a centered (x-axis) modal kendo window:
#(Html.Kendo().Window()
.Name("Window1")
.Visible(false)
.Position(builder => builder.Top(100))
.Draggable()
.Content(#<div class="kendoWindowContent"><p>Please wait...</p><div class="k-loading-image"></div></div>)
.Width(1000)
.Title("Title1")
.Actions(actions => actions.Close())
.Modal(true)
.Resizable())
..and displaying via:
var wnd = $("#ownerVoucherCreateWindow").data("kendoWindow");
wnd.refresh({
url: '#Url.Action("Voucher_Create", "OwnerVoucher")'
});
wnd.open();
The window is not beeing displayed in the middle of the x axis.
Are there any constraints in order to have the kendo window beeing centered.
Window centering requires the usage of the center() method. Since the Window content is loaded via Ajax, you need to center the widget in its refresh event.
var wnd = $("#ownerVoucherCreateWindow").data("kendoWindow");
wnd.one("refresh", function(e) {
e.sender.center();
});
wnd.refresh({
url: '#Url.Action("Voucher_Create", "OwnerVoucher")'
});
wnd.open();
It is also possible to trigger centering in every refresh event, instead of just once.
Another option is to set explicit width and height. In this case you can center the Window at any time, because the widget dimensions will not change after changing (loading) the content.
ok I guess I was just lucky that all my kendo windows happened to be displayed centered although specifying an explicit offset to top like described.
I assumed, that the window would automatically center on y-axis when having only an x-axis position set.
As it seems this is not the case. I don't really know why this has been working in the past.
Anyway, I figured out a way to center the window depending on the browsers' viewport and window width:
just in case anybodes cares...
function displayWindowCenteredOnYAxis(kendoWindow) {
var windowOptions = kendoWindow.options;
var pos = kendoWindow.wrapper.position();
var viewPortWidth = $(window).width();
var wndWidth = windowOptions.width;
pos.left = viewPortWidth / 2 - wndWidth/2;
kendoWindow.wrapper.css({
left: pos.left
});
kendoWindow.open();
}
Usage:
var wnd = $("#id").data("kendoWindow");
wnd.refresh({
url: '#Url.Action("Action", "Controller")'
});
displayWindowCenteredOnYAxis(wnd);

syncronized scroll does not work in div based ckeditor

Basically i have 2 instances of ckeditor on a single page. One on the left and another in the right side of the page.
The left editor uses a div rather than traditional iframe. I've done this by removing the iframe plugin and including the div editing area plugin.
The right editor loads in an iframe and but is also div based(i can use the iframe editor as well on the right if required, not an issue).
Now if the cursor/focus is on the right editor's content area then the left editor should scroll along with it. I've tried to use the code as provied by Reinmar in below url but it seems to work only with editors based on iframe on both sides. Also please note that i'm using jquery adapter for initializing the editors.
CKEDITOR how to Identify scroll event
I initialized the editor on left as below:
var editor_left = $( '#editor_left' ).ckeditor();
And below is my code for the right editor:-
var editor_right = $( '#editor_right' ).ckeditor();
editor_right.editor.on( 'contentDom', function() {
var editable = editor_right.editor.editable();
editable.attachListener( editable.getDocument(), 'scroll', function() {
alert('scroll detected');
parent.$('#left_editor_content_area').scrollTop($(this).scrollTop())
});
});
If i use the iframe based editor on the right then i'm able to get the "scroll detected" alert. But the scrollTop() function still does not work as expected
Any help will be appreciated.
The code that you mentioned is right. You got to update scrollTop property of the div-based editable with the scroll position of the window inside the iframe-based editor (JSFiddle).
var editor_div = CKEDITOR.replace( 'editor_div', {
extraPlugins: 'divarea'
} );
CKEDITOR.replace( 'editor_iframe', {
on: {
contentDom: function() {
var editable = this.editable(),
win = this.document.getWindow(),
doc = editable.getDocument();
editable.attachListener( doc, 'scroll', function( evt ) {
// Get scroll position of iframe-based editor.
var scroll = win.getScrollPosition();
// Update scroll position in the div-based editor.
editor_div.editable().$.scrollTop = scroll.y;
} );
}
}
} );

How to reduce Tumblr photoset posts size and keep the original ph-set layout?

I want to reduce them to a maximum 200px width and keep the same layout with the 10px spacing the photos have. Also I don't want to style the posts to be that wide and use overflow:hidden that will only cut off the photosets.
jQuery Solution
For this solution you will need the latest version of jQuery and the jQuery plugin imagesLoaded included in the head of the theme before the following:
<script type="text/javascript">
$(document).ready(function() {
$('iframe.photoset').each(function() {
var i = this;
$(i).attr("onload", "ps_resize(this)");
var s = $(i).attr("src");
s = s.replace(/\/500\//, "/200/");
$(i).attr("src", s);
});
});
function ps_resize(i) {
$(i).contents().find("body").imagesLoaded(function() {
$(i).attr("width", 200);
$(i).attr("height", $(this).height());
});
return false;
}
</script>
What Solution Does
When the DOM is ready, find all the photoset iFrames
For each iFrame...
set the "onload" attribute to your frame resizing function
get the frame's source url, change the size (e.g. 500) to 200
set the frame's source url (this will cause it to reload with a smaller photoset)
In the resizing function...
wait for the images to load
set the frame width to 200
set the frame height to the new height of the photoset
Additional Code for Infinite Scroll
If you are using the Infinite Scroll jQuery Plugin, you will need to additionally include this in your success callback function:
...
$(newElements).find('iframe.photoset').each(function() {
var i = this;
$(i).attr("onload", "ps_resize(this)");
var s = $(i).attr("src");
s = s.replace(/\/500\//, "/200/");
$(i).attr("src", s);
});
...
Obviously, if you're using Infinite Scroll, I would suggest defining a function that is called on each iFrame on both the initial load and the scroll so you don't have repeated code to maintain.

Pull To Refresh Horizontal iScroll

Recently I successfully integrate vertical iScroll to my mobile web. It has pull to refresh feature. However, Im currently stack at the part which I need to implement the same feature into a horizontal iScroll. Does anyone knows where can I see any sample that uses the same feature? I really need the help. All I need is to know how to do it because as of now, i have no idea with it.
Regards,
Askhole :)
iScroll by default does not support Pull to Refresh from a horizontal standpoint. I'm sure it could be done with some CSS and code tweaks, but you might be better off asking in the iScroll forums: https://groups.google.com/forum/#!forum/iscroll
i guess you implement vertical refresh by using a non-official iscroll.js (i.e., a modified-for-refresh iscroll). If this is your situation, this answer may helps:
i implemented vertical refresh with the official iscroll.js, by adding a little trick:
1. keep sth very very tiny at the next-bottom, use its position().top to detect the actual height of ur page
keep you "onloading" ath the bottom, set it invisible
Math.abs(myScroll.y) + wrapper.height === $(yourTiny).position().top
when scroll starts, if scroll upwards, check the condition in 3.
for tolerance in 4, you may use, for example: if(Math.abs(myScroll.y - wrapper.height + $(yourTiny).position().top) < 11){ //your code to refresh}
Here are the sample codes:
1.html
<sapn id="theTinyThing"> </span>
<table id="bottomRefreshImg" style="display:none">
<tr><td><img src="refreshGreen.gif" /></td></tr>
<tr><td>loading...</td></tr>
</table>
</div> //close scroller
</div> //close wrapper
<div id="footer"></div>
<script src="./jquery-2.2.3.min.js"></script>
<script src="./iscroll.js"></script>
<script src="./mrPage.js"></script>
</body>
2.css
#theTinyThing{
height:1px; //it's ivisible
font-size:1px;
}
3.js
var myScroll;
var myScroolHasCausedAddNew=0;
function loaded () {
myScroll = new IScroll('#wrapper', {
scrollbars: true,
scrollbars: 'custom',
mouseWheel: true,
click:true,
interactiveScrollbars: true,
shrinkScrollbars: 'scale',
fadeScrollbars: true,
snap:true,
snap:'table',
});
myScroll.on('scrollStart',function(){
if($("#theTinyThing").position().top + myScroll.y-myScroll.wrapperHeight<11){
if(myScroll.directionY==1){
$("#bottomRefreshImg").show();
myScroolHasCausedAddNew=1;
}
}
return false;
});
myScroll.on('scrollEnd',function(){
if(myScroolHasCausedAddNew==1){
myScroolHasCausedAddNew=0;
$("#bottomRefreshImg").hide();
loadMore();
}
return false;
});
}

jQuery — a .live() > each() >.load.() finella

EDIT - URL to see the issue http://syndex.me
I am dynamically resizing images bigger than the browser to equal the size of the browser.
This was no easy feat as we had to wait for the images to load first in order to check first if the image was bigger than the window.
We got to this stage (which works):
var maxxxHeight = $(window).height();
$(".theImage").children('img').each(function() {
$(this).load( function() { // only if images can be loaded dynamically
handleImageLoad(this);
});
handleImageLoad(this);
});
function handleImageLoad(img)
{
var $img = $(img), // declare local and cache jQuery for the argument
myHeight = $img.height();
if ( myHeight > maxxxHeight ){
$img.height(maxxxHeight);
$img.next().text("Browser " + maxxxHeight + " image height " + myHeight);
};
}
The thing is, the page is an infinite scroll (I'm using this)
I know that you are not able to attach 'live' to 'each' as 'live' deals with events, and 'each' is not an event.
I've looked at things like the livequery plugin and using the ajaxComplete function.
With livequery i changed
$(".theImage").children('img').each(function() {
to
$(".theImage").children('img').livequery(function(){
But that didnt work.
ajaxComplete seemed to do nothing so i'm guessing the inifinte scroll i'm using is not ajax based. (surely it is though?)
Thanks
Use delegate:
$(".theImage").delegate('img', function() {
$(this).load( function() { // only if images can be loaded dynamically
handleImageLoad(this);
});
handleImageLoad(this);
});
The problem is that your infinite scroll plugin does not provide the callback functionality. Once your pictures are loaded there is no way to affect them.
I have tried to modify your plugin, so that it will serve your needs, please see http://jsfiddle.net/R8yLZ/
Scroll down the JS section till you see a bunch of comments.
This looks really complicated, and I probably don't get it at all, but I'll try anyway :-)
$("img", ".theImage").bind("load", function() {
var winH = $(window).height();
var imgH = $(this).height();
if (winH < imgH) {
$(this).height(winH);
$(this).next().text("Browser " + winH + " image height " + imgH);
}
});

Resources