I created some kind of lazy load for images. It works like this:
Every 500ms it check photoes which one you see on device and if you see it begin to load real image and this function will never run for images that loaded but if image cant load it will try again when you see this image again.
Is there any problem to use that kind of function every 500ms?
It sounds like you're using this in response to the images coming into view? Rather than polling every 500ms all the images on the page to see if they're in view, perhaps it would be better to trigger the check only when the page has scrolled (or whatever causes images to scroll. You could still limit this to be no more frequent than once every 500ms, but it has the benefit of:
Not having a 500ms interval loop running all the time
Not checking the images in view unnecessarily
I'll assume the images come in and out of view as the user scrolls, so what you'd want to do in that instance is as follows:
Bind an event to $(window).scroll
Have it fire an event after a fixed period with setTimeout (500ms in your case).
Cancel that timer if the user scrolls again and start it (to prevent it firing multiple times.
Listen for the event firing and perform your image check there.
Here's an example of how the code might look:
var scrollIntervalTimeout;
$(window).on('scroll', function() {
// Cancel the timeout and start it again
clearTimeout(scrollIntervalTimeout);
scrollIntervalTimeout = setTimeout(function() {
$(window).trigger('scrollDidEnd');
}, 500); // 500ms delay before firing the event
});
// Listen for the scrollDidEnd event
$(window).on('scrollDidEnd', function() {
// Perform your image check here
});
Related
I am in the process of profiling Sencha Touch applications and came across the fact that a click of a button triggers action faster as opposed to a click of a list item from Ext.List for the same action. My timeline profiling data indicates that the action is performed on Timer Fired condition for list item. This timer's timeout is 300ms. Now, for buttons there's no timer, so the action is performed as soon as there's touch end (and other Sencha processing common to all clicks).
In my case, the action is a simple transition to another view without any animation.
Following are the screenshot of my timeline data running application on an iPhone 4.
Transition by button click/tap:
Transition by list item click/tap:
I tried to dig into the source code, but could not understand why this is actually happening. My hypothesis is that list waits for that 300ms to see if it was actually a tap action or a scroll action. But is this true? If not, can anyone point me towards the right direction to verify if this hypothesis is true or not?
Any help would be highly appreciated!
I think is because of the pressedDelay config, which for Ext.Button default is 0 and for Ext.DataView is 100 ms.
Aditionally, the button fires directly the handler function. And the dataView executes store.getAt(index) to find the record object and pass it to the itemTap callback what adds some ms.
Got it!
This 300ms wasn't because of the scroll event, rather it was to recognize if its a single or a double tap event. If you look at DoubleTap recognizer source code, it has a maxDuration of 300 ms in the config object. This is used to set the time out for firing singleclick event.
onEnd function:
else {
this.singleTapTimer = setTimeout(function() {
me.fireSingleTap(e, touch);
}, maxDuration);
}
And on every touchStart event, this timeout is cleared.
onTouchStart: function(e) {
if (this.callParent(arguments) === false) {
return false;
}
this.startTime = e.time;
clearTimeout(this.singleTapTimer);
},
To note, this is a private class, so we cannot rely on it. But if anyone wants to decrease the duration between a tap event and firing off its logic, reduce this time. I have noticed that setting it to 150ms will make list item click much much faster, but at the same time, it also opens up the room for ghost click in other screens, since the events are queued up.
You can disable or edit recognizers configuration in Ext.application: http://www.sencha.com/forum/showthread.php?205692-Reduce-delay-of-itemsingletap-on-xtype-list
I have a function, that adjusts element width/height on a page. This function is triggered by a custom dimensionchange event.
I'm
$(window).trigger("dimensionchange")
whenever I'm loading content via AJAX or changing a page (I'm using jquery mobile).
My problem is on some pages, a bunch of Ajax requests get triggered (like a search page, which ajax loads criteria and intial results), so I'm ending up with several "dimensionchange" events, which all trigger my layout update function. This slows down the page considerably and is not necessary, because I only need to capture the last dimensionchange and then update the layout.
Question:
Is there a way to capture the last occurence of an event when the event fires a random amount of times? The only thing I could think of is to set a timeout on every event occurence and if there is no further event in ... 500ms... trigger the page update. But this seems pretty awkward, so I'm curious to know if there is a better way?
Thanks for help!
You want to use jQuery's Global Ajax Event Handlers ajaxStart() and ajaxStop() methods.
There is another recent post about Using AjaxStop and AjaxStart. The main thing you need to know is that you can be notified when the first ajax query begins, and when the last one ends. You could set a flag like this:
$(document).ready(function() {
var ajaxBusy = false;
$(document).ajaxStart( function() {
ajaxBusy = true;
}).ajaxStop( function() {
ajaxBusy = false;
});
});
jsFiddle
I use a customized drop-down menu which runs on jQuery events and animations.
The problem occurs when I activate the drop-down via mouseenter several times, which results in the menu sliding down then sliding up several times. I tried to fix it by adding .stop(true), which was successful, but it resulted in other problems like this.
I followed that advice(jsFiddle Here), but it causes more unattractive problems.
I need is a way to stop a function from firing redundantly, but still be able to stop a "slide down" immediately and then "slide up" if the user triggers .mouseleave.
I tangled with custom queues for a good 5 hours, with no success :(
Any ideas, advice, and criticism is welcome.
Basically it boils down to delaying the execution of the event handler.
var mouseoverTimer = null;
$('.elem').mouseover(function(){
clearTimeout(mouseoverTimer); //ignore previous trigger
mouseoverTimer = setTimeout(function(){ //wait to execute handler again
//execute actual handler here
}, 10);
});
If the same handler was called within the specified interval the pending execution is cancelled and queued again to execute 10ms later hoping that there's no subsequent trigger within that interval.
I develop an app using phonegap and jquerymobile/jquery.
During development I only had a virtual iOS device and now since I'm testing the app on a real device I see, that time between click on an element and handle this event is very long.
E.g if i Click on an icon a loader icon is shown but this icon first come in the moment the next page is final loaded (a very short time the loader is shown).
I develop with Javascript since a long time and always have focus on performant execution but this is very strange.
The App has got about 10 views in one HTML file. And on click on an element only show the next part of these file.
Does anyone know about solutions to solve "Bugs" like these?
Thanks in advance.
The click delay on iPhones is a feature used to distinguish between clicks and scrolls. When you bind to the click event iOS waits approximately 300ms to decide whether you were clicking an object or trying to scroll the page.
You can use jQuery Mobile's vclick event which fires much faster however you will probably run into situations where the vclick event is fired off twice in a row which can result in multiple elements being clicked. Here is some sample code of how to use vclick events and only capture the event triggered first:
$(function () {
//setup a function to check if a vclick event has fired within the last 500ms
function check_vclick () {
//if a vclick event has fired in the last 500ms then return false
if (do_vclick == false) return false;
//otherwise set a flag to disallow vclicks for 500ms
do_vclick = false;
//setup a timeout to allow vclicks in 500ms
setTimeout(function () {
do_vclick = true;
}, 500);
//return true so the event handler knows it's ok to run its code
return true;
}
//setup a flag to allow/disallow vclick events from firing
var do_vclick = true;
//bind an event handler to the vclick event for an element
$('#link_id').bind('vclick', function () {
if (check_vclick()) {
//run the code associated with the element, if it's a link referencing a pseudo-page on the same HTML document, you can do something like this
$.mobile.changePage($(this.href));
}
});
});
Here's a link to the documentation for $.mobile.changePage(): http://jquerymobile.com/demos/1.0rc2/docs/api/methods.html
Here's a link to the documentation for vclick (notice the notes under the virtual mouse event section): http://jquerymobile.com/demos/1.0rc2/docs/api/events.html
I want to load more content when the user scrolls the webpage. I tried using
onScroll event javascript which is getting called multiple times
jQuery .scroll() method which is also called multiple times.
How do I handle this? Is it a browser issue?
Note: I am calling onScroll = "function()" on body tag of HTML.
On every scroll any scroll method would be called
So you should check when the user scrolls to the bottom, then load more content.
If you're getting a series of events as the window moves (similar to what happens on a resize event), then one trick is to set a timer for 1-2 seconds on the first scroll event, but not do anything yet. If a subsequent scroll event comes in before the timer fires, you stop the previous timer and set a new one. When the user stops scrolling for a brief time, the timer will fire and you can then process the scroll event. If they scroll some more, the whole process will repeat.
jQuery pseudo-code example:
var scrollTimer = null;
$("#target").scroll(function(){
if (scrollTimer) {
clearTimeout(scrollTimer); // clear previous timer
}
// set timer while we wait for a pause in scroll events
scrollTimer = setTimeout(function() {
scrollTimer = null; // timer done here
// do your dynamic loading here
}, 1000);
});
Load content while scrolling: http://www.webresourcesdepot.com/load-content-while-scrolling-with-jquery/