Javascript
function openPage(pageName, elmnt) {
// Hide all elements with class="tabcontent" by default */
var i, tabcontent, tablinks;
tabcontent = document.getElementsByClassName("tabcontent");
for (i = 0; i < tabcontent.length; i++) {
tabcontent[i].style.display = "none";
}
// Show the specific tab content
document.getElementById(pageName).style.display = "block";
}
document
list = document.querySelectorAll(".myTextInputID")
list[1].addEventListener("keyup", function (event) {
if (event.keyCode === 13) {
event.preventDefault();
var input = document.getElementsByClassName("myTextInputID")[0]
.value;
if (input.includes("https://www.amazon.co.uk/")) {
document.getElementsByClassName("containFORM")[0]
.insertAdjacentElement("beforeend", itemcont);
document.getElementById("prodcont")
.insertAdjacentElement("afterbegin", imgcont);
document.getElementsByClassName("containFORM")[0]
.style.backgroundColor = "white"
} else {
var URLerror = document.createElement("p");
URLerror.classList.add("error");
var urlerror = document.createTextNode("This is not an amazon url, please input an amazon url and press enter again.");
URLerror.appendChild(urlerror);
var cont = document.getElementsByClassName("myForm")[0];
cont.insertAdjacentElement("afterend", URLerror);
setTimeout(function() {
URLerror.remove();
}, 2000);
}
}
});
function newTab() {
var allTabs = document.getElementById("navigation2");
var tabList = document.createElement("li");
var error = document.createElement("p");
var eNode = document.createTextNode("You cant track this many products");
var button1 = document.getElementById("button1");
var tabButton = document.createElement("button");
tabButton.setAttribute("onclick", "openPage('1', this, 'red')")
error.classList.add("error");
tabList.classList.add("tabli");
tabButton.classList.add("tabs");
if (button1.offsetWidth < 190) {
error.appendChild(eNode);
document.getElementById("tabcon")
.insertAdjacentElement("afterend", error);
setTimeout(function() {
error.remove();
}, 2000);
} else {
tabList.appendChild(tabButton);
allTabs.insertAdjacentElement("beforebegin", tabList);
var newt = ("window.location.href=")+("\'")+("#")+("newtab")+("\'");
var newtab = document.createElement("div")
newtab.id="#newtab";
newtab.className="containFORM";
// true means clone all childNodes and all event handlers
document.getElementById("0").insertAdjacentElement("afterend", clone)
clone.id = "1";
}
}
When you press the new tab button it makes a new tab and creates a clone of a stored element, however with the class selector I can only put a number (0,1) but I need it so its some sort of variable(x), x being the number of the current tab. So when you click on one tab set x to that and then all logic will be performed on each tab, I can't think of a way to do this without copying what I've done multiple times and just changing the number myself, which doesn't feel very efficient.
I have found this piece of code in JQuery that might help you.
var activeTab = $(".tab-content").find(".active");
console.log(activeTab.context.URL);
If you try it while inspect this very page, you can check that the result is the URL of this page:
https://stackoverflow.com/questions/65886250/how-to-tell-javascript-what-tab-is-active
Related
Here is the JavaScript code but I don't think it'll help much because it doesn't have anything that would relate to page reloading since I haven't done it before. every time I reload the page none of the items in a To-DO list save and disappear after it's reloaded.
JS:
// Create a "close" button and append it to each list item
var myNodelist = document.getElementsByTagName("LI");
var i;
for (i = 0; i < myNodelist.length; i++) {
var span = document.createElement("SPAN");
var txt = document.createTextNode("\u00D7");
span.className = "close";
span.appendChild(txt);
myNodelist[i].appendChild(span);
}
// Click on a close button to hide the current list item
var close = document.getElementsByClassName("close");
var i;
for (i = 0; i < close.length; i++) {
close[i].onclick = function() {
var div = this.parentElement;
div.style.display = "none";
}
}
// Add a "checked" symbol when clicking on a list item
var list = document.querySelector('ul');
list.addEventListener('click', function(ev) {
if (ev.target.tagName === 'LI') {
ev.target.classList.toggle('checked');
}
}, false);
// Create a new list item when clicking on the "Add" button
function newElement() {
var li = document.createElement("li");
var inputValue = document.getElementById("myInput").value;
var t = document.createTextNode(inputValue);
li.appendChild(t);
if (inputValue === '') {
alert("You must write something!");
} else {
document.getElementById("myUL").appendChild(li);
}
document.getElementById("myInput").value = "";
var span = document.createElement("SPAN");
var txt = document.createTextNode("\u00D7");
span.className = "close";
span.appendChild(txt);
li.appendChild(span);
for (i = 0; i < close.length; i++) {
close[i].onclick = function() {
var div = this.parentElement;
div.style.display = "none";
}
}
}
2 modern and easy to use solution are the following:
Web Storage API. It provides a mechanism for storing and retrieving smaller, data items consisting of a name and a corresponding value. This is useful when you just need to store some simple data, like the user's name, whether they are logged in, what color to use for the background of the screen, etc.
IndexedDB API. It provides the browser with a complete database system for storing complex data. This can be used for things from complete sets of customer records to even complex data types like audio or video files.
Check examples on this page: https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Client-side_web_APIs/Client-side_storage
Will edit this answer once I have a PC at reach to include examples.
EDIT: Here is an example https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Client-side_web_APIs/Client-side_storage#storing_simple_data_%E2%80%94_web_storage
I have the following script, from my previous question. I tried running it but it won't work. There isn't any console message as well. It does conflict with something in console called lstr.js (I think it is chrome related), the code works fine in jsfiddle but not on my machine.
var links = document.getElementsByClassName('link'), // add a class to the links and get them all
contentDivs = document.getElementsByClassName('content'); // same with the content blocks
for (i = 0; i < links.length; i++) { // loop through the links to add the event listeners
var link = links[i];
// add event listener
link.addEventListener('click', function(event) {
// reset color and hide content:
for (a = 0; a < links.length; a++) {
// number of links should match number of content
links[a].style.backgroundColor = 'magenta';
contentDivs[a].style.display = 'none';
}
// set colour of clicked
event.target.style.backgroundColor = 'grey';
// show clicked content
document.getElementById(event.target.getAttribute("href").substring(1)).style.display = 'block';
})
}
Wrap that in a function and then do
document.addEventListener('DOMContentLoaded', function() {
nameOfYourFunction();
});
So in the end, your could would look like
function attachEvents() {
var links = document.getElementsByClassName('link'); // add a class to the links and get them all
var contentDivs = document.getElementsByClassName('content'); // same with the content blocks
for (i = 0; i < links.length; i++) { // loop through the links to add the event listeners
var link = links[i];
// add event listener
link.addEventListener('click', function(event) {
// reset color and hide content:
for (a = 0; a < links.length; a++) {
// number of links should match number of content
links[a].style.backgroundColor = 'magenta';
contentDivs[a].style.display = 'none';
}
// set colour of clicked
event.target.style.backgroundColor = 'grey';
// show clicked content
document.getElementById(event.target.getAttribute("href").substring(1)).style.display = 'block';
});
}
}
document.addEventListener('DOMContentLoaded', function() {
attachEvents();
}
The code is OK except you ought to check if links.length === contentDivs.length
I currently have it so my titles slide in when the link is clicked.
How do I make it so that (when the link is clicked) the current title will slide out before the new one slides in?
This is the clicked event I have been using. It might be all wonky, I have been adding different things to it to try and get it to work.
// list of sections. the first section contains only the h1.
var sections = document.querySelectorAll("section");
function hideSections() {
for (var i = 0; i < sections.length; i++) {
sections[i].className = "hidden";
}
}
// list of links in the nav.
var links = document.querySelector("nav").querySelectorAll("a");
// add listeners to those links
for (var i = 0; i < links.length; i++) {
links[i].addEventListener("click", clicked);
}
function clicked(event) {
var target = document.querySelector('h2');
target.className = "slideout";
event.preventDefault();
hideSections();
var current = event.target.hash;
// "show" appropriate selection, based on id from link
document.querySelector(current).className = "";
// modify URL to reflect current location
location.hash = current;
target.addEventListener("animationend", newfile);
function newfile() {
target.removeEventListener("animationend", newfile);
}
target.addEventListener("animationstart", newfile);
}
// when page loads...
hideSections();
if (location.hash == "") {
sections[0].className = "";
} else {
document.querySelector(location.hash).className = "";
}
https://jsfiddle.net/yk7w2zt2/
Here is my full code.
You need you delay showing the next section until after the h2 has slid off the screen.
See JSFiddle using setTimeout():
https://jsfiddle.net/w9uypaae/
Here is my html with the JS within. The function "toggleMessage()" is the function I am using to hide and show messages when clicked. The problems I am running into include:
Messages showing by default, when they should hide by default (until clicked).
When clicked, all messages show at once - I want only the messages clicked on to show.
The new messages that populate the page every 3 seconds are not affected by the click event - I want them to be effected.
function newMessage() {
// Loop goes through emails and creats divs for subject, date, sender, and body
var i = 0;
while (i < window.geemails.length) {
//email container
var div = document.createElement("div");
//date
var dateField = document.createElement("h1");
dateField.className = "date";
dateField.innerHTML = window.geemails[i].date;
div.appendChild(dateField);
//subject
var subjectField = document.createElement("h1");
subjectField.className = "subject";
subjectField.innerHTML = window.geemails[i].subject;
div.appendChild(subjectField);
//sender
var senderField = document.createElement("h1");
senderField.className = "sender";
senderField.innerHTML = window.geemails[i].sender;
div.appendChild(senderField);
//body
var bodyField = document.createElement("p");
bodyField.className = "body";
bodyField.innerHTML = window.geemails[i].body;
div.appendChild(bodyField);
//Separate message content into containers
document.getElementById("main").appendChild(div);
//inbox counter
document.getElementById('counter').innerHTML = "You have " + document.getElementsByClassName("date").length + " messages";
window.geemails.shift();
}
}
newMessage();
//interval for loading new messages
function addNewMessage() {
setInterval(function() {
window.geemails.push(getNewMessage());
newMessage();
}, 3000);
}
addNewMessage();
//hiding and showing body message upon click
var messageBox = document.getElementsByClassName("subject");
for (var i = 0; i < messageBox.length; i++) {
messageBox[i].addEventListener("click", toggleMessage);
}
function toggleMessage() {
var showMessage = document.getElementsByClassName('body');
for (var i = 0; i < showMessage.length; i++) {
if (showMessage[i].style.display === 'none') {
showMessage[i].style.display = "block";
} else {
showMessage[i].style.display = "none";
}
}
}
You need a class for your messages and possiblt for their bodies.
Suppose you have a message div with a message body like this
<div class="message">
<div class="message-header">
</div>
<div class="message-body" style="display:none;">
</div>
</div>
if you want the body to be hidden by default use css display:none
then in your javascript do
$('.message').click(function(){
$(this).children('.message-body').show();
});
I have a javasccript function that shows or hides "spans" when I click an input to show hints when a user fills out forms:
function prepareInputsForHints() {
var inputs = document.getElementsByTagName("input");
for (var i=0; i<inputs.length; i++){
// test to see if the hint span exists first
if (inputs[i].parentNode.getElementsByTagName("span")[0]) {
// the span exists! on focus, show the hint
inputs[i].onfocus = function () {
this.parentNode.getElementsByTagName("span")[0].style.display = "inline";
}
// when the cursor moves away from the field, hide the hint
inputs[i].onblur = function () {
this.parentNode.getElementsByTagName("span")[0].style.display = "none";
}
}
}
}
My problem is that when I try to add a link to the hints text, the user cannot click it because it registers first with the onblur event and the hint dissapears, so I would like to know how to modify this function so that it does not hide when I click the hint.
You can use a boolean var to test if the user is with mouse over your hint, then if onblur and not mouseOver you hide your hint.
Something like this inside your loop:
var inputs = document.getElementsByTagName("input");
for (var i=0; i<inputs.length; i++){
(function(i) {
// Let the code cleaner :)
var span = inputs[i].nextElementSibling;
span.onmouseover = function() { this.isOver = true; }
span.onmouseout = function() { this.isOver = false; if(!inputs[i].isFocus) inputs[i].onblur(); }
// the span exists! on focus, show the hint
inputs[i].onfocus = function () {
this.isFocus = true;
span.style.display = "inline";
}
// when the cursor moves away from the field, hide the hint
inputs[i].onblur = function () {
this.isFocus = false;
if(!span.isOver) span.style.display = "none";
}
})(i);
}
I put a self executing function just to keep the var i scope, you don't have troubles onmouseout function.
EDIT: Updated the example
Your code for get the next span will not work, so I changed to nextElementSibling, because the example you put in the jsfiddler.
This is the new working code:
$(function(prepareInputsForHints) {
var inputs = document.getElementsByTagName("input");
for (var i=0; i<inputs.length; i++){
(function(i) {
// Let the code cleane
var span = inputs[i].nextElementSibling;
if(span instanceof HTMLSpanElement) {
if(span.className == "hint") {
span.onmouseover = function() { this.isOver = true; }
span.onmouseout = function() { this.isOver = false; if(!inputs[i].isFocus) inputs[i].onblur(); }
// the span exists! on focus, show the hint
inputs[i].onfocus = function () {
this.isFocus = true;
span.style.display = "inline";
}
// when the cursor moves away from the field, hide the hint
inputs[i].onblur = function () {
this.isFocus = false;
if(!span.isOver) span.style.display = "none";
}
}
}
})(i);
}
});