I want the contents of a link get printed by jQuery. What do i do?
Following is my code:
DEMO:
Print
$(document).ready(function() {
$('ul#tools').prepend('<li class="print">Click me to print</li>');
$('ul#tools li.print a').click(function() {
window.open('www.google.com');
window.print();
return false;
});
});
"Printing the contents of a link" sounds ambiguous. I guess what you are trying to do is to print another web page? It might work if you opened the page in a new frame and printed that, it seems to me that this question might help you.
You would have to call print() on the window you are opening, not the one the original code is running in.
var foo = window.open(bar, 'bar');
foo.print();
(You might run into timing issues if the window hasn't had time to load the document).
However, in you example you appear to be trying to open a third party page (although you forgot the http://). The same origin policy will prevent you accessing the print method of the remote document.
Related
Confusingly, or perhaps not, I don't want it to postback, as it is loading a popup containing content, but the postback closes the popup.
The code is really simple, and its just a bog standard asp:Hyperlink. Theres nothing that I can see which could cause this, and I am mainly confused as to how and why it is being handled so differently by each browser.
The only thing I could think of was JS with
event.preventDefault();
Any one got any ideas what could cause this?
I am reloading an iFrame with a new source, which sits on the page, but it is forcing the entire page to postback on firefox only.
iFrame.attr('src', newSrc);
The rest of the code:
$('.button-try-glasses').on('click', function (event) {
var modal = $('#modal-container');
var newAsset = $(this).attr('data-asset');
var iFrame = modal.find('iframe');
var currentIFrameSrc = iFrame.attr('src');
var newSrc = currentIFrameSrc.substring(0, (currentIFrameSrc.lastIndexOf("/") + 1)) + newAsset;
iFrame.attr('src', newSrc);
Trylive.parse();
showPopup($(null), '#modal-container', true);
event.preventDefault();
});
If I comment out the .attr line, it doesn't update the source, but it also doesn't postback and then close the component.
To answer exactly we need your aspx and js code. For quick hit and try. There must be some Js error. You can write
return false;
at the end of your Js code.
As the others mentioned we need your aspx and js code.
But as a workaround you can try to wrap your ifram with asp UpdatePanel which should fix it.
$('.button-try-glasses').on('click', function (event) {
event.preventDefault(); //put it here
....
return false; //this must be last line
});
hope that works for you
Looks like the problem is with the page you are trying to load in the iframe. The javascript in the iframe could be doing something like top.location = "post url" or window.parent.location="post url".
Could you try opening another url like google.com in your iframe and see if the problem persists
iFrame.attr('src', "http://google.com");
You might wanna try checking the following options for errors -
Order of calling => It is always a better approach to call loading or contents of your modals after the modal is shown. Because until the containers of modals are shown, you might not be able to use them in codes. For example, calling iFrame.attr('src', newSrc); after executing showPopup($(null), '#modal-container', true); could be a good idea.
Check Url => Make sure url is properly generated and the url you are trying to load supprts CORS.
I have tested with Twitter Bootstrap to try to load an iframe inside a modal, it worked perfectly. You might wanna check out the codes at jsfiddle, this might help you solving yours.
Here is a screenshot of the content loaded in modal -
If I call console.log('something'); from the popup page, or any script included off that it works fine.
However as the background page is not directly run off the popup page it is not included in the console.
Is there a way that I can get console.log()'s in the background page to show up in the console for the popup page?
is there any way to, from the background page call a function in the popup page?
You can open the background page's console if you click on the "background.html" link in the extensions list.
To access the background page that corresponds to your extensions open Settings / Extensions or open a new tab and enter chrome://extensions. You will see something like this screenshot.
Under your extension click on the link background page. This opens a new window.
For the context menu sample the window has the title: _generated_background_page.html.
Any extension page (except content scripts) has direct access to the background page via chrome.extension.getBackgroundPage().
That means, within the popup page, you can just do:
chrome.extension.getBackgroundPage().console.log('foo');
To make it easier to use:
var bkg = chrome.extension.getBackgroundPage();
bkg.console.log('foo');
Now if you want to do the same within content scripts you have to use Message Passing to achieve that. The reason, they both belong to different domains, which make sense. There are many examples in the Message Passing page for you to check out.
Hope that clears everything.
To answer your question directly, when you call console.log("something") from the background, this message is logged, to the background page's console. To view it, you may go to chrome://extensions/ and click on that inspect view under your extension.
When you click the popup, it's loaded into the current page, thus the console.log should show log message in the current page.
You can still use console.log(), but it gets logged into a separate console.
In order to view it - right click on the extension icon and select "Inspect popup".
The simplest solution would be to add the following code on the top of the file. And than you can use all full Chrome console api as you would normally.
console = chrome.extension.getBackgroundPage().console;
// for instance, console.assert(1!=1) will return assertion error
// console.log("msg") ==> prints msg
// etc
const log = chrome.extension.getBackgroundPage().console.log;
log('something')
Open log:
Open: chrome://extensions/
Details > Background page
Try this, if you want to log to the active page's console:
chrome.tabs.executeScript({
code: 'console.log("addd")'
});
It's an old post, with already good answers, but I add my two bits. I don't like to use console.log, I'd rather use a logger that logs to the console, or wherever I want, so I have a module defining a log function a bit like this one
function log(...args) {
console.log(...args);
chrome.extension.getBackgroundPage().console.log(...args);
}
When I call log("this is my log") it will write the message both in the popup console and the background console.
The advantage is to be able to change the behaviour of the logs without having to change the code (like disabling logs for production, etc...)
In relation to the original question I'd like to add to the accepted answer by Mohamed Mansour that there is also a way to make this work the other way around:
You can access other extension pages (i.e. options page, popup page) from within the background page/script with the chrome.extension.getViews() call. As described here.
// overwrite the console object with the right one.
var optionsPage = ( chrome.extension.getViews()
&& (chrome.extension.getViews().length > 1) )
? chrome.extension.getViews()[1] : null;
// safety precaution.
if (optionsPage) {
var console = optionsPage.console;
}
Curently with Manifest 3 and service worker, you just need to go to Extensions Page / Details and just click Inspect Views / Service Worker.
To get a console log from a background page you need to write the following code snippet in your background page background.js.
chrome.extension.getBackgroundPage().console.log('hello');
Then load the extension and inspect its background page to see the console log.
To view console while debugging your chrome extension, you should use the chrome.extension.getBackgroundPage(); API, after that you can use console.log() as usual:
chrome.extension.getBackgroundPage().console.log('Testing');
This is good when you use multiple time, so for that you create custom function:
const console = {
log: (info) => chrome.extension.getBackgroundPage().console.log(info),
};
console.log("foo");
you only use console.log('learnin') everywhere
chrome.extension.getBackgroundPage() I get null
and accrouding documentation,
Background pages are replaced by service workers in MV3.
Replace background.page or background.scripts with background.service_worker in manifest.json. Note that the service_worker field takes a string, not an array of strings.
manifest.json
{
"manifest_version": 3,
"name": "",
"version": "",
"background": {
"service_worker": "background.js"
}
}
anyway, I don't know how to use getBackgroundPage, but I found another solution as below,
Solution
use the chrome.scripting.executeScript
So you can inject any script or file. You can directly click inspect (F12) and can debug the function.
for example
chrome.commands.onCommand.addListener((cmdName) => {
switch (cmdName) {
case "show-alert":
chrome.storage.sync.set({msg: cmdName}) // You can not get the context on the function, so using the Storage API to help you. // https://developer.chrome.com/docs/extensions/reference/storage/
chrome.tabs.query({active: true, currentWindow: true}).then(([tab])=>{
chrome.scripting.executeScript({
target: {tabId: tab.id},
function: () => {
chrome.storage.sync.get(['msg'], ({msg})=> {
console.log(`${msg}`)
alert(`Command: ${msg}`)
})
}
})
})
break
default:
alert(`Unknown Command: ${cmdName}`)
}
})
I create an open-source for you reference.
I am creating an extension that will launch an external script based on highlighted text. So, far, the script works, except I am having issues closing the newly created window.
In my background.html, I have the following:
<script>
function executeScript(selection) {
var queryText = 'script:' + selectedText;
chrome.tabs.create({url: queryText});
chrome.tabs.getSelected(null, function(tab) {
chrome.tabs.remove(tab.id);
});
}
</script>
My problem is with the setup above, it closes the tab before the "url" loads, so it never executes the script.
If I take out the getSelected lines (lines 5-7), it opens the tab and runs the script perfectly. I am trying to just get the syntax to close the tab automatically after it executes.
Thanks!
Not exactly sure what you are trying to accomplish, but if you want to close a tab after a script has run you should have the script send a "Close Me" request to background.html using chrome.extension.sendRequest.
You might be better off using chrome.tabs.executeScript, which allows you to pass a function (in which you could close the tab) which gets called after the script has finished running.
I would like to post a followup question to this issue:
I want to make a Chrome Extension which passes on the URL (and eventually a selected Text) of a given Tab to my program (in OS X).
The problem is that Chrome closes the tab immediately after it opened it and does not really load the URL. The only way to make this happen is by inserting the alert-command, which is not practicable.
I also tried it with
chrome.tabs.onCreated.addListener
but it's the same result, and setTimeout does not seem to be registered at all.
My code:
chrome.browserAction.onClicked.addListener(function(tab)
{
chrome.tabs.create({url:"myApp:add?url="+encodeURIComponent(tab.url)},
function(tab){
alert("Your URL is added to myApp");
chrome.tabs.remove(tab.id);
});
});
I would need the exact same result, only without the alert box.... thank you for your help!
This worked for me:
chrome.tabs.create({ url: yourUrl },function(tab){
setTimeout(function(){chrome.tabs.remove(tab.id);}, 200);
});
I am at loss to understand how popup windows´ DOM-trees and their manipulation from opener window work. What is the proper way to implement what I am trying to do (described below)?
I have one normal browser window where JavaScript function gathers selected elements and creates POST data string from them.
I then open a popup window with placeholder content, bind a function to window.ready that does the AJAX request and then try to replace the HTML in popup window with AJAX results.
In code this is done in JavaScript run on the opener window:.
function showMessages(queryParams, width, height) {
var mailWindow = window.open('html/blankwithdoctype.html', 'foo', 'resizable=yes,scrollbars=yes,height='+height+',width='+width);
var params = queryParams.substring(1);
$(mailWindow.document).ready(function() {
doPostRequest(params, mailWindow);
});
return mailWindow;
}
function doPostRequest(queryParams, mailWindow) {
function callback(data, textStatus) {
var mv = mailWindow;
$(mv.document).find("html").html(data);
};
$.post('MailFile.do', queryParams, callback);
}
When breaking at $(mv.document).find("html").html(data); with Chrome developer tools or Firefox+FireBug, I notice that temporarily the result is shown but after the JQuery call stack is unwound (after $.post('MailFile.do', queryParams, callback);) the original blank page is yet again shown.
Without a debugger, I notice that rendering of the result page is atleast started but it is quickly replaced with the original placeholder page.
Something funny is definitely going on here.
I actually was looking for a way around this problem myself. I'm guessing the browser prevents access to modifying the DOM of a child window for security reasons. (I'm wishing it gave some sort of error, but I never got one)
In any case, I didn't need an already existing page to open, my application did require a separate popup though to accommodate multiple screens.
After opening up the popup with window.open(null, null, "...options..."), I simply called document.write("...FULL HTML FOR POPUP...") and built the entire popup essentially from scratch. From that point, I had access to any DOM operations I wanted to perform from the parent window.
Here's an example of what I'm talking about:
// using null for the URL (defaults to about:blank in some browsers)
// using null for the Window Name (allowed me to have multiple popups)
var popup = window.open(null, null, "width=600,height=600");
// overwrite the entire document with our own HTML
popup.document.write('<!DOCTYPE html><html><head></head><body></body></html>');
// Using jQuery for DOM manipulation here
var $popup = $("body", popup.document);
I only really tested this in Chrome and Firefox, unfortunately. Also, even setting the tag never changed the title of the popup window. It's not a perfect solution, but it worked in my situation.
I suspect that the jQuery library is not loaded in the popup window. Then, when the code that follows the ready event in the popup window is executed, the $ function is unknown, causing the error. I might be wrong though, I have never used ready() in a cross-window fashion (and always on document, not on window).
EDIT: What you could also do (instead of including jQuery in the opened window) is replace every $ in the opened window with window.opener.$. But that's rather ugly, now, isn't it? ;-)
I need to set the onload attribute for a newly popped-up window.
The following code works for Firefox:
<a onclick="printwindow=window.open('www.google.com');printwindow.document.body.onload=self.print();return false;" href='www.google.com'>
However, when I try this in IE, I get an error - "printwindow.document.body null or not defined'
The goal is to pop open a new window, and call up the print dialog for that window once it's been opened.
Any clues on how to make this work?
It is important not to use javascript elsewhere on the target page, as I do not have control over it. All functionality must be contained in the link I posted above.
While earlier answers correctly stated the new window must be from the same domain, they incorrectly answered why he got the error 'printwindow.document.body null or not defined'. It's because IE doesn't return any status from window.open() which means you can open a page and try to access it BEFORE onload is available.
For this reason you need to use something like setTimeout to check. For example:
printwindow = window.open('print.html');
var body;
function ieLoaded(){
body = printwindow.document.getElementsByTagName("body");
if(body[0]==null){
// Page isn't ready yet!
setTimeout(ieLoaded, 10);
}else{
// Here you can inject javascript if you like
var n = printwindow.document.createElement("script");
n.src = "injectableScript.js";
body.appendChild(n);
// Or you can just call your script as originally planned
printwindow.print();
}
}
ieLoaded();
This is further discussed here
This is not possible unless both pages are on the same domain. Your code does not work in FF, but rather prints the current page. If the pages are on the same domain, then you would write:
printwindow=window.open('/mypage.html');
printwindow.onload = function() {
printwindow.focus();
printwindow.print();
}
You are relying on "printwindow.document.body.onload=self.print();" line being executed before the child document finishes loading. I don't think you can be guaranteed that.
Here's an idea: prepare HTML or a page that has nothing but the page you need in an iframe. This page will have body.onload=self.print().
onload is a property if window objects, not body elements, despite what the HTML attribute might lead you to believe. This is the reference:
printwindow.onload
However, in this context you can't pass it a string of JavaScript - you need to hand it a function. So, the full script like would look like this
printwindow.onload=function(){self.print();}
Now, putting it all together
<a href="www.google.com" onclick="var printwindow=window.open(this.href,'printwindow');printwindow.onload=function(){self.print();};return false;" >try it</a>
HOWEVER! This will not work for you for the URL "www.google.com". The browser security model prevents parent windows from accessing the window objects of child windows, UNLESS they both reside # the same domain name.
Check our jQuery. Particularly the document ready feature.
http://docs.jquery.com/Tutorials:How_jQuery_Works#Launching_Code_on_Document_Ready
The final (admittedly, poor) solution that worked for all browsers was to use setTimeout and call print() that way, instead of modifying the onload attribute:
<a onclick="self.printwindow=window.open('print.html');setTimeout('self.printwindow.print()',3000);return false;" href='print.html'>