I have an aspx page that includes a javascript file in the head tag. This page has a user control placed on it. The user control has a link with an inline javascript function that references an object that is defined in the javascript file loaded on aspx page.
The application consists of a master page and a number of other aspx pages. The page in question (with the javascript file) loads before any other page, and the link with the javascript file is rendered. However, if I click on the link, I get an error, saying "Microsoft JScript runtime error: 'Foo' is undefined". Where foo is an object defined in the javascript file. However, if I wait until all the parts of the page are loaded, the link works fine. What is happening here? How can I prevent this error from happening?
Thanks.
if I wait until all the parts of the page are loaded, the link works fine
That says to me the browser hasn't finished retrieving and executing the js file by the time you have clicked the link with the inline function.
One potential solution is to wait until the page has loaded to attach your click handler:
window.onload = function() {
var link = document.getElementById('myLink');
link.onclick = function() {
// on click logic
}
}
This is just an example. This would be placed along inside your js file so as to load all dependencies at once.
It's a little hard to be more specific as you've generalized quite a bit in your question.
Related
I have a script.js file linked to all of the pages on my site.
On only one page in particular, the "About" page, I don't want a certain function from script.js, called myFunction, to run, because it messes with the formatting on that page.
However, I do still need to use the rest of the JS from script.js on this page, so I don't want to unlink the script.js file and copy every single line of code from script.js except myFunction onto the About page locally, as then I will need to update that page manually every time I add new JS to the script.js file.
Is there a way to tell a specific page to ignore a certain function from script.js? I thought this would be easy to find an answer to but all I could find were results for doing this in WordPress with php.
I would like to use vanilla JS if possible.
Add this code where you call your function on script.js
var pathname = window.location.pathname;
if(pathname != 'about.html'){
myFunction();
}
Please Help.
Question: Can I dynamically load a JS file (/scripts/banner.js) and then use one of its functions -- writeBanner(document, t1, t2, t3) -- to finish writing the page?
I've read till my eyes bleed, but:
-- Every example I find assumes the reader will call a function AFTER the page is rendered, and
-- Every example assumes blocking is bad.
Unfortunately:
-- I need to call the functions in order to finish writing the page that loaded them, and
-- Blocking is not a problem. The app is deployed as an EAR file, so no JS files need thereafter be downloaded from anywhere else.
Why try to do this?
The initial window ("TAPP") loads a dozen functions from 6 JS files. All pages use them to write HTML in the page's body element that displays a consistent banner with up to 3 paramaterized title lines.
Level-1 Pages: These are opened in the initial ("TAPP") window by each other. It already has all functions loaded – works perfectly.
Level-2 pages: These are opened in pop-up windows opened by level-1 pages. They use "this.opener", i.e. "TAPP" to call those functions – works perfectly.
Now I want to be able to open Level-2 pages both
-- as pop-ups from a level-2 page, AND
-- as free standing pages.
NOTE: All level-2 pages.jsp being with this include to write the HEAD element:
<%# include file='/jsp-pages/level-2/headers/beg.jsp' %>
That way I only need to deal with scripting for all of them, in one place, at one time.
First Step: I added this code to beg.jsp:
<script language="javascript">
var SH = "";
if (this.opener && this.opener.name == "TAPP") {
SH = this.opener; // TAPP has all required functions
} else {
//Dynamically add the required <script> elements
/************************************/
// see code I tried below
/************************************/
SH = this; // "this" now has all the functions TAPP has
// alert ("Opener is NOT TAPP: " + SH);
}
// All pages can now call SH.writeBanner(document, t1,t2, t3) with their own titles
</script>
Here's the rub. When the alert () function above is uncommented BOTH tries (DOM and document.write() below) work perfectly. When it is commented out, level-2 pages opened as pop ups work perfectly BUT when opened as free standing pages do NOT write their titles. Obviously they are being rendered before the script is loaded.
My Tries to date:
-- Give up! Skip the code above. Hard-code six additional tags in "/jsp-pages/level-2/headers/beg.jsp" that will reload the functions in the six JS files every time any level-2 page is opened Either way.
Ugly, inelegant, redundant, a waste if the page is opened as a pop-up, to be avoided at all cost.
-- When TAPP is not this.opener, use DOM to load the JS files by adding script elements at the end of
<script type="text/javascript">
function dynamicload(){
var head = document.getElementsByTagName("head")[0];
var script = document.createElement('script');
script.setAttribute("type","text/javascript");
script.setAttribute("src", "/scripts/banner.js");
script.async = false; // halt rendering until writeBanner() is loaded?
head.appendChild(script);
//alert ("DL Done");
}
dynamicload();
</script>
-- When TAPP is not this.opener, use document.write() to write the six scripts.
<script type="text/javascript">
document.write('<SCR'+'IPT src="/scripts/banner.js '><\/SCR'+'IPT>');
// and six more like it
</script>
So HELP!
Is it really NOT possible to use dynamically loaded functions to finish writing the page that dynamically loaded them?
glb
You can add things to the current page using dynamically loaded code. But, you cannot use document.write() to do so. You must add DOM elements directly to the page with methods like .appendChild() or .insertBefore() or set .innerHTML on an existing DOM element.
The problem with document.write() is that once the page had been loaded (and thus the document stream closed), any future calls to document.write() will clear the current page and start writing to a new, blank page which general ruins what you are trying to do.
And, when you dynamically load code, it will load AFTER the current document has finished loading.
document.write() is intended to insert content at the current location in the document stream while the document is in the process of loading which only works when the script is present in the original HTML either as a <script> tag or it can be used on a brand new document (such as the creation of a new iframe or new window).
Simple answer. You can't.
A page cannot load JS files with functions it needs to write the rest of the page.
No matter how you script to load the JS files -- add a script element with DOM, or write it in with document.write() -- the JS files end up being loaded AFTER the page is loaded when it is too late to write the page. (See discussion with nothingnecessarey.)
However, it still bothers me that if I throw an alert() in my the script, both conditional approaches work – DOM and document.write() -- i.e. I had titles! All I can think of is the alert causes the page to re-render itself and since the alert is called after the page is loaded, the JS files are loaded.
Thanks to all for their help
AFTERTHOUGHT: I dreamed that opening an empty page with an iFrame to load my level-2 might work. If so I'll return. If not ... I give up.
Here's my conundrum:
My website uses PJAX to load HTML into the '#main' container for each page.
Each page has its own specific javascript file. E.g: 'dashboard.index.js', 'inbox.index.js' and so on.
Note: All libraries are preloaded on the first load of the page through PreloadJS to avoid javascript compilation overhead.
The first load of the page is perfect, no worries, since it is a normal HTML load.
However if i come back to this page again, PJAX won't reload the javascript file, given it's already in the DOM.
What i tried so far & didn't work perfectly:
Place javascript file at the bottom of 'main' container. PJAX transfers it to the 'HEAD' of the DOM and won't load it the second time around.
Place in-line scripts in the 'main' container to execute functions of each page. Fails since the code is executed before JS libraries are loaded.
Bind 'PJAX success' event and execute function. Unable to determine which function to execute based on current loaded page.
Hence, my question:
Is there any strategy to load specific javascript files associated to each page?
When loading HTML from pjax, i added a 'data-js' attribute to the div, which contained the name of the function to call upon successfully loading HTML.
Then it was just a matter of using the 'pjax:success' event to call the function.
I'm using Rails 4. I have a javascript file, app/assets/javascripts/exotic_fonts.js, which adds some javascript functionality to fonts. When I load the homepage this javascript file is automatically loaded on the homepage, however it's not loaded automatically on other pages such as /user/show and the functionality is missing. However if I refresh the page, then the javascript file is loaded and the functionality is back. I was wondering how I can fix it.
Also, is it possible to load only some of the javascript files on a certain page?
Thanks.
You can use following snippet to fix this issue. Now your js code will works with turbolinks.
ready = ->
// Your javascriptcode goes here
$(document).ready(ready)
$(document).on('page:load', ready)
I have a Wordpress site set up on my local machine where I'm building a custom theme. In an 'enqueue-assets.php' file, I am using wp_enqueue_script to load a main bundle javascript file. In that bundle are additional imports of other .js files. In one of the imported .js files is the following function:
function svgPageJump(target){
alert(target);
}
I also tried assigning the function to variable, just to make sure I got the same results explained below:
let svgPageJump = function(target){
alert(target);
};
and
var svgPageJump = function(target){
alert(target);
};
When I call this function in the same .js file with .ready():
$(document).ready(function(){
svgPageJump('section-plan');
});
I get the alert when the page loads, as expected. I also get the alert by just calling it after the function declaration (also as expected.)
Unfortunately this isn't working on click events elsewhere on the page. Ultimately I'm trying to get these events to fire when clicking elements in a SVG, to create page jumps. On the clickable elements I'm using:
onclick="top.svgPageJump('section-plan');"
Clicking on the element gives me this error:
Uncaught TypeError: top.svgPageJump is not a function
at SVGGElement.onclick
At first I thought it was a targeting issue from the SVG, but I did another test on a bit of text elsewhere on the page. In a Gutenburg Heading Block in a Wordpress Page, I placed the following markup using the HTML editor for the block:
<h2 id="section-plan" onclick="svgPageJump('section-plan');">PLAN</h2>
I also did this in a Custom HTML Block, but either way when I click the h2 on the actual page I get this error:
Uncaught ReferenceError: svgPageJump is not defined
at HTMLHeadingElement.onclick
I'm obviously missing something (probably something simple) but not sure how to track the problem down between the theme's files (which are all working correctly otherwise) or the event being defined in the page via the Wordpress admin, or...?
Another note on this... I originally used the simpler approach to making these page jumps using anchor tags and associated ids. This worked fine but I have a sticky header on the page so when the page scrolls, the element with the id scrolls under the header so I am attempting to use JavaScript/jQuery to account for the header height.
Thanks!
As per this question (which I'd close as a duplicate of it if has an upvoted answer):
var in the top level of a non-module script will create a property on the window object. So will using a function declaration. You can access this from a frame via top.
let does not create a property on the window object, so you can't access it that way if you use let.