Are there any docs or training materials available that advise the best way to include multiple jQuery plugins in an abstract way, allowing for extension of those plugins, and also global control of things like events, setTimeout() etc?
I want to be able to do these kind of things:
Extend someone else's jQuery plugin, e.g. if I want to add a new feature, but not touch the original codebase
Have my own server-side detection script pass a value to JS (using a HTML meta tag) so JS can detect that and then decide which script to use (e.g. tone down some of the jQuery for lesser devices)
Better control all the events that are attached
setTimeout() - I have loads of these dotted around the place at various intervals - I want to control all this in one function
Add my own fixes to jQuery scripts. If I download a ready-made one and use it I always find I can improve usability - especially on mobile devices - so I want to add my own fixes and improvements.
Control the resize event. There's all sorts going on at the moment and it's quite a job triggering a full re-size when I write new code (and the resize is pretty slow on some mobile devices)
You can use RequireJS or similar library to load scripts dynamically depending on screen size or navigator's user agent parameter (You will need to set condition checking yourself though).
Related
Imagine a mobile webpage with a navigation bar at the very top of the page.
Using javascript/jQuery I'd like to be able to detect when a user scrolls "past" the top of the screen.
Let me try to explain: Imagine that the webpage just loaded and you see the navigation bar at the very top of your screen. Now, you put your finger on the screen and drag down. On an iPhone, this will look something like:
I'm looking for something similar to the following:
$(document).ready(function () {
$(window).scroll(function (event) {
var y = $(this).scrollTop();
if(y < -20)) {
//do something
}
Unfortunately, this won't work on Android phones because they don't have the same elastic behavior as iPhones:
The bad news
So, let's start with the bad news: there is no way to get the information you wish for natively. Why? Because once you get into the 'elastic' zone you're dragging the entire webview component down rather than just the content of the document like in your pseudo code.
What does this practically mean? Emulation or Native wrapping
Emulation, the choices
So you will have to run your own solution and you will have to make a couple of choices. First of all if you wish to use elastic scrolling you should note that this is patented by Apple Inc. in patent US7469381 B2. Please go through this patent carefully to ensure you won't be infringing (even if you're building an iOS only app this does not change anything).
Secondly the question is whether you really want to emulate a native experience. There is a big lobby against native experience emulation due to 1) a believe that it can't ever be perfect enough and 2) as operating systems and browser change your code will stay out of date and thus look terrible/weird or possible can even cause entirely unexpected behaviour/combinations.
Secondly you will have to decide whether you wish for the same elastic behaviour on android or whether you wish to give a more native like experice on android. Personally I believe it makes for some excellent UX, so I wouldn't explicitedly disadvice you from using an elastic effect, however it is something you should consider carefully.
Emulation, the scripts
Most scripts that provide similar emulation to what you want are "pull to refresh" scripts. Depending on your specific wishes you should simply use one of those scripts and either alter them or use some CSS to hide the message inside them.
Hook.js - Not perfect emulation of the native experience and uses the old iOS background, but a pretty good option none the less, to hide the spinner just use
.hook-spinner{
display:none;
}
iScroll.js - Very well developed code and behaves excellently. Disadvantage is that it provides a lot more than what you're looking for which might be either a good thing or a bad thing. You can find a sample implementation of pull to refresh behaviour here, but do note it's for an older version of iScroll, in the last version the example seems not to have been implemented, but it should be quite similar. Just look at the code to see how to remove the pull to refresh message.
jQuery scrollz - Just one more option. Seems to be comparable to hook.js, but does have some iScroll like features as well. You can 'remove' the message by specifying the pullHeaderHTML with empty HTML strings.
Native wrapping
The alternative, which I am convinced you do not want to do, but I do want to add for the sake of completeness, is to distribute your app as a native app for example bundled up in phonegap. However to get this working would require a fair number of changes to the phonegap code itself and would not be an advisable approach (I have once developed a phonegap app using native components and interactions 'around' it triggering various javascript events, although doable and presenting certain advantages it's not something I would advice).
So..I'm not sure what do you need this for.
If it's for a ListView - you can override onOverScrolled
If you need this for ScrollView - there's a way by also extending it. I don't remember now, but if you need it - I can find it.
If it's for a WebView inside your app - I'm pretty sure it's not possible. The amount of control you have on the way web pages are rendered and manipulated is limited.
If you want the Chrome/stock browser to act the way it does on iOS - I don't think it's possible unless you get the browser's code and change it yourself :)
I need to implement a page of which many parts are dynamic widgets. Which widgets are loaded depend on user choice and are not known before hand. Each of these widgets include some HTML, and some javascript code (to initialize and attach event handlers on the HTML elements). I am wondering what is the best approach to implement such a page and widgets.
AJAX. I could construct response with some HTML followed by a <script> tag. Although returning js code in AJAX is not recommended, I found this works for me (the script get executed, with HTML widget properly initialized and handlers attached). An alternative is to include an 'all-included' script in the container page. In this script I wrap each of widget-specific script in a function, and when the widget is dynamically loaded, I call that function. However, this way I fetch a lot of js code that may not be used.
Iframe. I can also return the widget as a standalone HTML page to be loaded in iframes. This solves the javascript problem, but I need to make cross-domain calls to interacte with other part of the container page.
I think this should be a common problem faced by web developers. I am new to web development, could you share some 'best pratice' tips for my case?
You should be going ahead with jquery+ajax.. There are lots of drawbacks with iframes. Although you could handle each plugin in separate page and avoid any kind of conflict, usablitity becomes a great headache..
In the time of everything going HTML5 based to support mobile platforms, iframes are hard to cuztomise for mobile screens. Moreover iframe takes out the entire apple users as iframes are not supported by apple devices..
jQuery + Ajax(HTML5) along with CSS3 should be the way to proceed..
Lets assume that we have a responsively-designed Web page which uses media queries to achieve three different views: screen, handheld and print. Lets assume further, that such a Web page includes several JS-based, view-dependent layout fixes, navigation logic, content-generating macros and similar stuff, reason for which may be more or less controversial.
Now, please imagine that users are playing with our design by resizing browser window and printing it's contents. A we would like to react on the style changes (carried out by the browser) in order to recalculate layout fixes, regenerate dynamic content, rearrange navigation or whatever else. But there is no "onMediaChange" event to be handled by our script, is it? So, in what way could a Web developer synchronise the media-driven style with the media-independent logic?
This question, in several forms and development contexts, has been asked on StackOverlow for years, but no rewarding answer has been given yet. There are workaroundss using width-based conditionals, but these neither handle the print view, nor react to width changes occurring after the page has loaded. Other group of CSS-sniffing solutions is based on polling which is fallible and inelegant. What I am looking for is a general, elegant, standards-compliant, client-side solution for synchronising JS and CSS with media changes. Two non-existing, ideal solutions could be:
The existence of an onMediaChange event, e.g.:
document.addEventListener('onMediaChange', myHandler, false);
The possibility to attach scripts with the link tag, e.g.:
<link rel="script" media="print" type="text/javascript" href="print.js"/>
I'll be grateful for any existing solutions, creative suggestions, theoretical comments or even a philosophical discussion exceeding the scope of this question.
I think you're looking for window.matchMedia API:
https://developer.mozilla.org/en-US/docs/DOM/window.matchMedia
Basically, it'll let you attach an Event Listener to media queries. You could pair this with an append() method to add/remove dinamically <link> tags.
Unfortunately, as far as I know, it is poorly supported among old browsers, but using a polyfill (like this one) you could potentially get a global, cross-browser support.
I'm interested in using only some of the components of jQuery mobile (specifically, the tap event handlers and datepicker). What's the best way to make use of the library without it "taking over" the layout and behavior my mobile web app?
modifying DOM is JQM's main feature. You have to cripple it hard.
Get the repo from git, remove all plugins from manifest, get to the code and find the .page method/widget and remove all the code (or leave some bits if you need to get something working - I haven't tried that).
Then run make and it will create a stripped jquery.mobile.min.js for you
I have a question about Javascript widgets. The widget I am working on simply embeds content on a page instead of using iframes. So far it looks good. But there are cases where some users layouts are messing up the widget. For example, the widget might require a width of 300px to appear. But the parent div is set to 250px and hence the right part of the widget is cut off.
I was wondering what sort of precautions should be taken to prevent this? I was talking to the product manager who mentioned he wanted me to check the parent div elements and get the size and then show an alternate message if their size is not accurate. But again, since this is Javascript and the widget is supported in many diff browsers(including IE6), I am wondering how fail-safe this method would be? What if I need to iterate the DOM all the way up before getting a valid size? I am also worried about performance here. This extra checks would slow down the delivery of my widget content to "good users" since I am adding a layer of complexity to all users. I don't want to penalize good users just because of the few errant ones.
I am not using any sort of JS library here, so any solution should not suggest the use of one. Also, the reason for not using a library was simply not to add extra weight to the page load to deliver a widget. I understand that "jquery" for example is small, but in my case, even 24k compressed seems like an overkill for a widget delivery that contains no core code for the widget.
Has anyone dealt with such issues before? What are your solutions to these?
There are reliable ways of determining the size of an element using JavaScript. You're quite right that you may need to iterate up the tree in some cases, but the answer you get will ultimately be quite valid.
Although you don't want to directly include any library code in this project, you may consider looking at how the major libraries implement their "what's the width of this element" functions to drive your own implementation.
Beware of quirks mode too.
I'd check to see of the page has Jquery, if not load it into the page using no-conflict mode. Then use jQuery to examine the page.
See: How to embed Javascript widget that depends on jQuery into an unknown environment