Sos = function() { return { /** * Returns a prefixed class name from an element without the prefix * (ie returns "dynamicData" from .value-holder-dynamicData). * Can be used for specifying settings etc in class names. * @param {Object} el * @param {Object} prefix */ getClassNameValue: function(el, prefix) { var ret = new RegExp(".*" + prefix + "(.*?)(?:\\s|$).*").exec(el.className); if (ret) { return ret[1]; } return null; }, init: function() { /*@cc_on if (@_jscript_version==5.6 || (@_jscript_version==5.7 && navigator.userAgent.toLowerCase().indexOf("msie 6.") != -1)) { try { document.execCommand("BackgroundImageCache", false, true); } catch (e) {} } @*/ // Always check if window is active (ie is in foreground and not in inactive tab etc) window.isActive = true; $(window).live("focus", function() { this.isActive = true; }); $(window).live("blur", function() { this.isActive = false; }); // Init functions Sos.print.init(); Sos.addAnchors.init([ { element: ".teaser", include: ["P", "IMG"], add: false } ]); Sos.slideshow.init(); Sos.sponsorForm.init(); Sos.carousel.init([ { element: ".shop-teasers UL", navigation: true, autoplay: true, delay: 800 } ]); Sos.startpage.init(); } }; }(); /** * Add print functionality */ Sos.startpage = function() { return { init: function() { $(".featured-projects LI").live("click", function(e) { e.preventDefault(); $self = $(this); $(".featured-projects LI").removeClass("selected"); $self.addClass("selected"); var n = Sos.getClassNameValue(this, "toggle-"); $(".featured-projects .teaser").hide(); $("#featured-project-" + n).show(); }); } }; }(); /** * Add print functionality */ Sos.print = function() { return { init: function() { var tools = $("ul.article-tools"); if (tools.length > 0) { $li = $("
  • Skriv ut
  • "); tools.append($li); $li.click(function() { print(); return false; }); } } }; }(); /** * Generic carousel function * @param {object} An associative array of elements and options * element (mandatory) The ul to make a carousel of * enumerate (optional) Enumerates the carousel and updates it on change * easing (optional, default swing) The easing to use for * delay (optional, default 200ms) The time each change takes * randomStart (optional) Starts the carousel at a random element * navigation (optional) Display backwards and forward navigation elements * centerNavigation (optional) Centers the navigation vertically * clickToChange (optional) Moves the carousel forward when it is clicked * beforeChange (optional) A function that get called before each change is performed * afterChange (optional) A function that get called before each change is performed */ Sos.carousel = (function() { var delay = 8000; var options; var defaults = { easing: "swing", delay: 200 }; var navigationInitialized = false; var change = function($carousel, delta) { if (!$carousel.data("working") && window.isActive) { var options = $carousel.data("options"); $carousel.data("working", true); if (options.beforeChange) { options.beforeChange.call($carousel, delta); } if (delta > 0) { $li = $carousel.find("li:first-child"); $li.animate({ "marginLeft": -$carousel.data("width") }, { easing: options.easing, duration: options.delay, complete: function() { $carousel.append($li); $li.css("marginLeft", 0); if (options.afterChange) { options.afterChange.call($carousel, delta); } $carousel.data("working", false); } }); } else { $li = $carousel.find("li:last-child"); $li.css("marginLeft", -$carousel.data("width")); $carousel.prepend($li); $li.animate({ "marginLeft": 0 }, { easing: options.easing, duration: options.delay, complete: function() { if (options.afterChange) { options.afterChange.call($carousel, delta); } $carousel.data("working", false); } }); } if (options.enumerate) { enumerate($carousel, delta); } } }; var enumerate = function($carousel, update) { var no = $carousel.data("no") + update; var noOfLis = $carousel.data("noOfLis"); if (no >= noOfLis) { no = 0; } else if (no < 0) { no = noOfLis - 1; } $carousel.data("no", no); $("#" + $carousel.attr("id") + "-enumeration").html((no + 1) + " av " + noOfLis); }; var startAuto = function($carousel) { var autoplay = setInterval(function() { change($carousel, 1); }, delay); $carousel.data("autoplay", autoplay); }; var stopAuto = function($carousel) { var autoplay = $carousel.data("autoplay"); if (autoplay) { clearInterval(autoplay); $carousel.data("autoplay", null); } }; var DOMReady = function() { var noOfCarousels = 0; var i; for (i = 0, ln = options.length; i < ln; i++) { $(options[i].element).each(function() { var cOptions = jQuery.extend({}, defaults, options[i]); $ul = $(this); var carouselId = "carousel-" + noOfCarousels; $ul.attr("id", carouselId); $li = $ul.find("li"); var noOfLis = $li.length; var width = $ul.width(); $ul.css("overflow", "hidden"); $ul.width(width * noOfLis); $li.css({ "float": "left", "display": "block", "visibility": "visible" }); $parent = $("
    "); $parent.css({ "overflow": "hidden", "position": "relative" }); $ul.wrap($parent); $parent = $ul.parent(); if (cOptions.addMargin > 0) { var margin = cOptions.addMargin; $parent.css({ "marginLeft": margin, "marginRight": margin }); width = width - (2 * margin); } $parent.width(width); $li.width(width); var startNo = 1; if (cOptions.randomStart) { startNo = Math.floor(Math.random() * noOfLis); var j; for (j = 0; j < startNo; j++) { $ul.append($li.get(j)); } } $ul.data("noOfLis", noOfLis); $ul.data("width", width); $ul.data("no", startNo); $ul.data("options", cOptions); if (cOptions.enumerate) { $parent.after("

    "); enumerate($ul, startNo); } if (cOptions.clickToChange) { $ul.css("cursor", "pointer"); $ul.click(function(e) { change($(this), 1); e.preventDefault(); this.blur(); }); } if (cOptions.navigation && noOfLis > 1) { $navigation = $("
    FöregåendeNästa
    "); $navigation.data("carousel", "#" + carouselId); $parent.after($navigation); if (!navigationInitialized) { $(".carousel-navigation A").live("click", function() { var $self = $(this); this.blur(); var $carousel = $($self.closest(".carousel-navigation").data("carousel")); if ($self.hasClass("next")) { change($carousel, 1); } else if ($self.hasClass("previous")) { change($carousel, -1); } return false; }); if (cOptions.centerNavigation) { $(window).load(function() { var height = $ul.height(); $li.height(height); }); $navigation.find("A").each(function() { var $self = $(this); $self.css("top", "50%"); $self.css("marginTop", -Math.round($self.outerHeight() / 2)); }); } navigationInitialized = true; } } if(cOptions.autoplay && noOfLis > 1) { $ul.mouseover(function() { stopAuto($ul); }); $ul.mouseout(function(e) { if ($(e.relatedTarget).closest(".carousel-navigation").length === 0) { startAuto($ul); } }); startAuto($ul); } noOfCarousels++; }); } }; return { init: function(initOptions) { options = initOptions; $(document).ready(DOMReady); } }; }()); /** * Sponsor form */ Sos.sponsorForm = function() { return { init: function() { $(".sponsor-form-collapsed").live("click", function() { var self = $(this); self.find(".form-fields").slideDown("normal", function() { self.addClass("sponsor-form-expanded"); var inputs = self.find(":text"); if (inputs.length > 0) { inputs[0].focus(); } }); self.find(".description a").fadeOut(); self.removeClass("sponsor-form-collapsed"); return false; }); $(".sponsor-form-expanded .description").live("click", function() { var self = $(this.parentNode); self.find(".form-fields").slideUp(function() { self.find(".description a").fadeIn(); self.removeClass("sponsor-form-expanded"); self.addClass("sponsor-form-collapsed"); }); return false; }); } }; }(); /** * Adds slideshow functionality */ Sos.slideshow = function() { var idPrefix = "slideshow"; var listSuffix = "-list"; var no = 0; var duration = 1000; var distance = 20; var autoplayInterval = 8000; var easing = "easeOutQuint"; var timer = []; var switchElements = function(list, forward, width) { var el = $(list).find("li:" + (forward ? "first-child" : "last-child")); if (el.nodeType == 3) { el.remove(); el = $(forward ? list.firstChild : list.lastChild); } el.remove(); list.css("margin-left", forward ? 0 : -width + "px"); if (forward) { list.append(el); } else { list.prepend(el); } }; var scroll = function(id, forward) { var el = $("#" + id); var list = $("#" + id + listSuffix); if (!forward) { el.data("itemNo", el.data("itemNo") - 1 < 0 ? el.data("noOfItems") - 1 : el.data("itemNo") - 1); switchElements(list, false, el.data("width")); } else { el.data("itemNo", el.data("itemNo") + 1 == el.data("noOfItems") ? 0 : el.data("itemNo") + 1); } list.animate({"margin-left": forward ? -el.data("width") : 0}, duration, easing, function() { if (forward) { switchElements(list, true, el.data("width")); } }); }; var previous = function(id) { scroll(id, false); }; var next = function(id) { scroll(id, true); }; var goTo = function(id, n) { var el = $("#" + id); var forward = (el.data("itemNo") < n); var steps = Math.abs(el.data("itemNo") - n); var list = $("#" + id + listSuffix); if (!forward) { el.data("itemNo", el.data("itemNo") - steps < 0 ? 0 : el.data("itemNo") - steps); } else { el.data("itemNo", el.data("itemNo") + steps == el.data("noOfItems") ? 0 : el.data("itemNo") + steps); } list.animate({ "margin-left": forward ? -el.data("width")*el.data("itemNo") : -el.data("width")*el.data("itemNo") }, duration, easing, function() { el.data("busy", false); }); }; var construct = function(el, ul, lis, img) { var width = $(img).outerWidth(); el.css({ "width": width + "px", "marginRight": "0px" }); width += distance; el.data("width", width); $(ul).css("width", width * el.data("noOfItems") + "px"); for (var i = 0; i < el.data("noOfItems"); i++) { $(lis[i]).css({ "display": "block", "width": width + "px" }); } if (el.data("autoplay")) { Sos.slideshow.autoplayStart(el.attr("id")); $("#" + el.attr("id")).live("mouseout", function() { timer[el.attr("id")] = setTimeout("Sos.slideshow.autoplayStart('" + el.attr("id") + "')", 1000); }); $("#" + el.attr("id")).live("mouseover", function() { clearTimeout(timer[el.attr("id")]); Sos.slideshow.autoplayStop(el.attr("id")); }); } if (el.data("showNavigation")) { var content = "
    "; for (var i = 0, l = el.data("noOfItems"); i < l; i++) { content += "" + (i+1) + ""; } content += ""; $("#" + el.attr("id") + " .slideshow-navigation a").live("click", function(e) { if (!el.data("busy")) { el.data("busy", true); var target = parseInt($(this).html()) - 1; goTo(el.attr("id"), target); $("#" + el.attr("id") + " .slideshow-navigation a").removeClass("current"); $("#" + el.attr("id") + " .slideshow-navigation a::nth-child(" + (target + 1) + ")").addClass("current"); } else { this.blur(); } e.preventDefault(); }); el.append(content); $("#" + el.attr("id") + " .slideshow-navigation a:first").addClass("current"); } }; var DOMReady = function() { $(".slideshow").each(function() { var el = $(this); var lis = el.find("li"); var noOfItems = lis.length; el.attr("id", idPrefix + no++); el.data("itemNo", 0); el.data("noOfItems", noOfItems); el.data("autoplay", el.hasClass("autoplay")); el.data("showNavigation", el.hasClass("show-navigation")); el.data("busy", false); el.css("overflow", "hidden"); if (noOfItems > 0) { lis[0].style.display = "block"; } if (noOfItems > 1) { var ul = lis[0].parentNode; $(ul).attr("id", el.attr("id") + listSuffix); var img = $(lis[0]).find("img")[0]; if (!img.complete) { $(img).load(function() { construct(el, ul, lis, img); }); } else { construct(el, ul, lis, img); } } }); }; return { init: function() { $(document).ready(DOMReady); }, autoplayStart: function(id) { var el = $("#" + id); timer[id] = setInterval("Sos.slideshow.autoplay('" + id + "')", autoplayInterval); }, autoplayStop: function(id) { if (typeof timer[id] != "undefined") { clearInterval(timer[id]); } }, autoplay: function(id) { next(id); } }; }(); /** * Adds anchors (using the first found anchor in the element as a source) around an * element's inner elements when hovered. Also Sets a class of "hover" on the * parent element when its children are being hovered. * @param {object} An associative array of elements and their inner items to anchor * element (mandatory) The parent element. * include (mandatory) The inner element to be anchored. * add (optional, default is true) Makes the included elements clickable instead of added anchors. */ Sos.addAnchors = (function() { var selectors = ""; return { init: function(settings) { if (settings) { var i; for (i = 0, ln = settings.length; i < ln; i++) { if (settings[i].element) { if (settings[i].include) { var selector = settings[i].element; selectors += (selectors.length > 0 ? "," : "") + selector; var j; for (j = 0, ln2 = settings[i].include.length; j < ln2; j++) { if (settings[i].add === false) { $(selector + " " + settings[i].include[j]).live("click", function() { var $self = $(this); window.location = $self.closest(selectors).find("a").attr("href"); return false; }); } else { $(selector + " " + settings[i].include[j]).live("mouseover", function() { var $self = $(this); var $linkParent = $self.data("linkParent"); if (!$linkParent || typeof($linkParent) === "undefined") { $linkParent = $self.closest(selectors); if ($linkParent.length > 0) { $self.data("linkParent", $linkParent); var href = $linkParent.find("a").attr("href"); if (href !== null && typeof href !== "undefined") { $a = $(""); if (!this.innerHTML) { if (this.parentNode.tagName !== "A") { $self.before($a); $a.wrapInner($self); } } else { $self.contents().each(function() { if (this.tagName !== "A") { $self = $(this); if (jQuery.trim($self.text()).length > 0) { $self.wrap($a); } } }); } } } } if ($linkParent) { $linkParent.addClass("hover"); } }); $(selector + " " + settings[i].include[j]).live("mouseout", function() { var $linkParent = $(this).data("linkParent"); if ($linkParent !== null) { $linkParent.removeClass("hover"); } }); } } } } } } } }; }()); Sos.init();