Objective
I'm looking at the .length of each of these positions:
.player--forward, .player--defenseman and .player--goalie to see how many of these players have the class is-selected
A player is selected when a user clicks the btn--add button to add that player to their team.
Once a position reaches the maximum number that can be chosen: two
forwards (pickedF === 2) or three defensemen (pickedD === 3) or
one goalie (pickedG === 1), I'm looking to make it so any players that have do not have a class is-selected unable to be clicked on with "pointer-events:none"
Update #1
Right now, it appears to be counting correctly, but it does not change "pointer-events" to none until after btn-add is clicked because of the nesting of the if-statements and I think that some parts are in the btn-add click function when they don't need to be
scripts.js
function countPlayers(){
$(".player").click(function(){
// Select the current player
var player = $(this);
// Count number of players of each position that have been clicked
var pickedF = $(".player--forward.is-selected").length;
var pickedD = $(".player--defenseman.is-selected").length;
var pickedG = $(".player--goalie.is-selected").length;
// Grab the name of the player last clicked
playerName = player.find(".player__name").text();
// Literally magic.
$(".btn--add").unbind("click");
$(".btn--add").click(function(){
// Ensures names don't match
var spanText = $(".player__pick").eq(0).text();
// Changes the opacity of a picked player to 0.5
player.addClass("is-selected");
if (player.hasClass("player--forward")) {
if (spanText !== playerName) {
$(".player__pick--forward.is-empty").eq(0).html(playerName);
$(".player__pick--forward.is-empty").eq(0).removeClass("is-empty");
if (pickedF < 2) {
pickedF++;
} else if (pickedF === 2) {
$(".player--forward").not(":has(.is-selected)").css("pointer-events", "none");
console.log("Locked forwards");
} else {
$(".player--forward").css("pointer-events", "auto");
}
}
}
if (player.hasClass("player--defenseman")) {
if (spanText !== playerName) {
$(".player__pick--defenseman.is-empty").eq(0).html(playerName);
$(".player__pick--defenseman.is-empty").eq(0).removeClass("is-empty");
// Issue here
if (pickedD < 3) {
pickedD++;
} else if (pickedD === 3) {
$(".player--defenseman").not(":has(.is-selected)").css("pointer-events", "none");
console.log("Locked defensemen");
} else {
$(".player--defenseman").css("pointer-events", "auto");
}
}
}
if (player.hasClass("player--goalie")) {
if (spanText !== playerName) {
$(".player__pick--goalie.is-empty").eq(0).html(playerName);
$(".player__pick--goalie.is-empty").eq(0).removeClass("is-empty");
// Issue here
if (pickedD < 1){
pickedG++;
} else if (pickedG === 1) {
$(".player--goalie").not(":has(.is-selected)").css("pointer-events", "none");
console.log("Locked goalie");
} else {
$(".player--goalie").css("pointer-events", "auto");
}
}
}
console.log(pickedF, pickedD, pickedG);
});
$(".btn--remove").click(function(){
player.removeClass("is-selected");
if (player.hasClass("player--forward")) {
$(".player__pick--forward").eq(0).html("Pick a Forward");
$(".player__pick--forward").eq(0).addClass("is-empty");
}
if (player.hasClass("player--defenseman")) {
$(".player__pick--defenseman").eq(0).html("Pick a Defenseman");
$(".player__pick--defenseman").eq(0).addClass("is-empty");
}
if (player.hasClass("player--goalie")) {
$(".player__pick--goalie").eq(0).html("Pick a Goalie");
$(".player__pick--goalie").eq(0).addClass("is-empty");
}
console.log(pickedF, pickedD, pickedG);
});
});
}
index.html
<div class="popup__text">
<p class="popup__position">tk-position</p>
<p class="popup__name">tk-name</p>
<p class="popup__years">tk-years</p>
<p class="popup__description">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Sequi ad dicta sunt unde, sed quae nihil inventore voluptates nulla voluptate laudantium nesciunt quo, aspernatur deleniti quod harum, nisi error doloribus.</p>
<div class="popup__stats">
<p>tk-stats</p>
</div>
<div class="buttons">
<button class="btn--add">Add to team</button>
<button class="btn--remove">Remove from team</button>
</div>
</div>
<div class="player player--bobplager player--defenseman" data-id="11">
<div class="player__info animated">
<p class="player__name">Bob Plager</p>
<p class="player__position">Defenseman</p>
</div>
</div>
<div class="player player--shanahan player--forward" data-id="12">
<div class="player__info animated">
<p class="player__name">Brendan Shanahan</p>
<p class="player__position">Forward</p>
</div>
</div>
<div class="player player--hull player--forward" data-id="13">
<div class="player__info animated">
<p class="player__name">Brett Hull</p>
<p class="player__position ">Forward</p>
</div>
</div>
<div class="player player--elliott player--goalie" data-id="14">
<div class="player__info animated">
<p class="player__name">Brian Elliott</p>
<p class="player__position ">Goalie</p>
</div>
</div>
function countPlayers(){
$(".player").click(function(){
// Select the current player
var player = $(this);
// Count number of players of each position that have been clicked
var pickedF = $(".player--forward.is-selected").length;
var pickedD = $(".player--defenseman.is-selected").length;
var pickedG = $(".player--goalie.is-selected").length;
// Grab the name of the player last clicked
playerName = player.find(".player__name").text();
// Literally magic.
$(".btn--add").unbind("click");
$(".btn--add").click(function(){
// Ensures names don't match
var spanText = $(".player__pick").eq(0).text();
// Changes the opacity of a picked player to 0.5
player.addClass("is-selected");
if (player.hasClass("player--forward")) {
if (spanText !== playerName) {
$(".player__pick--forward.is-empty").eq(0).html(playerName);
$(".player__pick--forward.is-empty").eq(0).removeClass("is-empty");
if (pickedF < 2) {
pickedF++;
}
if (pickedF === 2) {
$(".player--forward").not(":has(.is-selected)").css("pointer-events", "none");
console.log("Locked forwards");
} else {
$(".player--forward").css("pointer-events", "auto");
}
}
}
if (player.hasClass("player--defenseman")) {
if (spanText !== playerName) {
$(".player__pick--defenseman.is-empty").eq(0).html(playerName);
$(".player__pick--defenseman.is-empty").eq(0).removeClass("is-empty");
if (pickedD < 3) {
pickedD++;
}
if (pickedD === 3) {
$(".player--defenseman").not(":has(.is-selected)").css("pointer-events", "none");
console.log("Locked defensemen");
} else {
$(".player--defenseman").css("pointer-events", "auto");
}
}
}
if (player.hasClass("player--goalie")) {
if (spanText !== playerName) {
$(".player__pick--goalie.is-empty").eq(0).html(playerName);
$(".player__pick--goalie.is-empty").eq(0).removeClass("is-empty");
if (pickedG < 1){
pickedG++;
}
if (pickedG === 1) {
$(".player--goalie").not(":has(.is-selected)").css("pointer-events", "none");
console.log("Locked goalie");
} else {
$(".player--goalie").css("pointer-events", "auto");
}
}
}
console.log(pickedF, pickedD, pickedG);
});
$(".btn--remove").click(function(){
player.removeClass("is-selected");
if (player.hasClass("player--forward")) {
$(".player__pick--forward").eq(0).html("Pick a Forward");
$(".player__pick--forward").eq(0).addClass("is-empty");
}
if (player.hasClass("player--defenseman")) {
$(".player__pick--defenseman").eq(0).html("Pick a Defenseman");
$(".player__pick--defenseman").eq(0).addClass("is-empty");
}
if (player.hasClass("player--goalie")) {
$(".player__pick--goalie").eq(0).html("Pick a Goalie");
$(".player__pick--goalie").eq(0).addClass("is-empty");
}
console.log(pickedF, pickedD, pickedG);
});
});
}
Related
I tried to build a filter for some posts. When a year is selected the other year should be removed from the page. But only the half of the unselected year posts gets deleted. What am I doing wrong?
var filter2020 = document.getElementById('filter20');
var filter2021 = document.getElementById('filter21');
var posts = document.getElementsByClassName('article');
if (filter2020) {
for (item of posts) {
if (item.dataset.year == "Y2020") {
item.remove();
} else {
console.log("no")
}
}
} else if (filter2021) {
for (item of posts) {
if (item.dataset.year == "Y2021") {
item.remove();
} else {
console.log("no")
}
}
} else {
}
<div class="row filtered-news">
<div class="article col-lg-4" data-year="Y2021"> </div>
<div class="article col-lg-4" data-year="Y2020"> </div>
</div>
I'm working on a Drupal website and I'm working on revising a component. I would like the first accordion menu item open by default, I have been kind of stuck on this for a little while.
I can not add to html because content is dynamic so has to be done with JS. Here is the script so far.
Any help would be great.
Bellow is the JS and HTML
jQuery(document).ready(() => {
const buttons = document.querySelectorAll('[data-accordion-button]');
for (let i = 0; i < buttons.length; i++) {
buttons[i].addEventListener('click', (e) => {
const toggle = (e.target.getAttribute('aria-expanded') === 'true') ? false : true;
const root = buttons[i].closest('[data-accordion-container]');
const panel = buttons[i].closest('[data-accordion-panel]');
const panelSiblings = getSiblings(panel);
const firstChild = getFirstChild();
const window = panel.querySelector('[data-accordion-window]');
const content = panel.querySelector('[data-accordion-content]');
buttons[i].setAttribute('aria-expanded', toggle);
buttons[i].setAttribute('tabindex', '0');
toggle ?
window.setAttribute('style', `height: ${content.offsetHeight}px; visibility: visible;`) :
window.setAttribute('style', 'height: 0; visibility: hidden;');
if (root.getAttribute('data-accordion-config-single') === 'true') {
panelSiblings.forEach((sibling) => {
const siblingButton = sibling.querySelector('[data-accordion-button]');
const siblingWindow = sibling.querySelector('[data-accordion-window]');
siblingButton.setAttribute('aria-expanded', 'false');
siblingWindow.setAttribute('style', 'height: 0; visibility: hidden;');
});
}
});
// Arrow key controls
buttons[i].addEventListener('keydown', (e) => {
if (e.keyCode === 38) {
if (i === 0) {
buttons[buttons.length - 1].focus();
} else {
buttons[i - 1].focus();
}
}
if (e.keyCode === 40) {
if (i === buttons.length - 1) {
buttons[0].focus();
} else {
buttons[i + 1].focus();
}
}
});
}
function getSiblings(element) {
let siblings = [];
let sibling = element.parentNode.firstChild;
while (sibling) {
if (sibling.nodeType === 1 && sibling !== element) {
siblings.push(sibling);
}
sibling = sibling.nextSibling
}
return siblings;
};
});
```
<div class="accordion" data-accordion-container data-accordion-config-single="false">
<article class="accordion__panel-container" data-accordion-panel>
<h3 class="accordion__header">
<button class="h4 accordion__button" data-accordion-button aria-expanded="false" tabindex="0">
Taxation & Regulation in a Token Economy
</button>
</h3>
<div class="accordion__window" data-accordion-window>
<div class="accordion__content wysiwyg" data-accordion-content>
<p>
This text is for placement only. Vestibulum id ligula porta felis euismod semper.
</p>
</div>
</div>
</article>
<article class="accordion__panel-container" data-accordion-panel>
<h3 class="accordion__header">
<button class="h4 accordion__button" data-accordion-button aria-expanded="false">
Regulatory Content Aggregation
</button>
</h3>
<div class="accordion__window" data-accordion-window>
<div class="accordion__content wysiwyg" data-accordion-content>
<p>We demonstrate our commitment to Total Rewards through:</p>
</div>
</div>
</article>
</div>
This question already has answers here:
JavaScript TicTacToe if... Winner detection
(7 answers)
Closed 2 years ago.
I am tryin to implement a tic tac to game using jquery, and here is my code:
$(document).ready(function() {
let turn = 1;
$(".smallbox").click(function() {
if (turn == 1) {
$(this).text("X");
$(this).addClass("X");
turn = 2;
} else {
$(this).text("O");
$(this).addClass("O");
turn = 1;
}
$("#tune").text(turn);
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="box" id="mainbox">
<!-- creat 9 small box -->
<div class="smallbox" id="square1"></div>
<div class="smallbox" id="square2"></div>
<div class="smallbox" id="square3"></div>
<div class="smallbox" id="square4"></div>
<div class="smallbox" id="square5"></div>
<div class="smallbox" id="square6"></div>
<div class="smallbox" id="square7"></div>
<div class="smallbox" id="square8"></div>
<div class="smallbox" id="square9"></div>
</div>
however I have difficulty detecting the winner, due to X and Y. Since my code is providing X information but not Y, how can I improve my code in this regard?
$(document).ready(function() {
let gameArray = [];
let turn = 1;
let gameOver = false;
$("#turn").text(turn === 1 ? 'X' : 'O');
$(".smallbox").click(function() {
let squereIndex = $(this).attr('id').replace('square', '') - 1;
if (turn == 1 && !gameOver && gameArray[squereIndex] === undefined) {
$(this).text("X");
$(this).addClass("X");
turn = 2;
gameArray[squereIndex] = 1;
} else if (!gameOver && gameArray[squereIndex] === undefined) {
$(this).text("O");
$(this).addClass("O");
turn = 1;
gameArray[squereIndex] = -1;
}
checkWinner();
$("#turn").text(turn === 1 ? 'X' : 'O')
});
function checkWinner() {
let result;
//check Rows
for (let i = 0; i <= 6; i += 3) {
result = gameArray[i] + (gameArray[i + 1]) + (gameArray[i + 2]);
if (result === 3) {
$("#winner").text('X win');
gameOver = true;
}
if (result === -3) {
$("#winner").text('O win');
gameOver = true;
}
}
//check Columns
for (let i = 0; i <= 3; i++) {
result = gameArray[i] + (gameArray[i + 3]) + (gameArray[i + 6]);
if (result === 3) {
$("#winner").text('X win');
gameOver = true;
}
if (result === -3) {
$("#winner").text('O win');
gameOver = true;
}
}
//check Diagonal
result = gameArray[0] + (gameArray[4]) + (gameArray[8]);
if (result === 3) {
$("#winner").text('X win');
gameOver = true;
}
if (result === -3) {
$("#winner").text('O win');
gameOver = true;
}
result = gameArray[2] + (gameArray[4]) + (gameArray[6]);
if (result === 3) {
$("#winner").text('X win');
gameOver = true;
}
if (result === -3) {
$("#winner").text('O win');
gameOver = true;
}
}
});
.smallbox {
width: 50px;
border: 1px solid black;
height: 35px;
margin: 2px;
text-align: center;
padding-top: 15px;
}
.row-container {
display: flex;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div class="box" id="mainbox">
Turn: <span id='turn'></span>
<!-- creat 9 small box -->
<div class='row-container'>
<div class="smallbox" id="square1"></div>
<div class="smallbox" id="square2"></div>
<div class="smallbox" id="square3"></div>
</div>
<div class='row-container'>
<div class="smallbox" id="square4"></div>
<div class="smallbox" id="square5"></div>
<div class="smallbox" id="square6"></div>
</div>
<div class='row-container'>
<div class="smallbox" id="square7"></div>
<div class="smallbox" id="square8"></div>
<div class="smallbox" id="square9"></div>
</div>
<span id='winner'></span>
</div>
How can I stop this carousel from bubbling the animation? If you click right faster, it will start to mix up things. I need to stop the event handler function if the animation is running, inside that timeOut, the handlers should go offline.
Please see snippet below:
var Carousel = function(element, options) {
this.carousel = document.querySelector(element);
this.slides = Array.prototype.slice.call(this.carousel.querySelectorAll('.item'), null);
this.prev = this.carousel.querySelector("[data-slide='prev']");
this.next = this.carousel.querySelector("[data-slide='next']");
this.indicators = this.carousel.querySelectorAll(".carousel-indicators li");
this.interval = options && options.interval ? options.interval : 5000;
this.duration = 600; // bootstrap carousel default transition duration
this.paused = null;
this.direction = null;
this.index = 0;
this.total = this.slides.length;
this.init();
};
Carousel.prototype = {
init: function() {
this.cycle();
this.actions();
},
_slideTo: function(next, e) {
var self = this;
//determine type
var active = self._getActiveIndex(); // the current active
var direction = self.direction;
var type = direction === 'left' ? 'next' : 'prev';
if (!this.slides[next].classList.contains(type)) {
//e.preventDefault();
//e.defaultPrevented = false;
this.slides[next].classList.add(type);
this.slides[next].offsetWidth;
this.slides[active].classList.add(direction);
this.slides[next].classList.add(direction);
setTimeout(function() {
console.log('inside timeout prevented? ' + e.defaultPrevented);
self.slides[next].classList.remove(type, direction);
self.slides[next].classList.add('active');
self.slides[active].classList.remove('active', direction);
self._curentPage(self.indicators[next]);
//e.defaultPrevented = false;
}, self.duration + 200);
}
},
_getActiveIndex: function() {
return this._getItemIndex('.item.active')
},
_getItemIndex: function(itm) {
return this.slides.indexOf(this.carousel.querySelector(itm))
},
_curentPage: function(p) {
for (var i = 0; i < this.indicators.length; ++i) {
var a = this.indicators[i];
a.className = "";
}
p.className = "active";
},
cycle: function() {
var self = this;
//deleted some shit
},
actions: function() {
var self = this;
self.next.addEventListener("click", function(e) {
e.preventDefault();
self.index++;
self.direction = 'left'; //set direction first
if (self.index == self.total - 1) {
self.index = self.total - 1;
} else if (self.index == self.total) {
self.index = 0
}
self._slideTo(self.index, e);
}, false);
self.prev.addEventListener("click", function(e) {
e.preventDefault();
self.index--;
self.direction = 'right'; //set direction first
if (self.index == 0) {
self.index = 0;
} else if (self.index < 0) {
self.index = self.total - 1
}
self._slideTo(self.index, e);
}, false);
for (var i = 0; i < self.indicators.length; ++i) {
var a = self.indicators[i];
a.addEventListener("click", function(e) {
e.preventDefault();
var n = parseInt(this.getAttribute("data-slide-to"), 10);
self.index = n;
if (self.index == 0) {
self.index = 0;
}
if (self.index > 0) {}
if (self.index == self.total - 1) {
self.index = self.total - 1;
} else {}
//determine direction first
var active = self._getActiveIndex(); // the current active
if ((active < self.index) || (active === self.total - 1 && self.index === 0)) {
self.direction = 'left'; // next
} else if ((active > self.index) || (active === 0 && self.index === self.total - 1)) {
self.direction = 'right'; // prev
}
self._slideTo(self.index, e);
}, false);
}
window.addEventListener('keydown', function(e) {
if (/input|textarea/i.test(e.target.tagName)) return;
switch (e.which) {
case 39:
self.index++;
self.direction = 'left';
if (self.index == self.total - 1) {
self.index = self.total - 1;
} else
if (self.index == self.total) {
self.index = 0
}
break;
case 37:
self.index--;
self.direction = 'right';
if (self.index == 0) {
self.index = 0;
} else
if (self.index < 0) {
self.index = self.total - 1
}
break;
default:
return;
}
// e.preventDefault();
self._slideTo(self.index, e);
}, false)
}
}
var slider = new Carousel("#myCarousel1");
#myCarousel1 {
height: 300px;
max-width: 100%
}
.item {
height: 300px;
background: url(http://placehold.it/100x100/069/069.png) repeat center center;
background-size: cover
}
<link href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css" rel="stylesheet" />
<div id="myCarousel1" class="carousel slide" data-ride="carousel">
<ol class="carousel-indicators">
<li data-target="#myCarousel1" data-slide-to="0" class="active"></li>
<li data-target="#myCarousel1" data-slide-to="1"></li>
<li data-target="#myCarousel1" data-slide-to="2"></li>
</ol>
<div class="carousel-inner">
<div class="item active">
<div class="container">
<div class="carousel-caption">
<h1>Example headline.</h1>
<p>Note: If you're viewing this page via a <code>file://</code> URL, the "next" and "previous" Glyphicon buttons on the left and right might not load/display properly due to web browser security rules.</p>
<p><a class="btn btn-lg btn-primary" href="#" role="button">Sign up today</a>
</p>
</div>
</div>
</div>
<div class="item">
<div class="container">
<div class="carousel-caption">
<h1>Another example headline.</h1>
<p>Cras justo odio, dapibus ac facilisis in, egestas eget quam. Donec id elit non mi porta gravida at eget metus. Nullam id dolor id nibh ultricies vehicula ut id elit.</p>
<p><a class="btn btn-lg btn-primary" href="#" role="button">Learn more</a>
</p>
</div>
</div>
</div>
<div class="item">
<div class="container">
<div class="carousel-caption">
<h1>One more for good measure.</h1>
<p>Cras justo odio, dapibus ac facilisis in, egestas eget quam. Donec id elit non mi porta gravida at eget metus. Nullam id dolor id nibh ultricies vehicula ut id elit.</p>
<p><a class="btn btn-lg btn-primary" href="#" role="button">Browse gallery</a>
</p>
</div>
</div>
</div>
</div>
<span class="glyphicon glyphicon-chevron-left"></span>
<span class="glyphicon glyphicon-chevron-right"></span>
</div>
Perhaps checking the time interval between the clicks and returning false from the function that slides the carousel can solve this problem:
var oldTs = 0;
element.removeEventListener("click", slideClickHandler);
function slideClickHandler(e) {
var ts = e.timeStamp;
if ((oldTs !== 0) && (ts - oldTs < 500)) return false; //If time between clicks is 500 miliseconds and its not the first click cancel slide
else {
oldTs = ts; //Update timestamp buffer
slide(); //Do the sliding stuff
}
}
element.addEventListener('click', slideClickHandler);
Edit: You should put this code in a function and refresh the click handler after every slide for it to work.
I am trying to animate a show / div using javascript. The code works fine but i want it to open and close at 500 speed.
The code i have is this:
<a id="show-map" href="javascript:toggle();">Show Map</a>
<div id="top-map" style="display: none">
<h2>Hello</h2>
</div>
<script language="javascript">
function toggle() {
var ele = document.getElementById("top-map"),
text = document.getElementById("show-map");
if(ele.style.display == "block") {
ele.style.display = "none";
text.innerHTML = "Show Map";
} else {
ele.style.display = "block";
text.innerHTML = "Hide Map";
}
}
</script>
Based on an example posted by keypaul here I've adapted your code and shortened the example a bit for you:
<a id="show-map" href="javascript:toggle();">Show Map</a>
<div id="top-map" style="display: none">
<h2>Hello</h2>
</div>
<script language="javascript">
var ele = document.getElementById("top-map"),
text = document.getElementById("show-map");
function setTime(state) {
if (state === "out") {
for (var i = 1; i <= 100; i++) {
setTimeout("fadeOut(" + (100 - i) + ")", i * 5);
}
} else {
for (var i = 1; i <= 100; i++) {
setTimeout("fadeIn(" + (0 + i) + ")", i * 5);
}
}
}
function fadeOut(opacity) {
ele.style.opacity = opacity / 100;
if (opacity === 1) {
ele.style.display = "none";
}
}
function fadeIn(opacity) {
ele.style.opacity = opacity / 100;
if (opacity === 1) {
ele.style.display = "block";
}
}
function toggle() {
if(ele.style.display == "block") {
setTime("out");
text.innerHTML = "Show Map";
} else {
setTime("in");
text.innerHTML = "Hide Map";
}
}
</script>
you need to use time functions like setInterval or requestAnimationFrame
here is an example of setInterval
//to fade out
fadeout_interval = setInterval(function(el){
el.style.opacity -= 0.1;
if(el.style.opacity<=0) clearInterval(fadeout_interval);
}, 30, ele);
alternatively you can use css to do the same thing