What's the best way to "preserve" and "re-display" portions of an html page, along with jquery event handlers you've set up?
More detail:
I'm writing a "one-page javascript application" that lets users perform two different calculations. The user selects which calculation they want by clicking a radio button.
When they click radio button A, a big part of the UI needs to get displayed with appropriate html controls (and jquery event handlers) that allow the user to enter the parameters for calculation A.
Likewise, if the user clicks radio button B, that section of the page needs instead to show all the controls (and its associated jquery event handlers) that allow the user to enter the parameters for calculation B.
My question is how to best handle the swapping of calculation A and B's html controls and their associated jquery event handlers?
I had thought about just using jquery's .html() to get and set the parameter section part of the page, but I'm thinking that will not preserve any event handlers that I'd set up for those controls. Is that right? In that case, I'd need to either re-wire up the event handlers as the user switches between calculations or do something else.
(In essence I think what I want to do is to be able to preserve a chunk of the dom (which hopefully includes jquery event handlers) but I don't write a ton of jquery and am I'm not sure how to approach that... I'm wondering if I could get the whole parameter section of a page represented as a jquery node, and save that off (to a js variable) and restore it, as needed, if that would do the trick??
Thanks for any ideas!
Michael
Honestly, usually it's easier just to hide()/ show() elements rather than removing them/ re-adding them.
Add a calculation-1 class to elements you want to be visible for the first calculation, and calculation-2 for the second calculation elements. This will let you get a jQuery variable of all calculation 1 and 2 elements via $('.calculation-1') and $('.calculation-2).
You can then add an event handler for the radio's that hide() and show() the elements accordingly.
If you use html(), you'll lose events bound to the elements children. Unless you attach your handlers to an ancestor which you don't remove.
You can also use detach(), which will remove the elements from the DOM, but persist the event handlers you added. However, if your elements are dotted all over the DOM, it's hard to track their origional position, and TBH is more effort than it's worth.
Related
I'm learning HTML, CSS and JS with Angular and JQuery at the moment. I have a div "eventBoxes" where you can add as much divs called "eventBox" as you want. Therefore, I have one template of such an eventBox in my HTML file, which i clone, make displayed and add to the div "eventBoxes" when the user wants to add a eventBox.
I now want to get the inputs, that are made in the eventBoxes (one eventBox has several textfields), but obviously they all now have the same id.
What is a good practice in JS to differ between these same eventBoxes, sothat i can handle each eventBox separately? Do I really have to change the ID's before adding or is there a better way to do so?
If your templating a list then the individual list items should not carry an ID or the ID should also be templated as well in order to avoid duplicate IDs. Event handling on those elements should be performed using the event handler context element. For example if you handle click for an input, then the context of the click event handler would be the specific input that was clicked. Also the event object gives you access to specific context for the event like for example event.target carries a reference to the specific element the click was performed on.
Say I have a JQuery object, el, that has selected an element. Is it legal, safe, and reasonable to call el.trigger("change") if the selected element is a DIV? What about other element types? For that matter, can I call el.change()?
The JQuery documentation for .change() says:
The change event is sent to an element when its value changes. This event is limited to <input> elements, <textarea> boxes and <select> elements.
It's not clear to me what "limited" means here. It might be referring to the fact that these are the only three element types that will produce these events automatically, but it could instead mean that other elements aren't allowed to.
Empirically, Chrome v28 seems to allow it, but I want to know if I can expect it to work in general.
Goal
I have a pseudo-control that's composed of a set of buttons and spans wrapped in a div. Each instance of the control maintains and manages a value, which is modified by clicking the control's buttons. When the value changes, I need to send an event out from the div so that the rest of the page can react. I don't want to listen for the click events outside the control, since that couples the surrounding code to the controls' internals and not all clicks change the value.
I could create a new event name, but the built-in "change" event seems like conceptually correct, so I'd rather use it if I can. As an added bonus, my page already a "change" handler bound the right place with the right behavior (because I have some input and select controls on the page, too).
I need to support IE8 and up, in case the answer varies by browser make and version.
There are no restrictions, you can trigger any event type you like on any HTML element.
The jQuery documentation is simply telling you that change is only automatically triggered on <input>, <textarea> and <select>
I'm not really sure how to go with this, but here goes:
I have form elements that trigger a function (mainly for validation purposes). This triggers on click, on change etc. These are written with vanilla JavaScript.
If it's a straight-forward HTML element then everything works fine. E.g. a element fires on change.
However, if I use a jQuery script (e.g. a jQuery colour selector), then although that jQuery script populates an field, the validation script doesn't fire.
This I suppose is obvious as you don't click, blur, change it, it's just the jQuery script changing it.
Of course I could change the JavaScript in the colour selector jQuery script so it also fires the validation script, but there must be a better way where as well as on click, on change, on blur etc. I can also activate the function when it picks up that another script is changing it. I need this for various occasions and scripts.
Another example is a rating script (rate out of 5). It uses radio buttons as a non-jQuery fallback and the jQuery script just hides those radios (with CSS), displays the star images and then changes the radios when the user interacts with the star images. That way the server handles a form submit the same way regardless of the availability of jQuery. However, the validation script doesn't fire.
Any ideas?
Apparently the elements are being inserted on the dom after the javascript run.
try using $.live() instead of $.blur()
so even if this script elements are inserted after the page rendered, events will be bound to em.
http://api.jquery.com/live/
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'm wondering which is better for performance... I have a "web app" sort of thing. It has a lot of javascript. When a button is clicked, a hidden div becomes visible. This new div has 5 buttons. Which is better for performance:
1.) put the button click events in the html tag of each button like onClick="alert('hey');"
2.) Attach events to each button when the div is visible, and then remove the events when I hide the div containing the buttons?
The reason I ask is because I imagine the page might get bogged down if the events in the html tags are constantly there. I figure the page might be faster to only have those events when the user can see the buttons to click them.
Any help is great! Thanks!
I would use event delegation.
This way you can freely add/remove any buttons without worrying about attaching events on each one of them. This approach is also more memory efficient, since you always have one single event handler instead of N ones directly on each button.
Unless those events are causing something to act as a link (which it seems Google learned to read) the put all this JS outside your HTML. It makes your code tidier and more maintainable.
Can't be sure about performance.
Keeping the event handlers registered when the elements are hidden will have no impact on performance, since the events won't fire.
Whether to use HTML attributes or the DOM to register event handlers isn't a matter of performance, it's a matter of clean design. You'll want to keep presentation as separate from behavior as possible. This means that if you use attributes, they should only bind the event to a handler (i.e. call a single function) rather than contain more complex code. That is, don't:
<button onclick="if ('red'==this.parent.style.backgroundColor) {...}">...</button>
do:
<button onclick="clickColorButton(event)">...</button>