How to load page synchronously using jQuery - javascript

Currently I am using jQuery to choose what my index page should load depending whether a cookie is set.
For example, the body tag of the index.html should load hasCookie.html if the cookie is set and noCookieSet.html if no cookie is set.
My index page currently has:
load user scripts
load styling scripts
<html><body></body></html>
The user script has the code that checks whether the cookie is set. If it is, I use jQuery's load to load the content into the body:
$(document.body).load('hasCookie.html')
However, since this is executed asynchronously, the styling scripts have loaded before the body tag has been updated, hence the body is not styled.
Is there a way of having a synchronous load, or should am I approaching this in the wrong way?
EDIT: if it helps, the styling scripts are basically jQueryUI

AFAIK, JQuery load cannot be synchronous.
You can cet around this witha callback function.
$(document.body).load('hasCookie.html', function(){
//call styling script here
});

In your case, this sounds like it would really be a better idea to implement server-side if possible. In PHP it would be a simple matter of detecting if the cookie you want is set in the $_COOKIE array and outputting the correct page.

You can form it as an AJAX request and populate your page with the response. Set the async option to false. This SO answer has more: How can I get jQuery to perform a synchronous, rather than asynchronous, Ajax request?

Just change document.location.href to the url of the page.
What you're doing is loading content with ajax and placing it within the page body. You'd do this if you didn't want any resources declared in head to get requested. But there's no point in that since you can do it with caching.

Try
$(document).ready(function() { $(document.body).load('hasCookie.html'); });
This will postpone loading until after everything else is already there.

This is how i do it.
You can attach Style and Javascript upon callback from the Ajax Function.
$.ajax({
url: somePage,
success:function(ajaxData){
//ATTACH AND RUN CORRESPONDING PAGE SCRIPT
var script = somePage + '.js';
$.getScript(script);
//ATTACH CORRESPONDING STYLE SHEET
var style = document.createElement('link');
style.type = 'text/css';
style.href = '/css/'+somePage+'.css';
style.rel = 'stylesheet';
style.media = 'screen';
document.getElementsByTagName('head')[0].appendChild(style);
//ADD HTML RETURNED
$('body').html(ajaxData);
});
This allows everything to be loaded including styles and javascript, given that the script name and css file name are the same.

Related

How do I prevent execution of injected JavaScript after its initial execution?

I am trying to add javascript to my page after ajax call as I have newly created elements from the ajax response and I want them to listen to the javascript. Eveything works okay.
However,for some reason, I want to block that JavaScript functionality at some later point in time.
I have tried removing the script tag from the html using Javascript but it's not being effective. I have even tried using libraries such as
YETT but still i am not able to block the script I intend to block.
Javascript code
<script>
$(document).ready(()=>{
//when the page first loads I append the script (NOTE:I have this inside an ajax call as I am
appending html elements from the ajax call response
const scriptsrc = document.createElement('script')
scriptsrc.setAttribute('type','text/javascript')
scriptsrc.setAttribute('src','./assests/scripts/script.js_r='+Math.random()+Math.pow(10,10).toString(2))
scriptsrc.setAttribute('data-name','myscript')
$('head').append(scriptsrc)
//i do some other stuff here
//I want to block the script that i previously added (./assests/scripts/script.js) below here
})
</script>

How to get the contents of a Third Party lazy loading page?

Via a Chrome extension, I'm trying to get and modify the contents of a third-party page. Everything works for the part of the content that's immediately visible on initial page load.
The problem is that this page has a lazy-load/ajax pagination. To get all of the content I have to click "view all" (ajax link) (and I believe this works essentially the same way as lazy-loading that's why I put that keyword in the title).
Upon clicking that link (on that third-party website) all content gets loaded and becomes visible to the user but when I view source there's still only the originally loaded content present in the source code. i.e. none of the freshly loaded content can be found anywhere when I view page source after the new content has been loaded. The content is visible to the end user but not visible to me when I check the source code.
Initially, I tried to overcome the problem by using setInteval and checking the page content every second but as that wasn't working I checked the source code and sure enough, none of the newly loaded content is visible in the source code. No wonder my Chrome extension can't get that content.
Another confusing thing I just realized when typing here:
When I view source code, even the initial HTML content that my Chrome extension is detecting/loading is NOT actually present in the source code! It actually sits in a JavaScript array. So, somehow, my Chrome extension is correctly getting the initial HTML content that's constructed from that JS array. But it's NOT getting the content that gets loaded after clicking the "view all" ajax link on that page (even though I'm using setInteval and checking for new content every second).
What are possible solutions for this?
I can't post the link to the page because it's the "my certificates" page on Lynda.com and I don't know of a publicly accessible website/page with the same behavior.
you should find the actual service running in network-panel, when lazy loading happens, and then follow following code
//recursively make calls and gatther responses. cb is callback to run on response, end is end page-no (end of recursion condition) , pageId is the attribute changing in every subsequent lazy-loading call.
var callIfRequiredConfigured = ({cb,end,step=1,pageURL,pageId})=>callIfRequired = ()=>{
currentCounter = currentCounter + step;
if (currentCounter > end) {
return;
}
(async(currentCounter)=>{
queueCounter++;
//modify this as needed
const r = await fetch(pageURL+currentCounter,{credentials:"same-origin"});
//queueCounter to not make more than 6 calls at once
if (queueCounter > 6) {
return;
}
var response = await r.text();
cb(response);
queueCounter--;
callIfRequired();
}
)(currentCounter);
};
var call = (config)=>{
const callIfRequired = callIfRequiredConfigured(config);
callIfRequired();
}
call({
cb: (response)=>{
//do somrthing with response
}
,
end: 50,
step: 1,
pageId: 'PageNumber=',
pageURL: `https://www.lynda.com/home/CertificateOfCompletion/GetCertificatesByFilter?Start=0&Limit=99999&SortBy=CompletionDate&SortByOrder=1&_=[my_personal_id]&PageNumber=`
});
So main effort will be to deduce the service endpoint here and how it changes in subsequest requests. I have updated the url given in comments, but see if the fetch call is successful. Also this url should also have [my_personal_id] as given in url.

Re-execute js on back without reloading the whole page

Is there a way to re-execute JS without refreshing a page?
Say if I have a parent page and an inside page. When the inside page gets called, it gets called via ajax, replacing the content of the parent page. When user clicks back, I would like to navigate them back to the parent page without having to reload the page. But, the parent page UI relies on javascript so after they click back, I would like to re-execute the parent page's javascript. Is this possible?
Edit: Here is some code. I wrap my code in a function but where and how would you call this function?
function executeGlobJs() {
alert("js reload success");
}
You could use the html5 history-api:
In your click-handler you'll call the pushState-method, stat stores the current state for later reuse:
$(document).on('click', 'a.link', function () {
// some ajax magic here to load the page content
// plus something that replaces the content...
// execute your custom javascript stuff that should be called again
executeGlobJs()
// replace the browser-url to the new url
// maybe a link where the user has clicked
history.pushState(data, title, url);
})
...later if the user browses back:
$(window).on('popstate', function () {
// the user has navigated back,
// load the content again (either via ajax or from an cache-object)
// execute your custom stuff here...
executeGlobJs()
})
This is a pretty simple example and of course not perfect!
You should read more about it here:
https://css-tricks.com/using-the-html5-history-api/
https://developer.mozilla.org/en-US/docs/Web/API/History_API
For the ajax and DOM-related parts, you should need to learn a bit about jQuery http://api.jquery.com/jquery.ajax/. (It's all about the magic dollar sign)
Another option would be the hashchange-event, if you've to support older browsers...
You can encapsulate all your javascript into a function, and call this function on page load.
And eventually this will give you control of re-executing entire javascript without reloading the page.
This is common practise when you use any concat utility (eg. Gulp)
If you want to reload the script files as if it would be on a page reload, habe a look at this.
For all other script functions needed, just create a wrapper function as #s4n989 and #Rudolf Manusadzhyan wrote it. Then execute that function when you need to reinit your page.
I'm having the same problem I don't use jquery.
I don't have a solution yet. I think that your problem is that it doesn't read all the document.getelements after you add content, so my idea is to put all the element declarations in a function. And than after the ajax call ends to call the function to get all the elements again.
So it might be something like that
Func getElems(){
const elem= document.getelementsby...
Const elem.....
At the end of the js file make a call for
the function
getelems()
And than at the end of the event of the
ajax call. Just call the function again.
Sorry that is something that comes to my mind on the fly while reading and thinking on the problem i have too:).
Hope it helped I will try it too when I will be on the computer :)
I believe you are looking for a function called
.preventDefault();
Here's a link to better explain what it does - https://api.jquery.com/event.preventdefault/
Hope this helps!
EDIT:
By the way, if you want to execute the JS on back you can wrap the script inside of
$('.your-div').on('load', function(e) {
e.preventDefault();
//your JavaScript goes here
}

In HTML, if you load the same script file a second time, will it still be loaded?

Say you have the following in an HTML file:
<script type="text/javascript" src="whatever.js"></script>
<script type="text/javascript" src="whatever.js"></script>
Will whatever.js be loaded a second time, or will the browser see that it's already been loaded and skip re-loading it?
NOTE: This has come up for me because I'm using HTML templates which include other code snippets, some of which may load the same scripts, leading to possible duplication. I want to make sure my pages aren't weighed down by duplicate script loads.
It depends on what you mean by "skipping" the loading.
If you want to avoid hitting the server twice then setting up proper cache controls on the server will avoid the file from being downloaded twice.
If you want to avoid the file from being executed twice then the answer is no: the browser will not skip executing the file the second time. You can get around this by wrapping the file in a giant 'if' statement and check for a global variable or HTML element to test if the file have been loaded before.
Yes, it will reload it. What you can do is checking whether the current script element is already apparent in a "loaded" list that you keep track of: http://jsfiddle.net/kvPcU/1/.
Somewhere on the top of your page, before you fetch the files:
var loaded = {};
Then:
var elements = document.getElementsByTagName('script');
var currentElement = elements[elements.length - 1]; // element of currently executing script
if(!loaded[currentElement.src]) {
loaded[currentElement.src] = true;
// run code
}

jQuery replace all HTML

I'm trying to replace all the HTML (including the HTML tags) with another page. What I'm trying to do is having a website acting as an app even when navigating the another page.
Here is the code :
(function($) {
Drupal.behaviors.loadingPage = {
attach: function(context,settings) {
$('a').click(function(event) {
event.preventDefault();
// Create the loading icon
// ...
$.ajax({
url: $(this).attr('href'),
success: function(data) {
$('html').replaceWith(data);
}
});
});
}
};
})(jQuery);
I've tried several things. replaceWith() causes a jQuery error in jquery.js after deleting the HTML tag, I guess it is because it can't find the parent anymore to add the replacement.
The best result I got was with document.write(data). The problem is, the javascript code on the loaded page is not executed.
Anyone got a better idea ?
A better idea? Yeah, just load the new page normally by setting window.location instead of using AJAX. Or submit a form.
Otherwise, if you want to load something to replace all of the visible content of the current page but keep the current page's script going, put all the visible content in a frame sized to fill the browser window - which, again, you wouldn't populate using AJAX.
(I like AJAX, but I don't see why you'd use it to replace a whole page.)

Categories