How to trigger an event only when the user changes the URL? - javascript

I am working on a Chrome extension, I want to detect when the user has typed a URL. I know about:
chrome.tabs.onUpdated.addListener(eventLisenerObj.onUpdated);
But, it gets called whenever the URL is changed (e.g. when the page is auto reloads, or user clicks on a link, etc.)
I desire to be able to determine that the URL was changed only by the user typing a URL.

You can get this information using the webNavigation.onCommitted(MDN) event. The event listener receives a property transitionType(MDN), which will be different values(MDN) based on the cause of the navigation. Which values you trigger on will depend on exactly what you are desiring. For what you describe, you will probably want 'typed'(MDN), but potentially also 'generated'(MDN), 'keyword'(MDN) and/or 'keyword_generated'(MDN).
The list of possible values is explained on Chrome's History API page (they are listed on the Chrome webNavigation page, but not explained there) (On MDN: TransitionType) (text from the Chrome History API page):
"link"
The user got to this page by clicking a link on another page.
"typed"
The user got this page by typing the URL in the address bar. Also used for other explicit navigation actions. See also generated(MDN), which is used for cases where the user selected a choice that didn't look at all like a URL.
"auto_bookmark"
The user got to this page through a suggestion in the UI — for example, through a menu item.
"auto_subframe"
Subframe navigation. This is any content that is automatically loaded in a non-top-level frame. For example, if a page consists of several frames containing ads, those ad URLs have this transition type. The user may not even realize the content in these pages is a separate frame, and so may not care about the URL (see also manual_subframe(MDN)).
"manual_subframe"
For subframe navigations that are explicitly requested by the user and generate new navigation entries in the back/forward list. An explicitly requested frame is probably more important than an automatically loaded frame because the user probably cares about the fact that the requested frame was loaded.
"generated"
The user got to this page by typing in the address bar and selecting an entry that did not look like a URL. For example, a match might have the URL of a Google search result page, but it might appear to the user as "Search Google for ...". These are not quite the same as typed(MDN) navigations because the user didn't type or see the destination URL. See also keyword(MDN).
"auto_toplevel"
The page was specified in the command line or is the start page.
"form_submit"
The user filled out values in a form and submitted it. Note that in some situations — such as when a form uses script to submit contents — submitting a form does not result in this transition type.
"reload"
The user reloaded the page, either by clicking the reload button or by pressing Enter in the address bar. Session restore and Reopen closed tab use this transition type, too.
"keyword"
The URL was generated from a replaceable keyword other than the default search provider. See also keyword_generated(MDN).
"keyword_generated"
Corresponds to a visit generated for a keyword. See also keyword(MDN).
To differentiate some types of transitions, in addition to the transitionType values, you will also want to look at the TransitionQualifier(MDN). The possible values are (from the Chrome documentation, which are described somewhat differently on MDN):
"client_redirect"
One or more redirects caused by JavaScript or meta refresh tags on the page happened during the navigation.
"server_redirect"
One or more redirects caused by HTTP headers sent from the server happened during the navigation.
"forward_back"
The user used the Forward or Back button to initiate the navigation.
"from_address_bar"
The user initiated the navigation from the address bar (aka Omnibox).

You can have a look at $locationChangeSuccess.
You can get the path like this:
var loc = $location.path();
Then on change of loc you can attach your function.

Related

using javascript to get selected text from an iframe pointing to a different domain

I have an iframe set up that allows the user to browse to a different website with a simple form set up next to it so the user is able to enter information into the form.
This is set up in order to allow the user to quickly refer to the iframe and enter information into the form without having to open the site in a separate window and having to resize the two windows in order to view both at the same time (this was a specific user request).
Now the user has requested that this process of entering information from the form is streamlined a bit more by eliminating the need to 'highlight text > ctrl+c > select correct field in form (eg phone no.) > ctrl + v', so I am looking into seeing if it is possible to just highlight the text to be copied and then automatically update a field in the form using a button or a simple key down event.
I have tried using :
window.frames["myframe"].getSelection().toString();
but this results in an error telling me I don't have permission to access the "getSelection" property, which I believe is because I am trying to access the information of a page on a different domain to mine.
Is there any other way of capturing just the selected text to paste into my form element or will the user have to just deal with the constant copy and pasting manually?
You can't perform any JS action on any iframe that has another origin. That's a basic security policy of any web browser. It would be an enormous security flaw.

Design and SEO for a single page dynamic website with AJAX

I designed a website in which the whole site is contained within one page (index.php).
Within the page, <section> tags define different parts of the site (home, contact, blog etc.)
Navigation is achieved by buttons that are always visible, and when clicked use javascript to change the visibility of the sections, so that only one is shown at any time.
More specifically, this is done by using the hash in the url, and handling the hashchange event. This results in urls such as www.site.com/#home (the default if no other hash is present) and www.site.com/#contact.
I want to know if this is a good design. It works, but I get the feeling there must be a better way to achieve the same thing? To clarify, I was aiming for site that loaded all the main content once, so that there were no more page loads after the initial load, and moving between sections would be smoother.
On top of this, another problem is introduced concerning SEO. The site shows up in google, but if for example, a search query contains a term in a specific section, it still loads the default #home page when clicked, not the specific section the term was found in. How can I rectify this?
Finally, one of the sections is a blog section, which is the only section that does not load all at once, since by default it loads the latest post from a database. When a user selects a different post from a list (which in itself is loaded using AJAX), AJAX is used to fetch and display the new post, and pushState changes the history. Again, to give each post a unique url that can be referenced externally, the menu changes the url which is handled by javascript, resulting in urls such as www.site.com/?blogPost=2#blog and www.site.com/?blogPost=1#blog.
These posts aren't seen by google at all. Using the Googlebot tool shows that the crawler sees the blog section as always empty, so none of the blog posts are indexed.
What can I change?
(I don't know if this should be on the webmasters stackexchange, so sorry if its in the wrong place)
Build a normal site. Give each page a normal URL. Let Google index those URLs. If you don't have pages for Google to index, that it can't index your content.
Progressively enhance the site with JS/Ajax.
When a link is followed (or other action that, without JS, would load a new page is performed) use JavaScript to transform the current page into the target page.
Use pushState to change the URL to the URL that would have been loaded if you were not using JavaScript. (Do this instead of using the fragment identifer (#) hack).
Make sure you listen for history events so you can transform the page back when the back button is clicked.
This results in situations such as:
User arrives at /foo from Google
/foo contains all the content for the /foo page
User clicks link to /bar
JavaScript changes the content of the page to match what the user would have got from going to /bar directly and sets URL to /bar with pushState
Note that there is also the (not recommended) hashbang technique which hacks a one-page site into a form that Google can index, but which is not robust, doesn't work for any other non-JS client and is almost as much work as doing things properly.

pushstate - back button not working

If I use ajax to change specific portions of the page, like a content section, which warrants a new URL (and requires one specifically for favoriting, or refreshing), is there some magic that I am not aware of that allows the user to click the back button and reload the content that was just there?
Or do you have to re-retrieve the data based on stored variables using popstate
Thanks!

Multipage vs Single Page and Unobtrusive Javascript

I have a section of a site with multiple categories of Widget. There is a menu with each category name. For anybody with Javascript enabled, clicking a category reveals the content of the category within the page. They can click between categories at will, seeing the DOM updated as needed. The url is also updated using the standard hash/hashbang (if we are being Google-friendly). So for somebody who lands on example.com/widgets, they can navigate around to example.com/widgets#one, example.com/widgets#two, example.com/widgets#three etc.
However, to support user agents without Javascript enabled, following one of these category links must load a new page with the category displayed, so for someone without javascript enabled, they would navigate to example.com/widgets/one, example.com/widgets/two, example.com/widgets/three etc.
My question is: What should happen when somebody with Javascript enabled lands on one of these URLS? What should someone with Javascript enabled be presented with when landing on example.com/widgets/one for example? Should they be redirected to example.com/widgets#one?
Please note that I need a single page site experience for anybody with Javascript enabled, but I want a multi-page site for a user agent without JavaScript. Any answer that doesn't address this fact doesn't answer the question. I am not interested in the merits or problems of hashbangs or single-page-sites vs multi-page-sites.
This is how I would structure it:
Use HistoryJS to manage the URL. JS pushstate browsers got full correct URLs and JS non-pushstate browsers got hashed urls. Non-JS users went to the full URL as normal with a page reload.
When a user clicks a link:
If they have JS:
All clicks to other pages are handled by a function that prevents the default action, grabs the HREF and passes the URL to an ajax request and updates the URL at the same time. The http response for that ajax request is then parsed and then loaded into the content area.
Non JS:
Page refreshed as normal and loads the whole document.
When a page loads:
With JS: Attach an event handler to all your links to prevent the default so their href is dealt with via Ajax.
Without JS: Nothing. Allow anchors to work as normal.
I think you should definitely have all of your content accessible via a full, correct URL and being loading it in via ajax then updating the URL to reflect the address where you got your content from. That way, when JS isn't running, you don't have to change anything.
Is that what you mean?
Apparently your question already contains the answer. You say:
I need a single page site experience for anybody with Javascript enabled
and then ask:
What should someone with Javascript enabled be presented with when landing on example.com/widgets/one for example? Should they be redirected to example.com/widgets#one?
I'd say yes, they should be redirected. I don't see any other option, given your requirements (and the fact that information about JavaScript capabilities and the hash fragment of the URL are not available on the server side).
If you can accept relaxing the requirements a bit, I see another option. Remember when the web was crowded with framesets, and we landed on a specific frame via AltaVista (Google wasn't around yet!) search? It was common to see a header saying that page was supposed to be displayed as a frame, and a link to take the user to the frameset version.
You could do something similar: when scripting is available, detect that you're at example.com/widgets/one and add a link to the single-page version. I know that's not ideal, but it's better than nothing, and maybe better than a nasty client-side redirect.
Why should you need to redirect them to a different page. The user arrived at the page looking for an answer. He gets the answer even if he has javascript enabled. It doesn't matter. The user's query has been fulfilled.
But what would happen if the user lands on example.com/widgets#one ? You would need to set up an automatic redirect to example.com/widgets/one in that case. That could be done by checking the if javascript is enabled in the onload event and redirect to the appropriate page.
One way for designing such pages is to design without javascript first.
You can use anchors in the page so:
example.com/widgets#one
Will be a link to the element with id 'one'
Once your page works without javascript, then you add the javascript layer. You can prevent links to be followed by using the event.preventDefault.
(https://developer.mozilla.org/fr/docs/DOM/event.preventDefault), then add the desired javascript functionality.

Javascript menu remembering position

I am currently working on a JS menu for a web app. It consists of two bars, the fixed main one and the submenu which is activated (display:block from display:none) by Javascript function. The selected options of the main menu as well as the submenu are also highlighted by adding a class="main_on" and class="sub_on" by onclick event. Is there way of remembering which submenu was displayed and which options were currently classed as active when the user hits F5 or the page reloads itself? I am looking for a non-cookie and non-database approach if possible.
Thanks,
Mike
You can make the link/element that is clicked (for the onclick event) set the URL hash in the address bar. (i.e. http://server.name/page#URLhash) If it's a link you just have to adjust the HREF property, otherwise you may have to manipulate with window.location.
This sets the current state. When the page (re)loads, check the value of the URL hash. See http://developer.mozilla.org/en/DOM/window.location for details on how to access it. Provided the URL hash is still in the address bar, you'll be able to get the value.
Then use the value to determine which menu to make active. Thus you can restore the state this way.
There are some differences between browsers. Do a search on "Ajax History", in which some people have used the URL hash to preserve the state after Ajax actions. Not the exact same problem you are trying to solve but similar. Check out RSH:
http://code.google.com/p/reallysimplehistory/
The same ideas will be used.

Categories

Resources