In Private Logistics: Privacy-Sensitive Calendar, Todo, and Personal Information Management, data that is entered can be edited with a click, and there is support for either entering a link as <a href="... or entering a URL, which will be linkified.
This works great but it presents a problem when someone clicks on a link. The desired behavior is for the link to open and not to put the snippet of text into edit mode, which is the reverse of the usual pattern implemented by event.preventDefault()' or '...return false;}. (Clicks outside the link on the element should put the containing element in edit mode, same as a container that doesn't happen to have a link.)
How can I reverse the more common pattern using jQuery? My best guess now is to attempt introspection on the event target and see if it is an anchor. But that's just a best guess; I have seen plenty of examples of the pattern that would cancel the link loading another page but performing the added Ajax functionality of putting the container into edit mode; I'm not sure I've seen the reverse of that pattern which would follow the link and not put the container into edit mode.
I also see a way to dodge the matter by having links load in the same page, but that's the sort of solution I'd prefer to only adopt if there are intractable issues with implementation or the like.
Generally, you don't want to clean up your broad strokes, instead, don't make such broad strokes. Use an if statement prior to running e.preventDefault().
Something like:
var preventedLinks = $('a.preventthislink');
$('a').click(function(e){
if ($(this).index(preventedLinks) != -1) {
e.preventDefault();
}
});
you could alternatively just change the class of whatever you are preventing default on:
$(document).ready(function(){
$('.blue').removeClass('blue').addClass('green');
});
Related
I know it has been posted before on how to append only once, but my situation is a little unique because I'm attempting to call the function from an href link. I have my code posted on jsfiddle, but it's not working for some reason. The same code on my site works. Can someone help me get this working so that clicking the href link will append a given string to the #services div only one time. The code thats on my actual site appends the "details" over and over again every time I click the link, but I only want it to do it once.
<div id="services">SERVICES</div>
More Details
var details = '<p>Just some additional details</p>';
function moreDetails(){
$('#services').append(details);
}
http://jsfiddle.net/7g59yb5r/1/
I'd use .one() and do it like:
var details = '<p>Just some additional details</p>';
$('a').one('click',function () {
$('#services').append(details);
})
jsFiddle example
I'd strongly recommend you to follow a data attribute based approach for adding such kind of behavior. Otherwise you'll end up with a huge pile of spaghetti code. I recently prepared a small presentation about what I like to call data driven behavior.
Assuming that for your case it would also be fine to show / hide the details with a toggle button you could add such re-usable behavior with a few simple lines of code:
$('[data-toggle-show]').each(function() {
var $element = $(this),
$target = $($element.data('toggleShow'));
$target.hide();
$element.on('click', function() {
$target.toggle();
});
});
Then you can use this functionality anywhere in your markup using a data attribute:
<p>Welcome to the article. Do you want to read more?</p>
<button data-toggle-show="#article-more">read more</button>
<p id="article-more">Here you go! Some more to read...</p>
You can view the example on jsbin
Also, in my opinion, the correct HTML semantics for such behavior is to use a button instead of a link. I've also used a link in the past until I read an interesting debate on where to use a link and where to use a button. Actually the bottom line is that a link should be used where a user can right click to bookmark the URL and a button should be used where you could also decide to disable the possibility to execute the behavior.
Simply do:
<div id="services">SERVICES</div>
More Details
var details = '<p>Just some additional details</p>';
function moreDetails(obj){
obj.setAttribute("href", "")
$('#services').append(details);
}
I have a site that is in English and Spanish, and in each page of the site there is a link that leads to the Spanish version of that specific page, so if the user were on the "home.php" page, it would look like this:
<div id="language">
<ul class="language">
<li class="english"></li>
<li class="divider"></li>
<li class="spanish"></li>
</ul>
</div>
What I would like to do is leave the href and the class in the <a> tags in the HTML blank and assign a class and an href URL to the <a> depending on the page the user is on, that way I could, for example, just add that language div to an external file, and use an <include> to attach it to each page. To accomplish this I'm using the following code:
$('ul.menubar a').each(function(){
if(location.href.match('home.php')){
$('ul.language li.english a').addClass('active');
$('ul.language li.english a').append(function() {
$(this).attr('onclick', 'return false;');
});
$('ul.language li.spanish a').addClass('notactive');
$('ul.language a[href!="home.php"]').append(function() {
$(this).attr('href', 'inicio.php');
});
}
}
The problem is that the English version of the site has 4 links in the navigation bar (home.php, services.php, aboutus.php, contact.php), and the Spanish version likewise (with the corresponding translation of the URL names). I think that having to repeat that code 8 times (1 for each link, 4 links in each language) would be excessive and would actually add more code than simply adding the class and href url in the HTML. The point of using JS would be to simplify things.
So I basically would like to know if anyone can think of a better way to do this, that wouldn't require that much code. I'm trying to avoid having to, in the event that I'd need to change something, have to edit each different page. Also, I would like to know if this is the best way to achieve want I want to do using JavaScript.
HTML is best suited for managing content. CSS is best suited for presenting that content, and JavaScript is best suited for determining how that content behaves. Instead of trying to inject links and control the HTML from JavaScript; instead, leave the content where it belongs, inside the HTML, and use JavaScript to define one or two event-handlers to take action based on the class values on the hyperlinks themselves.
You already have a class on your English hyperlinks, and a separate class on your Spanish hyperlinks, so you can use this to your advantage.
Writing the Click Handlers:
Since toggling your "Language switch" most likely causes a boolean value to be set, you can use two click handlers to target all of your English links and all of your Spanish links, and then control the behavior based on the value of that switch at the time the links are clicked.
// handler for all English links
$('li.english a').click(function(event) {
event.preventDefault();
if(/* Switch is english */) {
window.location = $(this).attr("href");
}
});
// handler for all Spanish links
$('li.spanish a').click(function() {
event.preventDefault();
if(/* Switch is SPANISH */) {
window.location = $(this).attr("href");
}
});
Note that when a link is clicked, we first check the switch. Depending on it's value, we either redirect to that hyperlink, or simply prevent the default behavior -- going to a new page -- from completing.
Handling the Presentation:
Now, your other problem is going to be that, assuming your Spanish site and your English site are one in the same, you'll now see 8 hyperlinks in total. Again, this is where your switch can come in handy.
// single handedly hide or display the relevant content, based on the switch
function switchToEnglish() {
$('.english').show();
$('.spanish').hide();
}
function switchToSpanish() {
$('.spanish').show();
$('.english').hide();
}
Now, I don't know what else is contained in your switch function, but the general idea here is that we don't need to modify the content. We just need to show and hide the content. You'd need to integrate this concept into your existing switch function, if you don't already have something like this in place.
There are several advantages in this approach:
Your Web designers will still see href's in the HTML and can read and understand the HTML without needing your help or needing to go and look at JavaScript code. Not only will they see familiar patterns that they're used to seeing, but you'll likely have a better working relationship with them.
Search engines spidering your site will be able to read the links and follow them.
Browsers without JavaScript will be able to process the links. Some people seem to care about this. I don't. But it's worth mentioning anyway.
In summary, you're right about it being easier to manage in HTML. By using this technique, you can eliminate the repetition in the code that you're rightfully concerned about, and also move the content back to the HTML, as your gut is telling you is the correct thing to do. Not only will your code be more readable, but you'll get better SEO results as well.
I have this HTML:
Track Your Package »
Somebody on this site was able to provide me with a script to prefix the URL with the domain http://www.example.com/ Here's the script:
$(document).ready(function(){
$('a[onclick^="window.open(\'TrackPackage.asp"]').attr('onClick', $('a[onclick^="window.open(\'TrackPackage.asp"]').attr('onClick').replace("window.open('", "window.open('http://www.example.com/"));
});
However, I am having a little trouble with this:
The first issue is where there is multiple instances of the element. Here's a fiddle: http://jsfiddle.net/VMmZx/
Instead of one anchor being signed with ID=4 and the other with ID=5 as intended, they're both being signed with ID=4.
The idea is, each window.open function should be prefixed with http://www.example.com however, the remainder of the URL should remain intact...
The second problem I'm encountering is when the element does not exist on a page, the remainder of the jQuery fails...
Here's another fiddle: http://jsfiddle.net/VPf32/
The <a> should get the class foo, but since the element does not exist on the page, the jQuery does not execute.
Since the JavaScript is being included in the HTML template of the ASP.NET server, this can create many problems.
I hope I've been clear and you can help me. Thanks.
You can use .each() to iterate over each matching element and change them individually:
$('a[onclick^="window.open(\'TrackPackage.asp"]').each(function(index, element) {
element = $(element);
element.attr('onclick', element.attr('onclick').replace(/open\('/, 'open(\'http://www.example.com/'));
});
However, I don't think using links with a href of # and an onclick opening a window is as semantic as it could be. If possible, try changing the markup to this:
Track Your Package »
Now if someone is curious where it will lead them, the browser can show something useful in the status bar when you hover over it.
If you need to adjust the behavior further, add a class and bind for the click event. When they click, prevent the default action and open the window yourself, as you did before.
Why are you doing the click even inline like that? I would just output the links like:
Link Text
And then:
$('a[target=_blank]').click(function(){
var prefix = 'http://domain.com';
window.open(prefix + $(this).attr('href'));
});
When I hover over a url in Chrome, the url is displayed in the Chrome status bar. In my case this results in an ugly javascript:bla-bla-bla reference. Is there any way to change the contents of the status bar when you hover over a link?
Thanks
Although you selected your answer, this idea is an alternative.
You can change the href attribute on mouseover to affect what the status bar says, and change it back on mouseout or click:
function showNiceLink(el, e) {
e = e || event;
el.originalHref = el.originalHref || el.href;
console.log(e.type);
if (/click|out/i.test(e.type)){
el.href = el.originalHref;
} else {
el.href = "http://Linking...";
}
}
<a href="#this is a really UGLY link #1##$$%!!&"
onmouseover="showNiceLink(this,event)"
onmouseout="showNiceLink(this,event)"
onclick="showNiceLink(this,event)">a link with an ugly <code>href</code></a>
I'm pretty sure for security reasons this isn't possible in any browser. Otherwise links to phishing sites will become much, much harder to detect, because attackers can then just place a genuine URL in the status bar while the dangerous link actually leads elsewhere...
Use an onclick event handler for your hyperlink instead, and put a real, meaningful URL in the href attribute in place of the javascript: link (even if the link is meant to be used only with JavaScript).
Your "link"
I guess you mean you want to change what destination is shown for link that is selected? In that case you most likely should put nice url in href attribute, and use onclick attribute for your javascript. Not sure that you can duplicate everything what is done by putting javascritp in href.
Assuming this is what you have:
<a onClick="blabla">Link</a>
Add href="#" to it. Then the # should be shown in stead of the javascript:blabla.
So that would be like this:
Link
It is definitely possible to achieve the desired effect. Just look at what Google puts in the status bar of its search results.
However, you need to use some kind of a trick, e.g. onclick like BoltClock suggested.
Google shows you what you would like to see - a plain, clean URL.
Underneath, however, they use a long redirect URL with monitoring parameters to track you down as you click any result link. That way Google monitors which of the search results are clicked on and which are not.
Unfortunately, most people do not realize that. Quite frankly, I would be very glad to see a browser extension which takes all this dirty tricks down and replaces "tracking" URLs with the "real ones".
I have the problem to "stop" href executing any links.
So my question is:
1) Is it possible replace href-elements that generate internal (#) links with any component, maybe <p>, <div> or <span> (or whatever could be working) that keep the same behaviour of <a> element (hovering, underlined etc) but not executing any link?
2) Alternative, a "trick" to avoiding href elements execute links?
1 or 2 without using jquery or any other js library possibly
Thanks Randomize
There are all sorts of tricks that can be employed to do this kind of thing, but what you need to be careful of is modifying the behaviour from that which the users have come to expect from a browser.
For example , it would be possible to swap the meaning of 'OK' & 'Cancel' buttons, but this would just confuse the user. (An extreme example, I know, but you get the idea)
If you could supply some more information about why you are trying to do this, there may be a better way of approaching things.
You can either add an onclick attribute to specific <a> elements:
Or modify the href like this:
To make them look like links, without redirecting the browser.
If instead, you already have a bunch of links with hrefs, and you simply wish to make them all non-redirecting, then the following jQuery will do this to all links on the page:
$(function () {
$('a').click(false);
});
Although nice and short, the above only works with jQuery-1.4.3+. If you are using an older version, then you can use the expanded form:
$(function () {
$('a').click(function () { return false; });
});
Yes. You can prevent links from the default action - the recommended way is to have links work normally (in case JS is disabled or not available - think "mobile browsers"), and then override the default action with JS.
Unfortunately, due to cross-browser incompatibilities, there are three ways to do this ("traditional","W3C" and "IE") and you need all of them: stopPropagation(), cancelBubble and return false. See a complete example at QuirksMode: http://www.quirksmode.org/js/events_order.html#link9
(Incidentally most JS frameworks abstract this away, so in jQuery you'd do this:
$('a').click(function(event){
// do something on click here
event.preventDefault();
});
This does the same thing as the QuirksMode example, but is a easier-to-read example.)
TO disable the link via js add onclick="this.href='javascript:void(0)';" like so:
link text
You can use a similar tactic to make other elements work link links:
<div onclick="this.href='http://www.mysite.com';"></div>
This is working in IE, chrome and firefox:
text link
In the function return void(0):
function functionX() {
...
return void(0);
}