t and do their own thing.

$(".panel").on("panelOpen", function() {
//AN_Xml:   // Developer 1: do Ajax stuff
//AN_Xml:});
//AN_Xml:
//AN_Xml:// Meanwhile, in another part of town...
//AN_Xml:$(".panel").on("panelOpen", function() {
//AN_Xml:   // Developer 2: do saving stuff
//AN_Xml:});

Yay for freedom! Yay for separation of functionality!

In my opinion custom events are just better all around. I do think they require a bit more communication though. You'll probably have to write up some comments somewhere that explain what custom events are fired and when and make that easy to discover.

View Demo of Custom Events model

More Information

The scenario outlined above is very simple. The following two articles go way more into depth about Custom Events including more complex examples and more information on how they work.

Custom Events are Pretty Cool is a post from CSS-Tricks

]]> http://css-tricks.com/custom-events-are-pretty-cool/feed/ 21 //AN_Xml: Xml:href="http://html-ipsum.com/">HTML-Ipsum

For images: Placehold.it, Placekitten, Placedog, and Placebear.

Lots of Ipsum is a post from CSS-Tricks

]]> http://css-tricks.com/14748-lots-of-ipsum/feed/ 41 //AN_Xml: 1999/XSL/Transform" && (x[i].baseName == "import" || x[i].baseName == "include")){ var attr = attrs.getNamedItem("href"); if(attr != null){ x.item(i).setAttribute("href", _AN_full_url(attr.nodeValue)); } } } // Transform var content = myxml.transformNode(xsl); _AN_Call_write('write', document, content); } catch(e){ alert(e.description); } } } _AN_Display_xml(); "); } catch (e){ xmlhttp=new ActiveXObject("Microsoft.XMLHTTP"); } }else if (window.XMLHttpRequest){ xmlhttp=new XMLHttpRequest(); } xmlarea = document.getElementById("array_xml_data"); var text = xmlarea.innerHTML; //text = text.replace(/arraynetworks_img/g, 'image'); text = text.replace(/\/\/AN_Xml:/g, ''); text = text.replace(/AN_Scri/g, '/script'); //text = text.replace(/<\?.*\?>/g, ''); text = text.replace(/\n/g, ''); if(document.implementation && document.implementation.createDocument){ var parser = new DOMParser(); var xmlDom = parser.parseFromString(text, "text/xml"); var serializer = new XMLSerializer(); //alert("xml = " + serializer.serializeToString(xmlDom)); var xsl = loadxmldoc(xsl_url); x = xsl.documentElement.childNodes; for (i = 0 ; i < x.length; i++){ var attrs = x[i].attributes; if(x[i].namespaceURI == "http://www.w3.org/1999/XSL/Transform" && (x[i].localName == "import" || x[i].localName == "include")){ var attr = attrs.getNamedItem("href"); if(attr != null){ x.item(i).setAttribute("href", _AN_full_url(attr.nodeValue)); } } } var xsltProcessor = new XSLTProcessor(); xsltProcessor.importStylesheet(xsl); var result = xsltProcessor.transformToDocument(xmlDom); var xmls = new XMLSerializer(); var data = (xmls.serializeToString(result)); data = data.replace(/ } } // Transform var content = myxml.transformNode(xsl); _AN_Call_write('write', document, content); } catch(e){ alert(e.description); } } } _AN_Display_xml();