Not sure the best way to phrase the question, but suppose you are using jQuery to setup various things like so:
<script>
function doSecond(){
alert("Hi");
}
function dofirst(){
var x = asdasd;
}
$(dofirst);
$(doSecond);
</script>
So, imagine that dofirst and dosecond are completely independent. If dofirst throws an exception, which of course it will, then doSecond will never fire. I understand why this happens, but I'm wondering if there is a way of getting around this without having to wrap EVERY kind of jQuery handler that I want to set up in a try catch. E.g., I'd rather not do:
try{
$(doFirst);
}
catch{
//maybe log here?
}
try{
$(doSecond);
}
catch{
//maybe log here?
}
Now, if you're wondering why I want to do this? Well, take for example the code on the page you're looking at right now:
<script type="text/javascript">
$(function() {
$('#title').focus(function() { $('#how-to-tag').hide(); $('#how-to-format').hide(); $('#how-to-title').fadeIn('slow'); });
$('#wmd-input').focus(function() { $('#how-to-tag').hide(); $('#how-to-format').fadeIn('slow'); $('#how-to-title').hide(); });
$('#tagnames').focus(function() { $('#how-to-tag').fadeIn('slow'); $('#how-to-format').hide(); $('#how-to-title').hide(); });
});
</script>
Is it really necessary to have certain dom elements fade out when you click on them? No. But if you make a mistake in that function, then quite possibly other javascript that you really, really do need to run may never get setup.
A couple of ways to ensure things run independently of each other:
As you said, try/catch around each
Call each in a setTimeout (or
whatever the jQuery syntactic sugar
is for that)
Separate into different <script>
blocks
Obviously not ever throwing an exception is a ridiculous suggestion. Especially in the world of many browsers/versions/servers up/servers down. There are so many ways of website JS to break it's hard to find a site of any size which doesn't throw an exception of some type (on console examination).
You could create a simple wrapper (or extend existing jQuery methods)
function safeonload(fn){
$(function(){
try{
fn();
}catch{
//log?
}
});
}
safeonload(doFirst);
safeonload(doSecond);
Related
I am making a website where depending on what a column says in the database the javascript will perform a curtain task (using ajax). This is going fine, however in the if statement, when the requirements are met, it keeps repeating it since it's inside the setInterval. It is probably easier for me to just paste the code and give you a chance to take a look at it.
setInterval(function(){
$("#div").load("content.php");
if ($('#div:contains("hello")').length > 0) {
alert("Hello, world!");
}
}, 200);
As you can see above, the alert is alerted forever at the speed the interval is set to. Sorry if I have been unclear, I have no idea how to ask questions properly on forums.
I assume you use the setInterval to check if the div has gotten its content already.
This can be solved with a callback (or a promise)
The load method of jQuery (which you are using) offers a callback function "complete". See
http://api.jquery.com/load/
$("#div").load("content.php", {}, function(){alert(1)});
I think you have a lack of understanding of how to approach this task from the outset. I would suggest you look in to how asynchronous operations work in javascript.
What you're trying to achieve here can be achieved with something like this:
$.get("content.php", function( data ) {
$("div").html(data);
if (data.indexOf("hello") > -1) {
alert("Hello, world");
}
});
I have a web element that only appears while the page (or a part of the page) is still loading and disappears when the page has been completely loaded. I would like to see precisely when this element disappears and I can do that by repeatedly running something like that in the browser console:
$("div.v-app-loading")
or alternatively:
document.getElementsByClassName('v-app-loading')
But in most cases everything happens too fast and I am unable to catch the exact moment. There must be a way to create a loop that will just run in the console and execute one of the commands I mentioned say every 0.5sec or even more frequently.
Could anyone point me to the right direction?
You can use Javascript's setInterval() as following:
function yourFunction(){
//do something here...
}
setInterval(yourFunction, 500); //Will run the function every half a second(500ms = 0.5s)
Maybe it's easier to use jQuery to detect when the page is loaded:
HTML
<body class="loading">
JS
// do something initially here
$(window).load(function () {
// do something when finished loading
$('body').removeClass('loading');
});
Edit: If you rather wanted to check for existence of an elemtent, do it in a recursive function call. You can throttle it with setTimeout, but you don't need to:
function checkElement() {
if ($('.v-app-loading').length) {
checkElement();
// or: setTimeout(checkElement, 100);
} else {
// Element disappeared
}
}
checkElement();
I am trying something like this
<div onclick="check_update('personal_details') ; showUser(2)">Click me </div>
but only check_update('personal_details') is getting called . I want to execute two separate functions at the same time when DIV is clicked. Any help will be great for me as I am still in a learning phase. Thanks in advance.
You can't execute two functions at the same time. JavaScript in a web browser is single threaded.
The code you have will execute the functions sequentially, providing that the first one doesn't throw an exception and terminate the execution.
If it does throw an exception then you should try to resolve that. As a brute force hack:
try {
check_update('personal_details') ;
} catch (e) {
alert("Oh no! An exception! " + e);
}
showUser(2);
… but preventing the error in the first place is, obviously, a better solution!
You're question is tagged as jQuery, so I'm going to assume you're using it. In that case, you shouldn't be using the onclick attribute at all. This would be the correct way to write the code from a jQuery perspective:
<div id="yourId">Click me</div>
<script type="text/javascript">
$('#yourId').click(function(e) {
e.preventDefault();
check_update('personal_details');
showUser(2);
});
</script>
Use a function within a closure. Replace otherFunction with the name of the second function you'd like to call and everything should work as expected.
<div onclick="(function(){check_update('personal_details'); otherFunction(); })()">Click me </div>
I'm finding that with asynchronous callbacks I'm needing to write a try/catch for each callback function. It seems a bit error prone is there a method or technique whereby I can implement a single top level try/catch that catches everything? If not is the technique that I'm using considered good practice or is there a better way to do things?
There is two ways of doing this:
Set the window's onerror attribute
called with three arguments (message, url, lineNumber)
returning true(!) prevents the default error handling (making this something like a catch-all)
Add an error event listener to window
called with an Error event e as its sole argument
Calling e.preventDefault() prevents default error handling
If not is the technique that I'm using considered good practice or is there a better way to do things?
Due to the dynamic nature of JavaScript, try/catch is very slow. There's almost always better ways, for example: check if something exists before calling a method on it.
// bad
try {
document.getElementById('foo').focus();
} catch(e) {
alert('foo not found');
}
//good
var el = document.getElementById('foo');
if (el) {
el.focus();
} else {
alert('foo not found');
}
For your specific situation, please show some of your code; maybe in a separate question.
Nope, don't do it catch-all, that almost always results in problems (because you can't differentiate between exceptions very well).
It probably isn't a good idea to depend on a global catch all, but it isn't a bad idea to have one (in the case where an error is thrown where you might not expect). This way you can handle uncaught errors the way you would like to.
Using jQuery:
$(window).error(function (msg, url, line) {
//do something
});
So my issue is pretty straight forward, since there is seemingly no callback for after a .css is executed, what options do I have for making performing something after a task is done?
I'm creating a simple lightbox, and I need to wait for the center align to finish...
$("#img_lightbox").css("top", top);
So when that completes, I then need to fade in the whole thing, but since there is no callback option (to the best of my knowledge) it will occasionally start fading in before the alignment finishes... how can this prevented?
Any help is appreciated, thank you.
Anything being chained with your jQuery object will execute after the function before it. The easiest way to accomplish what you are asking is with Plugins.
jQuery.fn.myPlugin = function () {
//code to execute
return this;
}
$("#img_lightbox").css("top", top).myPlugin();
You could even write a plugin to execute a custom function, so you do not need to create plugins for every function you might happen to need to run:
jQuery.fn.myCallback= function (callback) {
this.each(function () {
callback.call($(this));
});
return this;
}
$("#img_lightbox").css("top", top).myCallback(function () {
// some code to run where this = $("#img_lightbox")
});
But incase I am still misunderstanding, you may be wanting a callback for your fade function: (otherwise please clarify more)
$("#img_lightbox").fadeIn('slow', function () {
$(this).css("top", top)
});
Adding and removing CSS styles are synchronous functions -- there is no callback because the next statement will be executed once the style has been applied. Rendering of the updated style is slightly different, since that will happen during the next repaint, but unless you're doing some serious number-crunching in your UI code, the difference would be completely unnoticeable. In any case, it would be applied before the 'fading in' starts to happen.
If you're seeing something wrong with your display, I'd suggest that the problem lies elsewhere.
jQuery provides you with a way to tell once the document is "ready" and in the correct state to execute code correctly. Use one of the following:
$(document).ready(function(){
//your code here
});
or the shorter,
$(function(){
//your code here
});
More information at http://api.jquery.com/ready/