There are many questions that ask how to change the class of a div in a JavaScript click handler, e.g., here: Change Div style onclick. I understand that well (just change .className), and it works.
However, when I follow a link from my page to somewhere else, and then click the back button, the class names are reverted. (Safari and Firefox get it right, Chrome does not.) In Chrome, most other changes I make dynamically, e.g., to click handlers, are also reverted when I go back to the page (although it remembers freshly inserted new divs).
Note that neither Chrome nor the other browsers are reloading the page when I press "back"; they must just take it from the cache. (I update the state on the server using ajax, so it works fine when the browsers reload the page.)
I am not really a web developer, so this is a bit puzzling. What is the standard practice here? Should I use history.replaceState() every time I change the divs? Should I save the changes in a state variable and reload them every time there is a popstate event? Instead of changing div classnames, should I delete the div and insert a fresh one (with all the old div's children)?
I am using vanilla JavaScript here (no jquery even) and would prefer to keep it that way if possible.
It is possible, but you will need additional ways to remember it
You could try one of these:
Cookies: This definitely looks like the best way to go
Pass Vars on the URL: example: www.mywebsite.com?myvar=red. This would be easier using PHP, but still is possible in pure JS (but I don't recommend it)
Store it on Database: (don't recommend this at all)
Store it in input elements: In current browsers, input element values (of radio buttons, hidden, etc.), persist after POST-ing, and returning using the back button.
These are just some options, but I don't recommend using them for what you want (it is a waste of time and effort if you weight the Pros and Cons of what you want to do)
You can save state in cookies and restore it when page loaded.
Also you can save it on server-side (send state using ajax, when it changed). And send prepared document to client when it requested again.
Browser forget all states when you reload page.
Related
I'm using Zero Clipboard and Downloadify to put certain data into clipboard and call Save As dialog. I want to avoid having to click two buttons, but Flash does not allow taking action with simulated click() from Javascript, only real mouseclicks. Is there a way to "spread" a single click done by user to two flash buttons?
I think I heard somewhere that a click can reach through several layers of elements. I tried putting the two buttons one on top of another (by calling ZClip on the flash object that Downloadify generates), but it doesn't work, only the upper button fires (ZClip), even though the bottom one is able to detect mouseover (changes button color).
I need this for a userscript I'm writing for myself to enhance functionality of an online photoalbum. The idea behind the script is that it tries to guess the category of a currently opened image based on its filename or tags and generates a full path under which I would want to save this image, which is then placed into clipboard so that upon saving I can simply paste it to the filename field saving me the trouble of having to navigate to the desired folder manually every time. Since I'm going for decreasing the amount of clicks, I'd like to have both clipboard operation and Save As dialog to happen at a single click instead of click for copy and right-click for context menu and click to choose "save as".
I'm using Opera 12.17 if it matters.
Edit: It looks like you can call a flash function from outside by Javascript via SWFObject plugin, but that function needs to be declared as external in flash code. I tried looking up the list of available functions in my case, ZClip has none and Downloadify only has unrelated stuff like show/hide/classes, so still no luck.
ZClip has the ability to relay the click event to the object it's glued to, which is on by default, but that still doesn't work in my case, even though I glue it to Downloadify.
Apparently it's impossible, I asked the same question in several places online and got no solution anywhere.
Still, I solved the problem another way, if I can't fire two buttons at once, I should just add the functionality of one into another. Which I did, adding the ability to copy to clipboard to Downloadify, works perfectly.
So, I have a page that has several links with onClick events that will retrieve data from external files and fill a div with this data. This works as intended. When I refresh the page, however, the div empties again. What I would like to happen is that after a refresh, the div will maintain the last content retrieved.
I'd prefer not to go down the road of cookies and have looked into adding data to the URL which I think is the way I want to go with this.
Is there some nice JQuery calls that can append data to url when a link is clicked and then on refresh restore the required content to the div?
My loadContent function is:
function loadContent (url, container) {
var target = $(container);
target.load(url, function (text, statusText) {
if (statusText === "success") {
target.find("a[rel^='gridnav']").initgn();
}
});
}
edit: I forgot to mention, the line
target.find("a[rel^='gridnav']").initgn();
is used to re-initialise a script on the new content loaded.
So when I click a link, the onClick event calls the function like this
TEST</li>
where xyz.html contains only the data I want inside the div "#right"
Is there a way to edit this function to do what I want ?
You can append data to the url by using
window.location.hash
https://developer.mozilla.org/en-US/docs/DOM/window.location
If you search for QueryString in jQuery plugins, there should be dozens of plugins that simplify this task.
I'd use localStorage. It's like cookies but much, much easier to maintain. The only downside is that it's not supported by all legacy browsers (See http://caniuse.com/#search=localStorage for browser support). For an orview on thhe feature, see https://developer.mozilla.org/en-US/docs/DOM/Storage If you want to go with completely no cookie like features at all; well then it has to be done server side to the best of my knowledge
Without cookies, your task will be a little bit harder. But I may have two solution for you:
Using session on server, you can control which ajax has been call, so next time when the main page is loaded, you can append the new content to it.
Using url hash to append ajax anchor has been click #anchorname so you can click it a gain after reload.
The comment tells you how you can modify the url without a page load. You could use that. If you have to work with older browsers, then you can still use the fragment (or do both things).
There are some history plugins for jQuery/JavaScript that manage this .. it's a technique called "deep linking." You may be able to find something simple to work with. Basically when loadContent runs you would want to update the url from /whatever to /whatever#right with the fragment indicating the load-content ID or something like that.
Another alternative would be to set some flag on the server that loads into that div when the page loads initially, which would save you an ajax request too. Depending on how your server code is set up that may not work for you, though.
Before explaining the question, I want to explain my main goal (If there is a better way than my approach):
I have the document element available with me and ideally I wanted to get a browser element such that it identifies a tab uniquely. In my previous approach I used
gBrowser.getBrowserForDocument(doc);
This returned the browser which was indeed unique to the tab (in the sense that attributes stored in it persisted across pages).
If instead, I don't store the browser element, and after moving to another page in the same tab I try the above command again, then the browser is no longer the same one as before (in the sense that it has lost all the stored attributes).
Therein lies my main problem. I want to get hold of the tab browser which I am able to refer to using different documents loaded in the same tab.
I read about a similar function:
gBrowser.getBrowserForTab(tab);
I have a feeling this might work. But again, I am not able to understand where I can get the parameter "tab" from (given a document).
Note: I am using GWT for the development of the extension
EDIT: To clarify the intent of the question, here's the use case as well as my approach:
In my extension, I am interested in monitoring user behaviour on particular websites. In a way it can be thought of as a session which remains active until the user stays on the same website. During the session, I am often required to store various attributes specific to user behaviour. One of the attributes concerning the question in "isSessionActive":"Y" or "" (blank string stands for no)
To make the code more optimal, I do not instantiate a browser for all the tabs in the beginning. Instead, I wait for the cue using an onLoad function. : if a relevant website is visited
Once that happens, I make a call to get the browser using the current document element, see if it has a non empty value for the attribute isSessionActive. If it does not, I set the attributes value to "Y" and instantiate my class which handles the profiling after that.
If it has value "Y", I know that the session is still active and that I don't need to initialize.
The problem which I'm facing is that after the first instantiation, when I move to another page within the same tab, I expected that the call to
gBrowser.getBrowserforDocument(doc);
would get me the browser instantiated previously since it is basically the same tab.
This is not happening. Each time I get a new Browser instance which does not have the attribute isSessionActive as "Y" (probably because the new page has a new document element). Thus, at present all my code instantiates over and over again which is what I do not want.
If you're only working with the current tab (and not any background tabs), then you could just use gBrowser.selectedTab https://developer.mozilla.org/en/XUL/tabbrowser#p-selectedTab
I have a list of items for which I want to show a couple of items, then a "more" button. I would like the more button to show the new items in a popup box. There are many ways to make this work, but I'm trying to figure out what is the best practice.
Here is my approach. We use MooTools and Clientcide on our site:
Directly following the "more" button, I include a div that contains the content I want to put in the popup (the full list, including a duplication of those items that are visible by default), with a class that includes the style "display:none".
I attach an event to the more button that runs a script called "popupNext". popupNext takes the next element after the button (using getNext from mootools), and creates a new StickyWin (via Clientcide and stickywin.ui) with that element as its content. Then (and this is the part that feels especially hacky) it removes the class that includes the "display:none" style from the content element.
Finally, I use element.store() (from mooTools) to store the StickyWin (with the key "win") in the event element. I neglected to mention above: when popupNext runs, it first checks via element.retrieve() whether there is an existing StickyWin, and shows it, if there is.
This all seems OK, I guess--the biggest disadvantage is page bloat--while I'm showing only first couple of elements of each list, there may be more that are loaded with each page but never seen. But I'm curious whether there is some better, standard way of doing this. For example, I could reduce bloat by retrieving the elements via ajax, at the expense of slower response when a user wants to see the full list.
Check out StickyWin.Ajax - it seems to be closer to what you need than the plain StickyWin.
I have been using hashes to pass data between pages (like setting scrollTop(), etc.) and have also used the hashChange event to trigger changes on a given page.
However, hashes have default behaviors that I'm not necessarily interested in, like making the page jump to a given (sometimes insignificant) spot.
I feel like getting/setting a query string would be more logical, but:
Is it?
Is there an event I can listen for when the query string is set?
Are there query-string-related behaviors I should know about?
It depends on what you're doing.
A query string change will always trigger a page reload. The only part of the URL you can change without a page reload is the #-part.
In javascript applications, page loads are generally not okay. But it may be possible to use when having a traditional html page request/response model.
There's no event AFAIK though, since it will change page.
As the other answer says, changing the query string will cause a page reload. As far as the browser is concerned you'll then be on a completely new page.
There are events that will fire when you do this. The ’beforeunload` event will fire, however it won't be very useful as it also fires when the user clicks on a link or closes the window.
Effectively the event that will fire if you change the query string will be the load event on the new page that it loads.
It is illogical to reinvent anchor behaviour. It is better to not expose hash links to insignificant fragments (although modern browsers are doing scrollIntoView() for any element with id, there is a dedicated behaviour for <a name="xxx">). So, answer is yes here, page arguments should be passed via querystring.
Event is window.beforeunload, yes, page reload when javascript:void(location.search='some') has been set
There are no surprises, have a look
Also, on working with querystring: http://xkr.us/js/querystring