Hi,
As I say all the time JS is not my forte so you would get better logic asking in the JS forum as I’m sure my code could be halved and simplified 
However, I’ll explain what I did to get it working and remember this is my first version and was just about getting something to work. Optimisation and efficiency would be the next step (as well as making the whole design fluid).
Firstly I decide that I would use the before element to draw the ball in each square and that is done with CSS.
.filled:before{
content:"";
display:block;
position:absolute;
left:0;
right:0;
top:0;
bottom:0;
margin:auto;
width:40px;
height:40px;
border-radius:50%;
background:red;
animation:fadeBall .5s ease forwards;
transform:translateY(-580px);
z-index:101;
box-shadow:10px 10px 10px rgba(0,0,0,0.7);
}
.filled.player1:before{background:red;}
.filled.player2:before{background:orange;}
@keyframes fadeBall{
to{transform:translateY(0)}
}
The JS adds the class called .filled
and soon as that is added the counter is animated from above the board and into its correct position. In order to simplify things I translated all the counters from -580px on the Y axis (basically upwards) so that they were hidden above the top of the board as I hidden the overflow. When the class is added the counter will animate back to a zero position which is in the square to which it is positioned from. The 580px is a bit of magic number but is basically taller than the height of the board. It doesn’t really matter they they all animate to different squares as the animation is the same duration for each.
In the JS I set up an array that listed the column numbers. (All cells had classes added to them when the JS starts to make it easier to keep track.)
columns = [
["c0", "c7", "c14", "c21", "c28", "c35"],
["c1", "c8", "c15", "c22", "c29", "c36"],
["c2", "c9", "c16", "c23", "c30", "c37"],
["c3", "c10", "c17", "c24", "c31", "c38"],
["c4", "c11", "c18", "c25", "c32", "c39"],
["c5", "c12", "c19", "c26", "c33", "c40"],
["c6", "c13", "c20", "c27", "c34", "c41"]
];
As you see each row of the array indicates the class name of a vertical connect 4 column. The JS detects which column was clicked and will then remove the last entry in the column.
columns[i].splice(columns[i].length - 1, 1);
That means that the array gets shorter and shorter for each column so we know what spaces are available. Eventually a column may get to zero so we know there is nothing to fill in that column.
(To be honest you could probably have worked this with one array as I use another array for the actual cell positions but I wanted to keep it simple and get it working first.)
The main board is held in another array:
columnWin = [
["c0", "c6", "c12", "c18", "c24", "c30", "c36"],
["c1", "c7", "c13", "c19", "c25", "c31", "c37"],
["c2", "c8", "c14", "c20", "c26", "c32", "c38"],
["c3", "c9", "c15", "c21", "c27", "c33", "c39"],
["c4", "c10", "c16", "c22", "c28", "c34", "c40"],
["c5", "c11", "c17", "c23", "c29", "c35", "c41"]
]
The above array contains the classnames that make the connect four grid (remember our html is just a linear selection of divs.) When a counter is dropped I change the cell classname in the array to say the playername instead. In that way we can cycle through later and find 4 in sequence.
To select a winner you would cycle through that array in a loop and test if 4 items match.To make it easier I cycled horizontally, vertically and diagonally left and diagonally right in 4 separate loops. It could all be done in one loop I think but would look cumbersome.
When you move horizontally through the array you just need to loop through 4 items for each row because check the one in the loop and then the next + next + next which means you are checking 4 at a time. the logic for vertical and horizontal is much the same except that the next item in sequence will be a bit further away.
i.e. for a diagonal 4 going to the left you would need.
for (i = 0; i < 3; i++) {
for (j = 3; j < 7; j++) {
if (columnWin[i][j] === theWinner &&
columnWin[(i + 1)][(j - 1)] === theWinner &&
columnWin[(i + 2)][(j - 2)] === theWinner &&
columnWin[(i + 3)][(j - 3)] === theWinner)
{
To check winners we just have to cycle through the ColumnWin array in blocks of 4 and to see if it has 4 player name matches in sequence so we can declare a winner.
Player names are toggled on each click and we change colours etc as required.
So to recap I check which column is being hovered and look up in the array for the classname at the bottom of each column. A class is added to that square in the html to trigger the animation and color the counter (i.e. the filled class and the playername class). Once the filled class is added the CSS does its work and animates the counter into its place. We then remove that entry from the column array so that we don’t fill it again.
To check winners we just have to cycle through the ColumnWin array in blocks of 4 and to see if it has 4 player name matches in sequence so we can declare a winner.
There is some complexity due to the fact that the html is linear while the connect four is a 7x 6 grid so we have to map between the two hence the need for the extra array.
In truth we could probably have done this without any arrays and just adding classes to the html and then checking the html on its own. I found it easier to visualise using the arrays and did this as a first iteration.
The next steps would have been to see how the whole thing could be simplified once a working version was created. It may be that a lot of the code is redundant but its so much easier once you have something working and then you can refine and make better.
Final steps would be to make the whole thing fluid in css and make it easier for touch users. Timings probably need to be altered as the JS acts quicker than the css animation so you would probably only declare winners after an animation has finished.
As I said you would be better asking in the JS forum for more succinct and logical approach once you decide how you want to programme this.
I have also added some comments to the demo above so hope it helps anyway.