Use jQuery with my own document object - javascript

I'm making a greasemonkey userscript that is supposed to preload certain data (actually, xkcd comic strips) and display them when link is clicked.
My task mostly consists of retrieving data from DOM fetched by ajax and assigning the values to DOM the user is viewing. This is one particular case I find jQuery incredibly helpful. But jQuery operates on window.document.
I load and parse document like this:
xhr.onload = function() {
var doc = document.implementation.createDocument(
'http://www.w3.org/1999/xhtml',
'html',
document.doctype
);
doc.documentElement.innerHTML = this.responseText;
}
And I need to perform jQuery selectors on doc, so that I can retrieve the site data (such as comic title).
Once more, the question: How to perform jQuery selectors on custom document object?

You can simply use $(doc) and jQuery's traversal methods:
var $doc = $(doc);
var comicContainer = $doc.find('#comics'); // for example

To add, for example, click events to custom loaded items, use this:
$(body).on( 'click', 'YOUR_DYNAMIC_SELECTOR', function(){ DO_ALL_THIS } )

Related

How to handle multiple AJAX behaviors in one HTTP request?

I am using jQuery. I have implemented a multipart web page where a list of links* are rendered and each link is periodically updated through AJAX HTTP requests. That is, on the page there are many links of which each one is "timer-triggered" through JavaScript so to perform a HTTP request to the URL pointed by the link itself and, on response success, to replace those links with the retrieved data (the updated links).
This implementation works but it is "performance less" in cases when the page contains many links: one AJAX request is executed per link resulting in many hits to the server. In order to solve that performance issue I thought to make the JavaScript code to execute a unique AJAX request that retrieves the whole set of links and then to replace DOM data.
However I do not know how to implement the "unique request" mostly due to the practice/technique that I have to use and since it is the first time I notice this kind of problem. What can I do? Should I implement a JavaScript handler for event-registration or what?
* In my case link elements are used (<a></a> HTML tags) but those can be anything associated with a URL.
Update after the jfriend00 answer
If the solution is to build a JSON array as jfriend00 describes in his answer then I should implement the page behavior so to update the JSON array dynamically. Since my HTML links are even rendered dynamically along with some JavaScript code then that JavaScript code could update the JSON array dynamically by "registering"/"unregistering" links. If this is a solution in my case, how can I implement it?
I render links as "partial templates" along with the JavaScript code which JavaScript makes those links to execute AJAX requests. HTML-JS code per each link (the mentioned "partial templates") looks like the following:
<script type="text/javascript">
(function() {
var link = $('#link_1')
...
}());
</script>
It seems like you can just send some JSON that is your array of links to request and then receive JSON back that is an object where each key is the requested link and the data is the server response for that particular link.
If the links you want to process look something like this:
<a class="myLink" href="xxx"></a>
It could look something like this:
function processLinks()
// assuming you can specify some CSS selector to select the links in your page that
// you want to target
// create an array of URLs for the ajax call
// and an index of arrays --> DOM objects so we know which DOM object goes
// with a given URL when processing the ajax results
var urlArray = [];
var urlIndex = {};
var urlArray = $(".templateLink").each(function() {
urlArray.push(this.href);
urlIndex[this.href] = this;
});
$.ajax({
url: "your ajax url here",
data: JSON.stringify(urlArray),
dataType: "json"
}).done(function(data) {
// assumes you get data back as {"url1": data1, "url2": data2, ...}
$.each(data, function(url, urlData) {
// get DOM object that goes with this URL
var domObj = urlIndex[url];
// apply urlData to domObj here
})
});
}
Updating my answer now that you've disclosed your "partial templates".
To process them all at once, change this type of structure which processes them one at a time:
<script>
(function() {
var link = $('#link_1')
...
}());
</script>
<a href="yyy" id="link_2></a>
<script>
(function() {
var link = $('#link_2')
...
}());
</script>
to this which finds them all in the DOM and process them all at once:
<script>
// process all the template links
$(document).ready(processLinks);
</script>

Displaying data from a database using jQuery and Javascript

I'm trying to display specific parts of a Cloudant database. This database contains many separate documents, and each document contains a category called "results". I'm trying to display whatever is in results. Each document is identified by its own id. I tried using the get() method in jQuery, but unfortunately it is not running successfully.
function grabData(){
var url = 'https://cloudant.com/futon/document.html?acharya%2Ftoxtweet/ff558f75077e8c758523cd3bd8ffdf88';
$.get(url, function(data) {
$('.result').html(data);
alert("Data loaded: " + data);
});
}
grabData();
I'm not entirely sure where I went wrong...Should I consider using SQL instead of ajax?
I think your issue it this:
replace this:
grabData();
with this:
$(document).ready(function(){
grabData();
});
or more shortened:
$(function(){
grabData();
});
The URL you are using is returning an entire webpage.
Your jQuery code is looking for an element on the current page with a class name of result and trying to change it's inner HTML to the response from the URL.
You didn't provide any additional code to look at, but I would assume that is not what you were expecting it to do.
I assume you are wanting to parse through the entire url, but in your current code the page will be processed as a raw string and not a DOM object. So you would have to parse through that string with regular expressions, etc.

How to override variable parameter loaded from another script

I have a script that loads the code dynamically. It is kind of a search engine. When I press a search button, the action gets triggered and a new page opens with many parameters.
I want to override one of the parameters generated with the script in the new URL. JS code is quite big and hard to read, but I have found the important part in the Firebug DOM editor.
This is the pattern of the URL generated when you perform the search:
http://www.example.com/...?ParameterOne=123&ParameterTwo=Two&ThisParameter=Sth&ParameterFour=Four...
What I want to edit is "ThisParameter" and change its value. This is the part edited in the DOM that does what I want:
Foobar = {
_options: [],
...
var options = {"ParameterOne":123,"ParameterTwo":"Two","ThisParameter":"ABC","ParameterFour":Four,...}
...
And this is the output of "ThisParameter" when you choose "Copy path" in Firebug's DOM tab:
_options[0].ThisParameter
I am wondering it this is possible at all. What makes me think that it is, is the fact that I can change this parameter in Firebug and it works perfectly. So, if Firebug can edit it, there should be a way to influence it with another script.
Looking forward to any suggestions, thank you in advance!
Since you cannot edit the dynamic script you have the following options:
You have to try to give the script the correct input and hope it uses your value.
Add a script to the results page which will read the url and arguments, change it and redirect, as we discussed here. (If you put everything in functions it should not conflict with the dynamic script if the functions are uniquely named.)
You could try adding something like this jQuery code to the page with the search button:
$('input[name=search_button_name]').click(function(e) {
e.preventDefault();
var form_search = $('#search_form_id');
$('<input>').attr({
type: 'hidden',
name: 'ThisParameter',
value: 'SomethingElse'
}).appendTo(form_search);
f.submit();
});
You can override any js function and method, or wrap you code around it. The easiest thing would be to look at the code you get and once it gets loaded, you re-declare a method with your own functionality.
I you are trying to replace a parameter in a specific jquery request, you can even wrap around the jquerys ajax method:
var jquery_ajax = $.ajax
$.ajax = function(options){
// parse only a specific occurence
if(options.url.indexOf("example.com") > -1) {
// change the url/params object - depending on where the parameter is
options.params.ThisParameter = "My Custom value"
}
// call the original jquery ajax function
jquery_ajax(options);
}
But it would be a lot cleaner to override the method that builds the ajax request rather than the ajax request itself.
I would investigate further on the scope of the variable options (var options), is it global? i.e. if you type 'options' in the Firebug console, does it display its properties?
If so, you could then access it via your own script and change is value, e.g.
options.ThisParameter = 'my-own-value';
You might hook your script to the click event of the search button.
I hope this helps, it could be more specific maybe if you have some sample code somewhere.

How to check if string exists on external page with JavsScript?

I'm trying to check a page (on the same domain) for a specific string and then execute something accordingly. How can I go about this in JavaScript (with jQuery loaded)?
A (maybe too much) simplified schematic:
url = "pageToLoad.php"
if(StringOnPage(url) == TRUE){
// Do a bunch of stuff
}else{
// Do nothing
}
Now how would I construct StringOnPage() ideally? I made several attempts with jQuery's .load and .ajax, I even tried to load it into a hidden container. There must be a way to load the page into a string and check for an expression or something without all the html hacks.
The page is just an HTML populated file. Basically I need to find a text in a DOM element.
Load the page via AJAX as a plain string and then simply check if the string you are looking for is somewhere in the string you got from your AJAX call:
$.get(url, function(data) {
if(data.indexOf('whatever') != -1) {
// do a bunch of stuff
}
}, 'text');
Of course you could also use 'html' instead of 'text'; then data is a jQuery object containing the DOM of the page you just loaded.

Using jQuery on AJAX response data

I'm looking to use jQuery to determine if the current page has changed upstream, and if so, perform some action.
I want to do this by using jQuery selectors over the data returned by an AJAX call (for the purposes of this question, my "page has changed" metric will be "has the content of first <h1> changed").
Thus I find myself wanting to use jQuery selectors over the HTML returned by an AJAX get(). The "best" "solution" I've found thus far is appending the data to some hidden div, and using a selector over that, as below:
var old_title = $('h1').html();
$.get(url, function(data) {
$('#hidden_temporary_storage').append(data);
var new_title = $('#hidden_temporary_storage h1').html();
if (new_title !== old_title) {
do_something();
}
});
This feels so very wrong - I'd be nesting html / head / body tags, and there would be id collisions et cetera.
I have no control over the upstream page, so I can't just "get the data in a more convenient format" alas.
You can do:
var x = $('<div>'+data+'</div>').find('h1').html();
// use x as you like
i.e. you don't need to append the returned data to your page to be able to get properties and values from HTML elements defined within it. This way there would be no id collisions, multiple head/body tags etc.
I think your best bet here is to use an iFrame.
And then use jQuery on the content of that iFrame.
var old_title = $('h1').html();
$.get(url, function(data) {
$('<iframe id="tmpContent"></iframe>').appendTo("html");
$('#tmpContent').contents().find('html').html(data);
var new_title = $('#tmpContent').contents().find('h1').html();
if (new_title !== old_title) {
do_something();
}
$('#tmpContent').remove();
});

Categories

Resources