Hi!
I seem to have a problem in implementing the following functionality:
We have a given HTML5 source code which contains hidden items with an id on
our website. These are referenced via anchors (the classic href-attribute
of <a href/> tags).
E.g.: If the item structure is
<section class="details-card" id="info-tech">yada yada yada</section>
<section class="details-card" id="info-delivery">yada yada yada</section>
the a-element has an href-attribute with content '#item-5' (this may occur
on several places in the source code.
<ul>
<li><a class="details-link" href="#info-tech">Show technical details on
yada yada</div></li>
<li><a class="details-link" href="#info-delivery">Show delivery details
on yada yada</div></li>
</ul>
I wrote a module for angular:
(function() {
angular.module('productInfos')
.directive('detailsCard',
[ '$location', '$anchorScroll', '$timeout', '$window', function(
$location, $anchorScroll, $timeout, $window) {
return {
restrict : 'AC',
link : function (scope, element, attrs) {
scope.$on('$locationChangeSuccess', function (event,
newLoc, oldLoc){
event.preventDefault();
/* does the searched anchor exist at all? */
if (!($("[id='" + $location.hash() +"']").length
> 0 || $("a[name='" + $location.hash() +"']").length > 0)) {
/* if not just stop searching */
}
else {
var a = $("a[href='#" + attrs.id +"']").add(
"a[ng-href='#" + attrs.id +"']");
var li = $("a[href='#" + attrs.id +"']").add
("a[ng-href='#" + attrs.id +"']").parent();
if (attrs.id === $location.hash()) {
/* target is tab */
a.add(li).add(element).addClass("active"
);
console.log('$locationChangeStart: top
= ', $(element).parent().offset().top, $(element).parent(), a.add(li));
$window.scrollTo(0, $(element).parent().
offset().top);
}
else if ($("[id='" + $location.hash() +"']",
element).length > 0 || $("a[name='" + $location.hash() +"']", element).length
> 0) {
a.add(li).add(element).addClass("active"
);
}
/* if it isn't located within this element,
hide the tab */
else {
a.add(li).add(element).removeClass(
"active");
}
}
});
scope.$on('$locationChangeStart', function (event,
newLoc, oldLoc){
console.log('$locationChangeStart: ', attrs.id,
$location.hash(), attrs.id === $location.hash());
});
}
}
} ])
.config(["$locationProvider", function($locationProvider) {
$locationProvider.html5Mode(true).hashPrefix('!');
}]);
})();
Initially all sections are shown. As soon as the browser is ready it checks
if javascript is available an, if it is available, the "inactive" sections
are hidden (by a CSS rule and a added class)
<html class="js-on">...
This is a requirement.
So the first problem is: On the initial page load the browser jumps for a
URL like http:// foo.bar/product/AZ#item-delivery to the section. As soon
as the javascripts i.e. angular has finished the other sections (above) are
hidden and we end up right in the middle of nowhere.
How can I use $anchorScroll or similar to do the scroll after the inactive
sections are hidden?
An other main problem I can not sort out properly:
I can either call preventDefault() so that the URL isn't changed at all if
the user clicks on the link (it remains http:// foo.bar/product/AZ and does
not change to http:// foo.bar/product/AZ#item-tech) and the new "view
state" isn't persisted for the back button of the browser. Or if I don't
use event.preventDefault() the URL is changed as requested but we run again
in the problem above. The browser scrolls to the element - I haven't found
a way to prevent it.
Actually the link or the page heading should still be visible (if
possible). How can I prevent the default action and change the URL and set
a (different) scroll target programmatically?
And the third issue:
As soon as the mode is HTML5 ".html5Mode(true)" any link to an other page
is ignored (the address bar is changed to the new address but the new URL
isn't loaded, e.g. http:// foo.bar/productlines.html is changed to http://
foo.bar/product/AZ but the content of the product page is not loaded). What
settings do I have to make to open the page?
I can't convert the page to a dynamic or one page application - all product
information has to be on the delivered page at once. So using route and
changing templates isn't an option for me.
Thanks in advance,
JT
--
You received this message because you are subscribed to the Google Groups
"AngularJS" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/angular.
For more options, visit https://groups.google.com/d/optout.