I'm currently developing an ajax application and I'm looking for a feature that lets me intercept all static and dynamic links using javascript. The links look like these:
link 1
link 2
etc.
I then want the browser to redirect to: current.page/#link1/ rather than current.page/link1/. I'm using jQuery, so the live() function is an option, however using that as a solution just seems rather sluggish to me(am I hysterical?). If there is a way to intercept ALL links on a page, maybe through detecting a change in the address, that would greatly help. I've tried a few plugins for jQuery (jQuery address & SWFaddress) but they only seem to have event handlers that respond to changes in anchor tags in the address. Any ideas?
thanks for your time
Don't worry to much about performance unless you have to. Often the elegant solution is also the right one.
I would use jQuerys live function, bind to the click event and rewrite the link as it is being clicked on.
Hope this helps, Egil.
What the live function does is it binds an event handler to the document, which catches all click events and then detects all clicks that match the selector, in your case the link elements. This is the most efficient way of catching all link clicks.
Related
I want to create a "confirm plugin" that will fire first and ask the user if "they are sure". Just to be clear, I will be using a custom made confirm box, not a the default Window confirm() Method.
If yes then it will fire all the other events that have been bound to it. If no then it will do nothing.
A use case would be a delete button that has a separate click event bound to it, which when pressed will delete an element.
If I attach my plugin to the button then it will bind another click event and by using the events info inside $._data I can send my even to the top of the list (making it fire first), I then stop propagation (this stops the other binding firing which deletes the element). If the user clicks ok on my confirm box, I trigger a click again this time just bypass the stop stuff and it will then fire the original events
I am using a slightly modified version of https://github.com/private-face/jquery.bind-first
The only way it can access this info on an element is by using:
$._data($(this)[0]).events
I want to know how "future proof" this is as I know this changed already since 1.7. Are there any plans to officially support a similar thing.
If all else fails, I know I can just make sure that the plugin and the bindings happen first in the code, but this is not really the most flexible solution.
Using $._data is a smelly solution, hence this post. Maybe there are some fancy custom event things I can do?
The short and simple answer is not at all. Using, or more importantly relying on undocumented features is never a good idea.
It sounds like you have an XY Problem here. There are likely many other ways to achieve what you're trying to do here, and using $._data is almost certainly not the best solution.
I've encountered an annoying issue while working on YUI.
I have a main area and a navigation block. The elements in the main area can be activated with a direct click or by clicking an element in the navigation block that triggers the appropriate element in the main area.
As it turns out, triggering a click event programmatically in YUI isn't as simple as I thought it might be. Looking at the documentation I found pleanty of information on how to attach and delegate events but not how to call one.
I found this question, but it deals with creating a new custom event and not calling an existing one.
All other similar questions are answered with using .simulate(), but this is actually not the best option for compatability reasons and it's also not recommended by YAHOO itself for client-side use http://yuilibrary.com/yui/docs/event/simulate.html#faking. EDIT: After re-reading the section I realized the warning is irrelevant for the subject of this question.
I found a solution by calling the click() command in the node's DOM element, but this is really a last resort and I would like to know if there's a more "clean" way to do it through YUI.
Here is an example of what I'm doing now: http://jsfiddle.net/3fso2dg8/
In the example, the second button is triggering the click event of the first button by using the DOM element
Y.one('#clickme')._node.click();
CONCLUSIONS
After more fiddling with the code I came to realize simulate() is the preferred option in most cases, but not all.
The YUI vesrion I'm required to work with (3.14) has a known issue on simulating a click event in IE9 and above. Since - for other technical reasons - I cannot upgrade to whatever version this issue was fixed and I need to keep a multi-platform compatibility, my original solution is still the best option. Anyone else that uses YUI components that don't respond well on IE, maybe you stumbled upon the same issue so this is one way to solve it.
After looking for exactly the same functionality I just used simulate in user-facing code - where It would just mimic clicking with no return method etc. (simple submit button or choose fil trigger).
When I would needed "complex" functionality I would just add a class or new ID and add new delegate or "on" method in my code - following the: "If a function needs to respond to user action or be called programmatically, it should be written accordingly and called directly in the latter case." prinsipp.
So to summarize - I use simulate for very simple effects with no callbacks or other "advanced" stuff and (sadly) duplicate other delegate/on elements where simulating would be tricky...
Had also looked into your method (._node.click();) and I can't see no obvious difference comparing to simulate()...
In a very common scenario, I have an HTML page with an "Add" button that opens a modal dialog (through Facebox) and asks the user to select an item from the list that appears in it.
The modal dialog gets its HTML snippet from the server asynchronously. I want this snippet to be reusable in many parts of my application so it shouldn't assume that I am using Facebox to load it. The only thing it should do is to trigger the item-selected event whenever the user selects an item in it. But since the snippet is loaded asynchronously, I cannot use $(document).ready. That is, I cannot trigger the event like this:
$(document).ready(function() {
$(".item").click(function() {
$(".items-modal-dialog").trigger("item-selected", this);
});
});
Also, I don't really like using the items-modal-dialog class to identify the enclosing DOM element.
I came up with some solutions to this, and I would like to know if there is some superior pattern that I am missing, because I think this is a very common problem.
Put the script after all the HTML so I am sure that the snippet DOM is loaded (I think this is a bad practice)
Creating a JavaScript function that loads the snippet with Facebox and then binds the events. This way I assume that I am using Facebox and also have to create a function for every type of modal dialog that I create. The only positive side I see in this is that I can create the items-modal-dialog DIV programmatically so I don't have to use a class to identify it.
Using jQuery live to bind the events.
Using an iframe and $(document).ready.
Any suggestions would be greatly appreciated.
Using jQuery's live or delegate function would be the best solution in my opinion.
I have a website, where I allow other developers to host content.
My aim is to log clicks on every hyperlink (even the content that is hosted by other developers) ,which exists on the page.
My initial approach was as follows:
$('a').click(function(event)
{
//do my logging
return true;
}
);
Now with the above approach , I am facing the following issues:
Developers may have images inside the anchor link, so the events target is an image rather than href
Many developers have their own way of handling an href click , using an onclick event rather than a simply href='' attr
Some developers add their custom attr , to the tag, and have custom functions to handle the clicks
so basically , the issue is , there is a huge variety of anchor tags available, and logging clicks is not as simple.
Many cases allowed me to log the data I wanted, but a few cases , broke the code badly.
My aim to post on this forum was:
to discuss what is the right approach to do hyperlink clicks logging in a dynamic environment
is there a plugin out there , which allows a functionality like this.
I know facebook and google have this , but they have a totol control, on what is being hosted in their environments.
Any help is greatly appreciated.
Adding a click handler to every link is not a good idea. You should make use of event delegation (which will only attach one event handler at the root of the document):
$(document).delegate('a', 'click', function(event) {
// logging
});
Update (17.12.2011):
Since jQuery 1.7, one would use .on() [docs]:
$(document).on('click', 'a', function(event) {
// logging
});
Regarding your problems:
Developers may have images inside the anchor link, so the events target is an image rather than href
Events bubble up as long as propagation is not canceled. It depends on what you want to log. With delegate the event.target property will point to the image, but this (inside the handler) will point to the a element.
So you should have no problems here (example: http://jsfiddle.net/cR4DE/).
But that also means to you will miss clicks if the developers cancel the propagation.
(Side note: You could solve this letting the event handler fire in the capturing phase, but IE does not support this (hence jQuery does not either).)
Many developers have their own way of handling an href click , using an onclick event rather than a simply href='' attr
This will not touch existing event handlers.
Some developers add their custom attr , to the tag, and have custom functions to handle the clicks
Not sure what you mean here.
It also depends on how the other content is included. E.g. the above code won't track clicks in iframes.
In your logging code you should check for the bad cases and deal accordingly.
For example in your first case i you get the image and walk the dom up until i would find an a tag and log the href from there.
There will be some cases in which you will not be able to do the logging but if they are small compared with the cases you can do that you will be fine :).
JQuery events are annoying me. The thing is that I very often use
javascript (after ajax requests, etc.) to draw up new elements
(buttons, divs, etc.). I've got a list of elements
which you can press on an edit button so you can manipulate the one
linked to the selected edit button.
Now if someone submits a form to make a new element like the ones who
existed before, and I submit it with ajax and then I append or prepend
the new element into the list. After that the new edit button for the
new element isn't linked to JQuery's event system since the DOM hasn't
been reloaded after the edit button was made. If I call the same
javascript file with the events in it, then the edit button works but
then when people click other edit buttons the event happens twice for
them since they're bound twice. I've also used .bind() but that only
binds (I think) the same event twice as before. I don't remember at
the moment how I tested it. I haven't tested .one() but I would rather
not use it since some events must be called more than once.
I just wanted to ask you guys what approach you use when dealing with
the events?
P.S. I'm binding the JQuery event to the class attribute that all the elements have. If I was going to bind this to each element based on ID, then this wouldn't be a problem because then I would just use .bind(). By writing this I suddenly though of using .unbind() and then .bind() to link the elements to the events system. What do you think of that? Would you do it in another way?
Thanks in advance.
Kristinn.
You're looking to use $.fn.live:
$('a').live('click', function(e) {
e.preventDefault();
alert('im attached even if the DOM has been updated!');
});
http://docs.jquery.com/Events/live
Your question is a bit general, but I have a feeling that what you're looking for is jquery live
http://www.thewebsqueeze.com/tips-and-tricks/tip-for-jquery-live-event.html
http://simpable.com/code/jquery-live-events/
http://www.thefutureoftheweb.com/blog/jquery-live-events
http://kylefox.ca/blog/2009/feb/09/live-event-binding-jquery-13/