I have the following code to get the ID of a <a href="#ID"> </ a>
and go to their respective div <div id="" />
:
$('a[href=#certificados]').click(function(e){
e.preventDefault();
$("html, body").animate({ scrollTop: $('#certificados').offset().top }, 1000);
});
$('a[href=#team]').click(function(e){
e.preventDefault();
$("html, body").animate({ scrollTop: $('#team').offset().top }, 1000);
});
$('a[href=#house]').click(function(e){
e.preventDefault();
$("html, body").animate({ scrollTop: $('#house').offset().top }, 1000);
});
$('a[href=#contact]').click(function(e){
e.preventDefault();
$("html, body").animate({ scrollTop: $('#contact').offset().top }, 1000);
});
How could I optimize the code?
4 Answers 4
Get the "respective" div in a more general way from the link's href
attribute:
$('a[href=#certificados], a[href=#team], a[href=#house], a[href=#contact]').click(function(e){
e.preventDefault();
$("html, body").animate({ scrollTop: $(this.hash).offset().top }, 1000);
// this.hash would be equivalent to $(this).attr("href") in your case
});
Probably you also can use a much better selector now - maybe selecting those links by a common class.
-
3\$\begingroup\$ Bad thing about this solution is maintaining the list of items and the slower look-up. You would be better off using a common classname. \$\endgroup\$epascarello– epascarello2014年01月14日 14:25:44 +00:00Commented Jan 14, 2014 at 14:25
-
3\$\begingroup\$ @epascarello: That's what I suggested in the last sentence :-) \$\endgroup\$Bergi– Bergi2014年01月14日 14:36:07 +00:00Commented Jan 14, 2014 at 14:36
-
\$\begingroup\$ Just hoping the OP saw it. :) \$\endgroup\$epascarello– epascarello2014年01月14日 14:46:38 +00:00Commented Jan 14, 2014 at 14:46
If you want to make the code DRYer, you can do
['#certificados', '#team', '#house', '#contact'].forEach(function(anchor){
$("a[href="+anchor+"]").click(function(e){
e.preventDefault();
$("html, body").animate({ scrollTop: $(anchor).offset().top }, 1000);
});
})
If all internal links are to be handled this way, do
$('a[href^="#"]').click(function(e){
e.preventDefault();
$("html, body").animate({ scrollTop: $(this.hash).offset().top }, 1000);
});
-
\$\begingroup\$ Why a forEach? jQuery supports multiple elements in a selector! \$\endgroup\$epascarello– epascarello2014年01月14日 14:01:25 +00:00Commented Jan 14, 2014 at 14:01
-
\$\begingroup\$ @epascarello to not compute n and to be dryer on the a[href=...] thing \$\endgroup\$Denys Séguret– Denys Séguret2014年01月14日 14:01:51 +00:00Commented Jan 14, 2014 at 14:01
-
\$\begingroup\$ Maybe rename
n
toanchor
?, +1 \$\endgroup\$konijn– konijn2014年01月14日 14:04:35 +00:00Commented Jan 14, 2014 at 14:04 -
1\$\begingroup\$
this.href
does not work \$\endgroup\$Bergi– Bergi2014年01月14日 14:14:29 +00:00Commented Jan 14, 2014 at 14:14 -
1\$\begingroup\$
this.href
returns the full URL, You would need to usethis.getAttribute("href")
or$(this).attr("href");
or hash jsfiddle.net/7439C/1 \$\endgroup\$epascarello– epascarello2014年01月14日 14:22:34 +00:00Commented Jan 14, 2014 at 14:22
You can make an extension, that will let you specify what link scrolls to where, without creating a hard dependancy between the href
attribute and the target identity:
$.fn.scrollTo = function(target){
return this.click(function(e){
e.preventDefault();
$("html, body").animate({ scrollTop: $(target).offset().top }, 1000);
});
};
$('a[href=#certificados]').scrollTo('#certificados');
$('a[href=#team]').scrollTo('#team');
$('a[href=#house]').scrollTo('#house');
$('a[href=#contact]').scrollTo('#contact');
-
\$\begingroup\$ Nice, but this doesn't optimize it at all. \$\endgroup\$Silviu Burcea– Silviu Burcea2014年01月14日 22:36:01 +00:00Commented Jan 14, 2014 at 22:36
-
\$\begingroup\$ @SilviuBurcea: Funny that you should single out this answer and point out that it won't optimise the code (and I assume that you only mean optimise for speed, not any other aspect), as neither of the previous answers does that either... \$\endgroup\$Guffa– Guffa2014年01月14日 23:13:56 +00:00Commented Jan 14, 2014 at 23:13
Add a class to the anchors, like scrollable
.
$('.scrollable').click(function(e){
e.preventDefault();
$("html, body").animate({ scrollTop: $(this.hash).offset().top }, 1000);
});
Each is called under the hood, no crazy functions, just KISS.