I have a front-end script that alerts when a link is clicked. The problem is, the link that my script looks for is loaded on the page via a knockout template, and I can't get my script to run after that happens.
I am not able to execute this within knockout, unfortunately, it must be done within my front-end CMS. Not ideal, I know.
Is there any way to work around knockout and ensure my script runs AFTER the knockout template has finished loading? I got it to work with a timeout, but that's not ideal. I've also tried docready, onload, etc, and no dice.
My script is very simple, I'm wondering if there is something specific to knockout that I can wrap it in...
$('.myLink').on('click', function(event) {
var foo = $(this).text();
alert(foo);
});
You could attach the event handler to an ancestor that does exist on the page on page load and create a delegated event handler:
$(document.body).on('click', '.myLink', function (event) {
/* ... */
});
Related
I am trying some hands on with javascript core concepts and came across this interesting thought. When I use the native javascript and try executing some events on the document load as below I get an error:
document.addEventListener('load',function(){ //this doesn't alert doesn't get fired
alert("document load event listener fired!");
});
But if I change the above code as below it works:
window.addEventListener('load',function(){//this works alert gets fired
alert("Window load event listener fired!");
});
A possible explanation that comes to my mind is that the window the parent object in browser object model is loaded the first before anything else can be ready or accessed.
However in jQuery (something I have been more comfortable with) the syntax clearly starts with document as below:
$(document).ready(function() {
// some code here
});
I guess jQuery has an inbuilt wrapper around $(document) which actually takes care of firing the window load event before any further code mentioned inside it can be executed.
Is my understanding correct?
I have this code (accepted solution).
This code snipped loads from a js file. When I put a breakpoint at this function, I see that this function getting called when the page (that includes it) is loaded.
After the initial page load, when I choose an option in this page, that anchor element is reloaded (Ajax) exactly same (js file does not reload) as part of the piece of data. However, now when I click on anchor link, it does not fire / open the outlook window.
Is it something about jQuery functionality that I am mis reading/using?
How do I resolve this?
If the element is reloaded you'll need to rebind the click event to it.
Alternatively to the way you are doing it you could bind to the window/body and just specify the id as the selector like this:
$('body').on('click', '#emailLink', function (event) {
// your code here...
});
I know I can inject the script when the user clicks an element by creating a script element and injecting it on the page via document.appendChild. However, the script is listening for onload and onDOMContentReady (or their own home grown domReady event, not sure).
If I inject the script only when the user clicks an element, the callbacks for onload/onDOMContentReady will never fire because those events have already passed.
Any ideas? This 3rd party script pulls in all these other requests and it's not optimal for page loading.
EDIT: I read the question again...and if you are using something like jQuery, it will fire your handler function in any other document ready calls even if document ready has already been fired. It will just execute the function right away. If you are looking for a pure javascript way to do it, you need to take extra consideration to check to see if dom ready has already been fired, and fire your function yourself, otherwise attach it to the dom ready callback.
I don't see a problem with just doing something like this (with jquery for brevity):
// on document ready
$( function() {
// attach the click handler
$('#loadScript').click( function( e ) {
// on click, get the script
$.getScript('path/to/your/script.js', function() {
// your script is loaded, so what you need from here
// to handle this click event.
});
});
});
I think you are over thinking it a bit. You only need to worry about making it possible to load the script once the dom elements are ready. You could look at using something like require.js as well.
I am making a book, and use jQuery to change pages etc.
At the top I have an $(document).ready(function() that does different stuff when the page is loaded.
On the GUI page I got a "change page" button, and when this is pushed, the function turnPage() is called. This method contain some code pluss this:
$.mobile.changePage("#device"+window.device, {
transition: "slide",
reverse: false,
changeHash: true
});
My question is, when turnPage() is called, is also $(document).ready(function() called?
(Yes, I am new to this)
DOM ready event is an event that fires when the DOM is fully loaded except of images (<img>).
The event fires once for each page load. So:
If the turn page() function makes a redirect, the answer is Yes.
If the turn page() function only gets data with ajax request, the answer is No.
Important Update:
I found this in the official plugin website :
Important: Use pageInit(), not $(document).ready()
The first thing you learn in jQuery is to call code inside the $(document).ready() function so everything will execute as soon as the DOM is loaded. However, in jQuery Mobile, Ajax is used to load the contents of each page into the DOM as you navigate, and the DOM ready handler only executes for the first page. To execute code whenever a new page is loaded and created, you can bind to the pageinit event.
...
...
So turn page does an ajax request, so the final answer is No.
What is the ready event:
While JavaScript provides the load event for executing code when a page is rendered, this event does not get triggered until all assets such as images have been completely received. In most cases, the script can be run as soon as the DOM hierarchy has been fully constructed. The handler passed to .ready() is guaranteed to be executed after the DOM is ready, so this is usually the best place to attach all other event handlers and run other jQuery code. When using scripts that rely on the value of CSS style properties, it's important to reference external.
Hard to summarize in one question, but here are the details:
I have an ASP.NET MVC 3 project (many of them actually).
My standard practice is for each view to have an Init() method that is fired when the document is ready. This is where I put all my UI code, like rendering buttons and accordions, etc.
I am using the trick to hide un-formatted html elements by setting the html tag to display: none and after Init() is complete, I can unhide everything.
This works pretty well, but I initially had the showing of content in my layout page, but that would execute before the Init code of a view finished running. It gets even more complex if I use partial views with their own Javascript.
What I would like is to attach a callback in one place that fires after the all of my possible Init() calls are finished.
I tried using custom events, but then I would have to trigger them at the end of every Init method, and that's not very efficient.
Requested Code:
Layout Page
<script>
$("html").addClass('init') // init has display: none
$(function() {
InitLayout() // Basic stuff for every page like menu, buttons, etc
$("html").removeClass('init'); // show all content
});
</script>
View Page
<script>
$(function() {
ViewInit() // Init all custom ui elements on page: tabs, accordions, etc
});
</script>
The problem is that the removeClass will occur before each page's Init fires. I am trying to find a way to avoid having the removeClass call at the bottom of every Init method. Is there some way to attach a callback programmatically to avoid repeating code. My main goal here is to implement hiding of unstyled content until everything is complete globally so I don't have to worry about it in each view.
You could try to register the occurence of the init procedure into a global variable (array). This should be done outside of the document.ready() or JQuery equivalent. So within the <script> tags.
When your Init functions, inside the document.ready() event handler or it's JQuery equivalent , are finished, unregister the occurence.
While unregistering, check if there are any occurences left, if not, modify your html style.
The gap between script parsing and the DOM actual finishes loading could be working for you in this case.