i have a problem with this script in firefox 4. I test the same script in chrome and it works, but in FF the load never stops, maybe some problem with the code
<script type="text/javascript">
$(document).ready(function(){
var somevar = 'some info';
var someothervar = 'some other info';
var data = "var1=somevar&var2=someothervar";
$.post("chart.php", data, function(theResponse){
if (theResponse == 'sim') {
document.write("test");
}
else {
document.write("testone");
}
});
});
</script>
php file have a simple echo "sim";
thanks
You really can't get away with using "document.write()" for such testing. Change your code like this:
$(document).ready(function(){
var somevar = 'some info';
var someothervar = 'some other info';
var data = "var1=somevar&var2=someothervar";
$.post("chart.php", data, function(theResponse){
if (theResponse == 'sim') {
alert("test");
}
else {
alert("testone");
}
});
});
Because the response to the request is very likely to be received after the browser has finished with the original page, the call to "document.write()" will have the effect of obliterating that page.
Beyond that, you can try the TamperData plugin for Firefox (if it's been updated for FF4 ...) to watch the progress of HTTP requests. FireBug will show you XHR requests too.
Related
I am new to Firefox addon development.
I need a way to call a contentscript function from main.js in firefox addon.
I have injected contentscript xyz.js on every opening webpage.
I want to call function abc() present in my contentscript xyz.js from my main.js on click of a button which i have place in navigation toolbar.
Below is my code.
Main.js
..
function addToolbarButton() {
var document = mediator.getMostRecentWindow('navigator:browser').document;
var navBar = document.getElementById('nav-bar');
if (!navBar) {
return;
}
var btn = document.createElement('toolbarbutton');
btn.setAttribute('id', 'mybutton-id');
btn.setAttribute('type', 'button');
btn.setAttribute('class', 'toolbarbutton-1');
btn.setAttribute('image', data.url('icon_16.png'));
btn.setAttribute('orient', 'vertical');
btn.setAttribute('label', 'Test');
btn.addEventListener('click', function() {
tabs.activeTab.attach({
//
abc() //here i want to call the function present in my contentscript
//
});
}, false)
navBar.appendChild(btn);
}
..
xyz.js
..
function abc(){
//here is my code logic
}
..
I came to know that message passing is way to do so but unable to implement in firefox.
Please help me i have got stuckd.
You cannot call the function directly, you need to send a message to the content script. Meaning something like that:
var worker = tabs.activeTab.attach({
...
});
// Some time later
worker.postMessage("doABC");
And in the content script:
self.on("message", function(message) {
if (message == "doABC")
abc();
});
For more information on communicating with content scripts see documentation.
According to documentation it should work this way;
However I have similar question Accessing pre-loaded content script from ActionButton not yet resolved.
// main.js
function handleClick(state) {
var myWorker = tabs.activeTab.attach({
});
myWorker.port.emit("initialize", "Message from the add-on");
}
// content.js
/*BEGIN Listen events coming from Add-on script*/
self.port.on("initialize", function () {
alert('self.port.on("initialize")');
return;
});
I have a tricky problem with Google Chrome Browser.
I have the folowing HTML node:
<div class="result-req-chat pointer float-right" onclick="chat.addUser(this/*, other vars*/)" ><img src="/images/profile_icon_4.png" alt="" /></div>
On the click event it triggers the chat object's method
this.addUser = function(trigger_node, id, is_silent, session, show_block_message){
if(trigger_node){
this.bk_trigger_node.html = trigger_node.innerHTML;
this.bk_trigger_node.cn = trigger_node.className;
trigger_node.innerHTML = '';
jQuery(trigger_node).addClass("loader");
jQuery(trigger_node).removeClass("bpurple");
jQuery(trigger_node).removeClass("bgray");
jQuery(trigger_node).removeClass("button");
}
//alert('if this is executed then it displays the previous changes of the node');
if(trigger_node.innerHTML == ''){
this.addUserToChat(id, is_silent, session, show_block_message);
}
if(trigger_node){
trigger_node.innerHTML = this.bk_trigger_node.html;
trigger_node.className =this.bk_trigger_node.cn;
}
}
addUserToChat():
this.addUserToChat = function (id, is_silent, session, show_block_message){
var response = this.chat_tabs.addTab(id, null);
if(response.error){
callUrl("/me/chat/remove-session/id/"+id);
this.chat_tabs.removeTab(id);
if(show_block_message) alert(response.message);
}else{
this.createTabsBar();
if(!is_silent){
this.switchTab(id);
this.resetContainer(is_silent);
}
if(id == this.chat_tabs.active_tab){
this.active_chat_obj.refresh(session);
}
if(this.closed){
if(this.stop_check){
return;
}
this.resetContainer();
this.switchTab(id);
}
callUrl("/me/chat/add-session/id/"+id);
}
}
chat_tabs.addTab():
// creates and adds the a tab
this.addTab = function(id,name,user_data,session){
var exists = this.getTab(id);
if(!exists){
if(session){
var user_session_id = session.id;
var user_session_data = session.data;
}else{
var session = this.createSession(id);
if(session.error){
return session;
}
var user_session_id = session.id;
var user_session_data = session.data;
}
if(name){
var user_name = name;
}else{
var user_name = this.getName(id);
}
if(user_data){
var user_data = user_data;
}else{
var user_data = this.getData(id);
}
var ob = new Object({
user_id: id,
user_name: user_name,
user_data: user_data,
user_session_id: user_session_id,
user_session_data: user_session_data,
has_new:false,
chat_screen: new ChatScreen(session, id, user_name, user_data, this.main_user_id, this.main_user_photo)
});
this.chat_users.push(ob);
return ob;
}else{
return exists;
}
}
callUrl():
function getUrl(url){
return jQuery.ajax({ type: 'GET', url: url, async: false }).responseText;
}
The point is that the method addUserToChat() contains a syncronous Ajax call.
The problem with Chrome is that the trigger_node changes aren't displayed. If you watch with the built-in JS debuger then everithing goes ok ( even with displaying ) .Also if you uncomment the alert.
It runs on Mozilla ( latest version ).Also the Crome is the latest version.
I can observe that in the time that it waits for the ajax response, the page is unresponsive to events like hovers, tips etc.
Do you have any suggestions for this? How can I implement a workarround method?
Synchronous Ajax calls are bad practice! They stop the browser for the entire duration and fool the user into thinking something crashed. You really should change this.
To your question why you don't see the latest DOM changes:
When you change something in JavaScript the browser will not immediately change the DOM, because painting a ui element is far more expensive than painting a dozen. So modern browsers will try to change the DOM as lazy as possible.
There are, apart from performance other upsides, like
$('p').hide();
can hide all p elements at the same time although jQuery will select each and than change the css.
I cant't give you any hind of a workaround without understanding your code better, sorry. Thanks!
UPDATE:
After reading your code, I would think about adding some closures to the application. A basic concept of javascript is that functions are first class types. I personally think, that your program flow is less than ideal, and this is the area of improvement. the calls to call url should look something like this:
var callUrl = function(url, callback, interactionStoped) {
if(typeof interactionStoped != 'undefined' && interactionStoped == true) {
//add code to display some loading animation
}
jQuery.ajax({ type: 'GET', url: url, success: function(data) {
callback(data);
//remove loading animation here
} });
}
as a start. Then you refactor your getUrl calls.
Funny thing is in your code example you never use the response, so I don't know what your app is waiting for. Assuming it is something important you must handle the response always in your callback.
Try looking at your app as if it were a tree. A Parent Function or Object will call itself some child functions that handle different tasks, wich themselves will invoke other functions. Build methods that are small and do only one thing on a really small set of data / parameters.
I can't rewrite your complete code, but I hope this helps anyway.
When do you try to display/fill the trigger_node variable?
It seems a bit like you aren't executing this action in the callback-function of the AJAX-request. Note that if the request is still running while you try to check for trigger_node, it won't of course show your changes.
I have a link: Hello.
When someone clicks the link I'd like to check via JavaScript if the page the href-attribute points to exists or not. If the page exists the browser redirects to that page ("www.example.com" in this example) but if the page doesn't exist the browser should redirect to another URL.
It depends on whether the page exists on the same domain or not. If you're trying to determine if a page on an external domain exists, it won't work – browser security prevents cross-domain calls (the same-origin policy).
If it is on the same domain however, you can use jQuery like Buh Buh suggested. Although I'd recommend doing a HEAD-request instead of the GET-request the default $.ajax() method does – the $.ajax() method will download the entire page. Doing a HEAD request will only return the headers and indicate whether the page exists (response codes 200 - 299) or not (response codes 400 - 499). Example:
$.ajax({
type: 'HEAD',
url: 'http://yoursite.com/page.html',
success: function() {
// page exists
},
error: function() {
// page does not exist
}
});
See also: http://api.jquery.com/jQuery.ajax/
A pretty good work around is to proxy. If you don't have access to a server side you can use YQL. Visit: http://developer.yahoo.com/yql/console/
From there you can do something like: select * from htmlstring where url="http://google.com". You can use the "REST query" they have on that page as a starting point for your code.
Here's some code that would accept a full URL and use YQL to detect if that page exists:
function isURLReal(fullyQualifiedURL) {
var URL = encodeURIComponent(fullyQualifiedURL),
dfd = $.Deferred(),
checkURLPromise = $.getJSON('http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20htmlstring%20where%20url%3D%22' + URL + '%22&format=json');
checkURLPromise
.done(function(response) {
// results should be null if the page 404s or the domain doesn't work
if (response.query.results) {
dfd.resolve(true);
} else {
dfd.reject(false);
}
})
.fail(function() {
dfd.reject('failed');
});
return dfd.promise();
}
// usage
isURLReal('http://google.com')
.done(function(result) {
// yes, or request succeded
})
.fail(function(result) {
// no, or request failed
});
Update August 2nd, 2017
It looks like Yahoo deprecated "select * from html", although "select * from htmlstring" does work.
Based on the documentation for XMLHttpRequest:
function returnStatus(req, status) {
//console.log(req);
if(status == 200) {
console.log("The url is available");
// send an event
}
else {
console.log("The url returned status code " + status);
// send a different event
}
}
function fetchStatus(address) {
var client = new XMLHttpRequest();
client.onreadystatechange = function() {
// in case of network errors this might not give reliable results
if(this.readyState == 4)
returnStatus(this, this.status);
}
client.open("HEAD", address);
client.send();
}
fetchStatus("/");
This will however only work for URLs within the same domain as the current URL. Do you want to be able to ping external services? If so, you could create a simple script on the server which does your job for you, and use javascript to call it.
If it is in the same domain, you can make a head request with the xmlhttprequest object [ajax] and check the status code.
If it is in another domain, make an xmlhttprequest to the server and have it make the call to see if it is up.
why not just create a custom 404 handler on the web server? this is probably the more "good-bear" way to do this.
$.ajax({
url: "http://something/whatever.docx",
method: "HEAD",
statusCode: {
404: function () {
alert('not found');
},
200: function() {
alert("foundfile exists");
}
}
});
If you are happy to use jQuery you could do something like this.
When the page loads make an ajax call for each link. Then just replace the href of all the links which fail.
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.min.js"></script>
<script type="text/javascript">
<!--
$.fn.checkPageExists = function(defaultUrl){
$.each(this, function(){
var $link = $(this);
$.ajax({
url: $link.attr("href"),
error: function(){
$link.attr("href", defaultUrl);
}
});
});
};
$(document).ready(function(){
$("a").checkPageExists("default.html");
});
//-->
</script>
You won't be able to use an ajax call to ping the website because of same-origin policy.
The best way to do it is to use an image and if you know the website you are calling has a favicon or some sort of icon to grab, you can just use an html image tag and use the onerror event.
Example:
function pingImgOnWebsite(url) {
var img = document.createElement('img');
img.style.visibility = 'hidden';
img.style.position = 'fixed';
img.src = url;
img.onerror = continueBtn; // What to do on error function
document.body.appendChild(img);
}
Another way to do this is is with PHP.
You could add
<?php
if (file_exists('/index.php'))
{
$url = '/index.php';
} else {
$url = '/notindex.php';
}
?>
And then
<a href="<?php echo $url; ?>Link</a>
I load html & JS code dynamically from webservice. I use prototype update method:
placeholder.update(result.Static.html); // which also include javascript code
Immediately after i loaded code, everything works fine:
ProRegResetForm();
alert('reset done');
however, from control declared as
Reset
I am having error: ProRegResetForm is not defined.
SIMPLIFIED TEST CODE (which is also not working):
<script type="text/javascript">
var defkeyword_ZipCode = 'Zip Code';
</script>
test link
It was correct to write code like:
test link
<script type="text/javascript">
functoin somethingcomplex() {
bla bla bla
}
$('element').onclick = function() { somethingcomplex(); }
</script>
Given that your 'simplified test code' did not execute, you likely have a javascript error elsewhere in your code. Javascript code that follows an exception will not execute.
Have you tried examining the script prior to your snippet (as it appears on the client) using Firebug or IE Developer Toolbar?
I had a similar problem and solved it by delimiting the HTML response from the JavaScript with a '^' and inserting them separately.
//=============================================================================
function injectJavascript(src)
{
var scripts = document.getElementById("scripts");
var javascriptSrc = document.createElement("script");
javascriptSrc.setAttribute("type", "text/javascript");
javascriptSrc.setAttribute("language", "JavaScript1.2");
javascriptSrc.innerHTML = src;
scripts.appendChild(javascriptSrc);
}
//=============================================================================
function insertHtmlAndScript(target)
{
if (req.readyState == 4) // 4 == "loaded"
{
if (req.status == 200) // 200 == "Ok"
{
var resp = req.responseText.split("^");
div = document.getElementById(target);
div.innerHTML = resp[0];
injectJavascript(resp[1]);
}
else
{
alert("Could not retreive URL:\n" + req.statusText);
}
}
}
//======================================================================
The only reason I can think of that this works while your injection does not is that the HTML vs. JavaScript interpretation is threaded such that the JavaScript can not bind properly... but that's just a guess.
So far I've been making an AJAX call to replace the content of a div with another page, using the following code:
<script>
function fetchContainerContent(url, containerid) {
var req = false
if (window.ActiveXObject) {
try {
req = new ActiveXObject("Msxml2.XMLHTTP")
} catch (e) {
try {
req = new ActiveXObject("Microsoft.XMLHTTP")
} catch (e) {}
}
} else if (window.XMLHttpRequest) {
req = new XMLHttpRequest()
} else {
return false
}
req.onreadystatechange = function() {
requestContainerContent(req, containerid)
}
req.open('GET', url, true)
req.send(null)
}
function requestContainerContent(req, containerid) {
if (req.readyState == 4 && (req.status==200 || window.location.href.indexOf("http")==-1))
document.getElementById(containerid).innerHTML = req.responseText
}
</script>
I have tried transforming the above code to work with jQuery as below but it doesn't work. In other words, I am trying to mimic the end result of the above behaviour but it is nowhere near the same. In fact, nothing happens on screen, nothing changes. I should mention that I don't really need the Loading... but since the examples I've seen use it and since I'm not sure how to correctly syntax jQuery, I've left it in.
<script>
function fetchContainerContent(url, containerid) {
jQuery.ajaxSetup ({
cache: false
});
var ajax_load = "loading...' />";
jQuery("#load_basic").click(function() {
jQuery("#"+containerid).html(ajax_load).load(url);
});
}
</script>
Thanks in advance. I'm really new to jQuery so I may have done something really stupid.
After all the comments received (thanks guys!) I have left only the following:
function fetchContainerContent(url, containerid){
var ajax_load = "loading...";
$("#load_basic").click(function(){$("#"+containerid).html(ajax_load).load(url);});
}
but I'm still having problems as it does not update the page. No js error, nothing happens.
Try this:
jQuery("#load_basic").click(function() {
jQuery("#result").html(ajax_load).load(url);
return false;
});
Note the return false statement at the end of the click handler. This will prevent from propagating the click event in case load_basic is a button or an anchor element.
The only fundamental differences I see are:
You're using a hacky-looking loading string "loading...' />". This doesn't smell good.
You're hardcoding the containerid with "#result" instead of using "#" + containerid.
You're defining the click event in JS code rather than (apparently) inline in the element. How did it originally look like?
For the remnant the code looks fine.
Is the issue that it isn't calling your callback method? You have to had the callback to the .load method.
<script>
function fetchContainerContent(url, containerid) {
jQuery.ajaxSetup ({
cache: false
});
var ajax_load = "loading...' />";
jQuery("#load_basic").click(function() {
jQuery("#result").html(ajax_load).load(url, null, requestContainerContent);
return false;
});
}
function requestContainerContent(responseText, textStatus, XMLHttpRequest) {
// do replacement in here
}
</script>
You'll have to adjust the code a bit in your requestContainerContent to do what you need it to do with the arguments provided.
OK, I seem to have gotten it working, even if I'm not too sure about the quality of the code.
var ajax_load = "loading...";
$("#"+containerid).html(ajax_load).load(url);