Load a page and apply javascript in a single bookmark - javascript

I have a bookmark that opens my a google calendar page (http://www.google.com/calendar/renderOnline) and a bookmarklet that applies some javascript on it:
javascript:document.getElementById('gadgetcell').setAttribute('style','width:300px');document.getElementsByClassName('sn-frame')[0].setAttribute('style','width:300px');
Is there a way to combine these into a single bookmarklet so that i don't have to click twice all the time?
Thank you!

No. A bookmarklet runs in the context of the original page, so it can't change pages and keep running. You may find GreaseMonkey helpful if you always want to run that code on the page. Or, Stylish lets you apply user styles to pages.

You could use an extension to get the same behavior.
For example in Safari you would create a button that launches the URL and an injected script that runs your bookmarklet. GreaseMonkey and many other extensions frameworks can do similar things.

I had the thought to use a bookmarklet to do this:
javascript:location.href='http://google.com';setTimeout(function(){alert('hi');},2000);
The setTimeout function could be anything, and due to the 2 second timer, the page would have time to load and the arbitrary code would execute against it. But it didn't work. No matter what function I seem to try to call in the setTimeout, it just never executes, or perhaps it executes in some other space that was being destroyed as the new page loaded or something like that. That setTimeout code works fine as a bookmarklet as long as there's no location.href change, it seems.
However I wonder if perhaps a better approach would be to do an AJAX load of the page you want into the current space, and then try to execute something. If I get around to trying that I'll update here.

Related

How does an auto refresh page extension works and how to recreate one with code?

I'm looking for a way to recreate the functionality of a refreshing page extension on a browser (e.g. Auto refresh plus in Chrome) by using javascript. The problem is that I have no ideia how to achieve that.
I must find a way to refresh the page every second or so, click on a link that appears on the page from time to time, add a sound effect for when it appears and send an e-mail notification every time it appears.
I'm trying to use a simple javascript snippet to run in the console in order to refresh the page:
win1 = window.open("https://www.myUrl.com/");
timer1 = setInterval(function(){win1.location.href="https://www.myUrl.com/"}, 1500);
However, this implies running code from tab A on tab B which I found very challenging.
The code can't run on tab A alone because at the time it refreshes the page, it gets erased from the console.
I know it would have been so much easier to use an extension, but the platform I work for does not allowed any extensions.
I have basic HTML and javascript knowledge, but I find this would be a good project to learn more.
Also, if the solution involves other languages, I just need a direction to know where to look for and start this project.

Using history.pushState with the pageShow and similar events

Bit of background in the problem: I am working on a project that loads most of it's content via api calls in JS. The initial page is built in PHP and delivered ready to use, but every interaction/load after that is just done in JS async and pushed to the "content area" of the html. I'm adding QoL so that you can navigate back to where you were using your history/back/forward button, but in order to do that, every time you navigate using those buttons, I would like to force-refresh the page (for various reasons which I don't think are relevant but am happy to describe if requested).
I'm struggling to understand both pushState and pageShow when used in conjunction. As far as I know, I can use pushState to push new entries to the history object every time it's run, like so:
// Update history
var stateObj = {};
history.pushState(stateObj, response.data.title, uri);
That seems to be working when I run that section of code and check my browser history; a nice neat entry sitting there every time I run it. As far as I know, the title isn't actually supported by any browser, but it doesn't hurt to have it.
My issue occurs when I try to use that newly generated history with the back/forward buttons. As far as I can tell doing some google research, typical browser behavior will not actually reload the page when I press the back button. Herein is where I believe my problem occurs. While navigating to any url fresh will load that specific piece of content into the content area, the site is basically a single page application, loading content into the content area async as it needs it. It doesn't actually change pages. I'm not sure, but I think that is the core problem. I have tried to use several events to "catch" the back/forward behavior:
window.onunload
window.onpageshow
$(window).on("pagehide", function() {})
window.addEventListener("pageshow", function(event) {})
I know several of those are basically the same thing, but I was trying to cover my bases. I have looked around for a solution, and I know that window.onunload is SUPPOSED to override the bfcache (not even sure if that is my problem), but it doesn't seem to fire at all, no matter how many times I navigate between the history.pushState entries. I'm not familiar enough with any of these functions to tell where my problem is. What am I doing wrong?

Get a bookmark to load a page and run javascript on it [duplicate]

I have a bookmark that opens my a google calendar page (http://www.google.com/calendar/renderOnline) and a bookmarklet that applies some javascript on it:
javascript:document.getElementById('gadgetcell').setAttribute('style','width:300px');document.getElementsByClassName('sn-frame')[0].setAttribute('style','width:300px');
Is there a way to combine these into a single bookmarklet so that i don't have to click twice all the time?
Thank you!
No. A bookmarklet runs in the context of the original page, so it can't change pages and keep running. You may find GreaseMonkey helpful if you always want to run that code on the page. Or, Stylish lets you apply user styles to pages.
You could use an extension to get the same behavior.
For example in Safari you would create a button that launches the URL and an injected script that runs your bookmarklet. GreaseMonkey and many other extensions frameworks can do similar things.
I had the thought to use a bookmarklet to do this:
javascript:location.href='http://google.com';setTimeout(function(){alert('hi');},2000);
The setTimeout function could be anything, and due to the 2 second timer, the page would have time to load and the arbitrary code would execute against it. But it didn't work. No matter what function I seem to try to call in the setTimeout, it just never executes, or perhaps it executes in some other space that was being destroyed as the new page loaded or something like that. That setTimeout code works fine as a bookmarklet as long as there's no location.href change, it seems.
However I wonder if perhaps a better approach would be to do an AJAX load of the page you want into the current space, and then try to execute something. If I get around to trying that I'll update here.

Cannot use setTimout doesn't work in bookmarklet

Can I not use setTimeout() in a bookmark?
This works:
javascript:
document.location="mysite.com";
alert("test");
void(s);
This does not:
javascript:
document.location="mysite.com";
var t=setTimeout(function () {
alert("test");
}, 10000);
void(s);
Why is this?
Each time you change a page the entire javascript context is destroyed and recreated(This for security reasons and the fact that a context hell would be made)
document.location="mysite.com";
efectively changes the context of the page destroying any javascript reference left(in your case the timeout). The moment the new page has started loading your page has a new context.
for your timeout to work you would need a server that takes more than 10 seconds to respond(based on your second argument 10000 or to reduce the timeout to something like 10 ms).
document.location="mysite.com";
var t=setTimeout(function () { alert("test"); }, 10);
why would you need this?
Bookmarklets can do no more than what normal embedded script on a web page can do. If you can't do it with normal JavaScript, you can't do it with a bookmarklet.
In your example, if run as normal javascript embedded in the page, as soon as the page reloads the timeout would be gone, along with all other variables from that page. (Don't be mislead by the fact that JavaScript embedded in script tags will be re-run as the page is loaded. That would create a new timeout, but the previous one would be deleted.)
A more precise test would be to put your bookmarklet code into an a hyperlink on the page and click it (test). That is exactly the same as clicking a bookmark containing the same code. What you cannot do with this, you cannot do with a bookmarklet.
SOLUTIONS TO YOUR PROBLEM:
Option 1: Bookmarklet creates an iframe inside the current page, and continuously reloads the desired page inside that iframe.
Option 2: Bookmarklet opens a small window and inject javascript into it which continuously reloads the opener window.

Chrome extension: page loads faster than extension code

I am working on the extension that needs to update page texts after page is loaded. I use window.onload in "content_script".
As I need to test my changes a lot I decided to create a little page with a few paragraphs of text and put it in my web server. But when this page loads - extension's window.onload doesn't trigger, wheres on any other internet page it works properly.
I started investigation and found out, that this is because of the page loading speed. So basically page loads faster than extension code.
It was verified by adding background image on the body linked to the external site. Like this:
body
{
background: url(http://colourunity.com/img/2013/07/autumn-wallpaper-computer-14172-hd-widescreen-wallpapers.jpg) no-repeat;
}
So the page's loading speed slows down and extension has enough time to load in and window.onload triggers.
Of course I don't worry about extension work, because it is too rare case when page loads that fast.
But still - is there anyway to bypass this?
Thanks.
The window object of your content script is not the same as the one of your page. From the content script documentation:
It's worth noting what happens with JavaScript objects that are shared by the page and the extension - for example, the window.onload event. Each isolated world sees its own version of the object.
Therefore listening for this event in your content script won't work as you intent, since it's not the one you want.
It doesn't matter anyway: you can specify at which point your script is executed via the run_at option. For example, if you choose to run it at document_idle, then you're guaranteed it's executed after the window.onload event of your page.
In other words, you can simply stop using the window.onload event, and directly run the code you need.

Categories

Resources