i have this function in the index page which show a part of the the page and hide the other:
var switchTab = function() {
var p = $(this).parent('li');
var i = p.index();
var s = section.eq(i);
var c = s.find('*');
section.removeClass('active');
sectionContent.removeAttr('style');
s.addClass('active');
c.css({
transform: 'none',
opacity: 1
});
linkParent.removeClass('active');
p.addClass('active');
return false;
};
link.on('click', switchTab);
</script>
now i wanted to jump to a certain part of the page in the index from the menu bar so i used this a href:
<li>NEWS</li>
and i as u can see had to use the function to be able to href this part.
the problem is that this works fine in the index page since the function is in the index page, but when i click on the news on the menu bar on another page it just takes me to the index page and not to the part i want in the index page.
is there a way to make it work? any ideas?
note: i tried adding this function to the other pages but still having the same result, i think it is because the function should be called in the index page and it is useless in the other pages.
this are the tabs in the index page, the function closes the old one and open the one i click on, i want to go to one of the tabs in the index page from another page.
the tabs in the index page
i want to directly switch to the news tab when the user clicks news in the menu bar in other pages.
is there a way i can write a js that first load the index page than call the function?
You must create a file javascript like app.js or whatever, then include to script tag like this :
<script src="app.js"></script>
And inside app.js you can declare your function inside document ready.
$(document).ready(function(){
function switchTab() {
var p = $(this).parent('li');
var i = p.index();
var s = section.eq(i);
var c = s.find('*');
section.removeClass('active');
sectionContent.removeAttr('style');
s.addClass('active');
c.css({
transform: 'none',
opacity: 1
});
linkParent.removeClass('active');
p.addClass('active');
return false;
};
});
Related
I have some custom JavaScript on my SquareSpace site that manipulates Product titles beyond what you can do with SquareSpace's default style editor. It works when initially loading the page (https://www.manilva.co/catalogue-accessories/) but if you click on any of the categories on the left, the styling resets to the default.
I'm assuming the JavaScript is being overwritten by the SquareSpace style, but I can't figure out why. Perhaps I'm calling the function in the wrong place?
Any suggestions would be helpful.
Thanks!
Current code:
document.querySelectorAll(".ProductList-filter-list-item-link".forEach(i=>i.addEventListener("click", function()
{
var prodList = document.querySelectorAll("h1.ProductList-title");
for (i = 0, len = prodList.length; i < len; i++)
{
var text = prodList[i].innerText;
var index = text.indexOf('-');
var lower = text.substring(0, index);
var higher = text.substring(index + 2);
prodList[i].innerHTML = lower.bold() + "<br>" + higher;
});
The source of your problem is that your template has AJAX loading enabled. There are currently a couple generally-accepted ways to deal with this as a Squarespace developer:
Disable AJAX loading
Write your javascript functions in a
manner that will run on initial site load and whenever an "AJAX load" takes place.
Option 1 - Disable AJAX:
In the Home Menu, click Design, and then click Site Styles.
Scroll down to Site: Loading.
Uncheck Enable Ajax Loading.
Option 2 - Account for AJAX in Your JS
There are a number of ways that developers approach this, including the following, added via sitewide code injection:
<script>
window.Squarespace.onInitialize(Y, function() {
// do stuff
});
</script>
or
<script>
(function() {
// Establish a function that does stuff.
var myFunction = function() {
// Do stuff here.
};
// Initialize the fn on site load.
myFunction();
// myFunction2(); , etc...
// Reinit. the fn on each new AJAX-loaded page.
window.addEventListener("mercury:load", myFunction);
})();
</script>
or
<script>
(function() {
// Establish a function that does stuff.
var myFunction = function() {
// Do stuff here.
};
// Initialize the fn on site load.
myFunction();
// Reinit. the fn on each new AJAX-loaded page.
new MutationObserver(function() {
myFunction();
// myFunction2(); , etc...
}).observe(document.body, {attributes:true, attributeFilter:["id"]});
})();
</script>
Each of those works for most of the latest (at time of writing) templates most of the time. Each of those have their advantages and disadvantages, and contexts where they do not work as one might expect (for example, on the /cart/ page or other "system" pages). By adding your code within the context of one of the methods above, and ensuring that the code is of course working in the desired contexts and without its own bugs/issues, you will have your code run on initial site load and on each AJAX page load (with some exceptions, depending on the method you use).
Your problem is the page does not reload when clicking a button on the left, just some elements are removed, added and replaced. The changed elements will not be restyled. You will need to re-run your JavaScript after one of those buttons is clicked. Perhaps something like this:
document.querySelectorAll(
".ProductList-filter-list-item"
).forEach(
i=>i.addEventListener(
"click", ()=>console.log("hello")
)
)
where you replace console.log("hello") with whatever resets your formatting.
i want to open on every new site load another random tab with content.
i think i have to do it with some java script but it donĀ“t work.
You can look at the page here: LINK
Thanks for helping.
use this code :
var items = $('[data-toggle=pill]');
var i = parseInt(Math.floor(Math.random()*items.length));
$('#tabs a:eq(' + i + ') ').tab('show');
Select all available tabs (the code below uses jQuery which is available on your page)
Draw a random item
"Simulate" a click event
You can do it like this:
$(function () {
var items = $('[data-toggle=pill]');
var randomItem = items[Math.floor(Math.random()*items.length)];
randomItem.trigger('click');
});
I am wondering if it is possible to load infinityScroll response content in a reverse order.
The way it is now is that you have your index.html that on scroll loads the external page2.html then page3.htmland so on.. so when the user wants to add content he just duplicates the pageX.html file, changes the content and assigns the corresponding next number to the html file. Nice and simple right? But now the latest update, with the freshest content, is on the bottom of the page - not on top, as one most like would like it to be.
So my grand idea is that if the user updates the
<nav id="page-nav">
</nav>
to whatever the highest number of his external html file and then have infinityScroll show all the files in reverse order down to page1.html being the last one.
At the moment it works like this:
index.html - loads the following files in this order
page1.html (oldest)
page2.html
page3.html
page4.html (newest)
But I'd like it to be like this:
index.html - loads the following files in this order
page4.html (newest)
page3.html
page2.html
page1.html (oldest)
and whenever one adds a page it would "land on top of the stack"
This could be pretty useful for all of us right?
Anyone up for the challenge? :)
Cheers
actually 'infinityScroll' only reads external files from number 2 onwards, but just to present my idea clearer I use the sequence one-two-three etc..
I am guessing you want to do this so you get urls that always point to the same content (permalinks), which in some cases can be very handy. For example, you know that article foo is located on page 5, and can then link to it with page5.html#foo.
You can achieve this by passing a function to the path option. However, you will have to know the amount of pages before hand, since that is what we use to calculate the path.
// Amount of pages
var numPages = 45;
// Initialize infiniteScroll plugin
$(selector).infinitescroll({
path: function (page) {
// Concatenate the path to a page
var path = "page";
// Only add a page number if page is below or equal numPages
if (page <= numPages) {
path += (numPages - page);
}
// Return path as "page%d.html"
return path + ".html";
}
});
As stated in the documentation, the path option can either be an array of URL parts (e.g. ["/page/", "/"]) or a function that accepts the page number and returns a URL.
You could put the read more button at the top of the page, make an event listener:
$('.selector').infinitescroll({
loading: {
finished: function(){
//move your newly-added content to the top using $.prepend()
}
}
})
I have created a sample in which new element(which you need to add) will add on top in the container element.
HTML:
<div id="container" class="container">
</div>
CSS:
.container {
border: 1px solid #ccc;
height: 100px;
width:500px;
overflow:auto;
}
JAVASCRIPT/JQUERY
// page count
var count = 0;
var content_to_add_on_top = '<div>Page {count}</div>';
// call this function in every 2 seconds
setInterval(function () {
// code which you need to call when you wants to add an element to top in container
var content = content_to_add_on_top;
content = content.replace(/{count}/g, count);
var container = $('#container');
var child_elements = container.children();
if (child_elements.length === 0) {
// if child element does not exists
container.append(content);
} else {
// if child exists
var first_element = child_elements[0];
$(first_element).prepend(content);
}
// increment count
count++;
}, 2000);
JSFiddle Link
Hope it helps.
I'm using the Win8 Grid View Template to display infos from a news site. In the lower menu bar i have implemented a function wich shuts off the titles, so that only the pictures are still visible.
This function is in a "global.js" file which is included in the "default.html" so it's available everywhere and it looks like this:
//function to turn titles off and on
function titleToggle() {
var titles = document.getElementsByClassName("item-overlay");
for (var i = 0; i < titles.length; i++) {
if (Global.titlesAreOn) {
titles[i].style.display = "none";
}
else {
titles[i].style.display = "";
}
}
Global.titlesAreOn = !Global.titlesAreOn;
};
So when i call this function from the menu bar it works for the first items, but when i scroll the end of the groupedItems view (hubview) the titles are still there. When i then scroll back to the beginning the titles are there again too.
I'm also calling the titleToggle function from the ready() function of the "groupedItems.js" to check whether or not to display the titles depending on a global variable. When i do that (whenever i come back to the hubpage) it works all the way, just as expected.
ui.Pages.define("/pages/groupedItems/groupedItems.html", {
navigateToGroup: function (key) {
nav.navigate("/pages/groupDetail/groupDetail.html", { groupKey: key });
},
ready: function (element, options) {
appbar.winControl.disabled = false;
appbar.winControl.hideCommands(["fontSizeBt"]);
appbar.winControl.showCommands(["titleToggle"]);
if (Global.titlesAreOn == false) {
Global.titlesAreOn = true;
Global.titleToggle();
}
I made a short video to show the problem, because its kinda hard to explain --> http://youtu.be/h4FpQf1fRBY I hope you get the idea?
Why does it work when i call it from the ready() function?
Does anyone have an idea? Is it some kind of automatic item caching in order to have better performance? And how could this be solved?
Greets and thanks!
First, here is why this might be happening - WinJS is using single page navigation for the app experience. This means that when you navigate to a new page, actually you don't. Instead the content is removed from the page and the new content is loaded in the same page. It is possible that at the moment you press the button not all elements have been loaded in the DOM and therefore they cannot be manipulated by your function. This is why when you call it from the ready() function it works - all contents are loaded in the DOM. It is generally better to do things in the ready() function.
About the behavior when you slide back left and the items are again reloaded with titles - for some reason the listView items are reloading. Maybe you are using live data from the news site and they are refreshing with the listView control's template again. I cannot know, but it doesn't matter. Hiding the elements is not the best approach I think. It is better to have two templates - one with a title element and one without. The button click handler should get the listView controls(they have to be loaded) and change their templates.
ready: function (element, options) {
var button = document.getElementById('btn');
button.addEventListener("click", btnClickHandler);
}
And the handler:
function btnClickHandler(e) {
var listView = document.getElementById("listView").winControl;
var template2 = document.getElementById("template2");
listView.itemTemplate = template2;
};
I've got a problem I'm having trying to append a bannercode to the end of an URL. The customer journey is as follows:
Person receives an email which contains a link to a site (SITE1), the URL will contain a banner code e.g. www.site1.com?banner=helloworld
Once the person is on this site, there are 2 buttons which take the customer to a second site:
Button 1 goes to https://www.site2.com/page1
Button 2 goes to same URL/page2
$(document).ready( function () {
var banner = String($.query.get('banner'));
if(banner){
href = $('a[href^="https://"]').attr("href") + "?banner=" + banner;
$('a[href^="https://"]').attr("href", href);
}
});
Basically what happens is, the piece of code I have makes both buttons go to the same URL for example button 1. How can I get the script to not change the URL for all buttons? Thanks in advance.
Do I understand you right: you want to add banner part for every link, but keep the original part unchanged?
$(document).ready(function(){
var banner=String($.query.get('banner'));
if(banner){
$('a[href^="https://"]').attr('href',function(){
return this+'?banner='+banner;
});
}
});
or in shorter:
$(document).ready(function(){
(banner=$.query.get('banner'))?$('[href^=https]').attr('href',function(){
return this+'?banner='+banner}):null;
})