Preventing malicious overwrite of JQuery - jquery-ui

Long story short:
We've had errors being logged concerning a JQuery/JQueryUI based system for some time. At it's core we're doing a pretty basic click link -> JQuery AJAX GET -> Open JQueryUI modal pattern.
The error we were getting appeared simple - "Object doesn't support property or method 'dialog'" - leading us to believe there was an error with JQueryUI. After expending a lot of time ruling out browser incompatibilities, bad code on JQuery's end, bad code on our end, angry code gods... we caught a lucky break. A 100% repro on one of the machines in the office.
Turns out the thing was riddled with adware - specifically [an older version of] easyinline - http://www.easyinline.com. When the user clicked any link a cascade of javascript files would be loaded, including reloading JQuery from Google's CDN.
For most links this isn't really a problem - they take you off the page anyway and everything reloads. But for our modals it meant that every modal link would stamp over our JQuery at the point the request was sent, resulting in the response trying to make use of the 'new' $ which would now be missing JQueryUI and any other plugins.
Initially we thought about making another global var ($$ or something) for 'our' JQuery and explicitly using that in our code instead of just $. The issue with that is that we were using a few other 3rd party tools which rely on $ and the adware-loaded $ is a different (older) version. So it's important that we preserve $ correctly.
Any ideas? I'm aware of JQuery's noConflict() method but after a cursory glance don't think it fits the bill.

Ultimately we've decided to re-establish our JQuery integrity when we receive any ajax responses (i.e. just before the open modal code is executed). All our ajax stuff is wrapped in our own handler so this was fairly easy to inject across the board.
Basically;
We have the original JQuery 'saved' - we've got it in-scope thanks to our handler but it could be easily put into a separate global (like $$) just after it is loaded. In our ajax response handler we've got a fairly straightforward check;
if (window.$ !== $$) {
window.$ = window.jquery = window.jQuery = $$;
}
This will reset the global jquery back to what it should be.

well this is just a work around and not a full fledged solution.
you can try multiple things here
1. if you have control over what the adware loads then just put in something like this if(!$) where they try to load the jquery
2. try loading your plugin at the end of the page
3.even if end of the page is not working. Try injecting the link(a script tag using document.write) to the plugins CDN in the Jquery document ready event. this would ensure that the plugins code would be loaded at the end when all the jquery is already loaded (not a preferred thing).

Related

Architecture for jQuery Mobile site with a lot of pages

I've got a website that I'm converting into an app using JQM. I've read about Pages and how the DOM loads but I'm still uncertain how to architect the site.
The main page of the application is based on the Google Maps API which uses JS to load. There are 150+ target pages so I don't want them to load until the user taps the link. All of the target pages also require JS to initialize. When they return to the main page the cached state should be the default but I also need the option to run JS if the query string changes. Content doesn't change often so my preference would be to cache data once loaded but there would need to be some way to flush the cache.
I converted the site to JQM. The target page JS didn't run so I added rel='external' to the links. The JS now runs on the target but when I link back to the main page it reloads the page without running initializing the JS. The obvious solution would be to add rel="external" but then I'd be defeating all performance value. Any recommendations on how I should structure it?
Using rel=external your links will not be loaded with Ajax and you will lose animated page transitions. If you want to run some script when a page displays, use this page event:
$(document).on("pageshow", "#selector", function(event, ui) { /* your code */ });
This and other useful events are described in jQuery Mobile API Documentation.
For example, pagecreate (the now deprecated pageinit) is called once when the page initializes.
About getting query string parameters, see this answer.

jquery tabs sometimes not rendered

I have a strange problem in a web-app (using jQuery 1.10.2 and jQuery UI 1.10.3: the tabs (of the Tabs-plugin) are SOMETIMES rendered correctly and SOMETIMES not. "incorrect" means that the divs with the tab-contents are shown one below the other, no
That happens with IE7,8,10 and FF26 and on machines with rigid policies as well as those with more relaxed policy.
The browser may show a page incorrectly and then you just press F5 and the reload renders correctly.
Has anyone else had similar problems before? I have no idea how to approach this thing, yet the project-mgr wants to see something happening...
(I have validated the HTML/JS using CSE HTMLValidator and it did not report issues, also the JS console does not show any errors, but reports a few warnings (like 'Expected declaration, but found '*' for CSS-declaration like '*cursor: hand;' etc., but nothing related to the stuff I do)
How are you loading the tab content? Is it in the page when it's downloaded, or are they loaded via Ajax?
If already present in the document, you should try hiding (display: none) the content div's - that way you won't see them all if the tab initialization fails (which is likely what is happening intermittently).
This sounds like it could be a timing issue - where are the tabs initialized? Make sure you have them in the document.ready function so you are sure jQuery and jQuery UI are fully loaded first.
After a failure you could try manually initializing the tabs from the console - the result (success or failure) should give some additional insight.
Also use Firebug to examine the content divs to see if they are getting changed by the tab initialization - there should be classes added.

Using Jquery moble with old fashioned hrefs just wont work right

Have been bashing my head against the wall for a good day and a half now. Did everyone abandon old fashioned page structures to go to jQuery Mobile?
I have a webpage, tracks legislation. Main navbar goes as such:
/bills/list, /legislators/list, /committees/list
Where each link is rewritten into
index.php?category=$1&detail=$2
so /bills/list translates to
index.php?category=bills&detail=list
But when I load a page from the navbar, using an a href tag, the pages load all nice and easy using the AJAX loader, but the newly loaded pages 1. don't run scripts, and 2. don't display any formatting. This is a problem.
All the suggestions I have seen say to .bind something or .refresh or .trigger without any context of where that goes, and everything I have tried in that vein has frustrated me to no end.
Please help! And by the way, if I just data-ajax=false everything it works perfectly. But I want the quick loading that ajax gives! I just don't understand how it works and there are really no good pointers on the web I could find.
Code in this pastebin: http://pastebin.com/9jMxV0B6
You can see some artifacts of my struggling to get the thing working.
From what I gather, you shouldn't call new pages via a href, but then why the hell does jqm use href's for its nav menu? Is that supposed to call a function or something?
"But when I load a page from the navbar, using a basic old fashioned a href tag, the pages load all nice and easy using the AJAX loader, but the newly loaded pages 1. don't run scripts, and 2. don't display any formatting. This is a problem."
That happens because JQM ignores all the headers in all other pages besides the first page that loads. So if you want to do any changes to the page use page events, place them In first page.
I had problems understanding it also. Here is a link to my previous post that explains it a bit: How do I enable onload in jQuery mobile (open page both from link & load)?
Hope it clears some things for you. My recommendation for you is to do two simple pages and test simple URL functionality.

Should I be worried about lots of script blocks on my page?

When debugging my MVC3 app in Visual Studio using IE9 I see lots of small "script block" entries for my page. My page relies heavily on AJAX, and some actions result in replacing sections of the DOM with partial views coming back from the server.
What I'm seeing is a growing list of these "script block" entries - should I be worried about this? Will this ultimately be a performance problem when the app is live?
Note: the script blocks are quite small bits of code - I've moved most of my significant javascript into their own .js files.
Mm, I thinks it's more of a personal style thing with modern browsers, but if nothing else, trying to contain all the script for a view in one block at the bottom of the page will make for easier debugging and your future self will thank you for it!
As a general rule of thumb I will only have script blocks in pages that need to use the document.ready or variables from my viewmodel. Otherwise, I would move all the functions into their own js file. It helps keep the views cleaner and the browser will load the page faster since it won't block loading the page when it hits as many script tags. Plus, it will make debugging easier since you can go straight to the js file instead of having to find the function within the HTML.

Jquery load external file that relies on jquery plugin

I have a set of jqueryui tabs that, when clicked, load in their content dynamically. It works great, except that one of the pages uses a jquery plugin itself. This results in two issues:
The main page that holds the tabs throws an error when loaded because there is js that refers to elements that haven't loaded yet (those elements are in the external file that contains the code that relies on the plugin).
If I embed the js that triggers the plugin functionality into the external file, it is outside of the document.ready function from the main page and therefore isn't usable.
Basically I am looking for a technique that allows me to ajax load an external html file into the DOM while not crapping out the main page itself because JS that is already there is expecting HTML which is not yet there.
Thanks.
I haven't used it yet, but I think that this is what you are looking for
Listen
This plugin brings a clean, light solution, to websites with dynamic loaded content, or full of event bindings.
Intead of bound, handlers for events, are registered along with matching selectors.
And they'll still work for new added content.
This is achieved, using Event delegation, so the plugin will only work for events that bubble
You need to encapsulate your jquery code inside of the $(document).ready() function. If you're saying the code that's waiting to load via AJAX may or may not be loading at the same time as the parent page (i.e. a user has to click the tab to load it, vs. it being the default load) then you're design is bad and you'll have to rethink the approach. Basically you can't have code in your parent page referencing DOM elements that don't yet exist, and may not exist until your user clicks a tab.

Resources