My goal is to create a clickable grid in jQuery/javascript that when a cell is clicked it will return the index value of the cell and then not allow for anymore clicking after the first click (I'm working on a board game so a click on the board would be a move and once you have moved you can't move until your next turn). However, currently I'm having issues simply getting my click event to work properly.
For now I'm just looking to make it so when I click on my grid it changes the color of the cell to red.
I looked at Creating a Clickable Grid in a Web Browser but I have very little experience with js so I was fairly confused by how the callback functions worked. Therefore I was attempting to use part of that example and jQuery which seems, at least to me, to be much more understandable when it comes to attaching events to things.
EDIT: Forgot to say what my issue was but its the fact that when I run all of the following code and click on the grid nothing happens.
grid.js:
$(document).ready(function()
{
grid();
});
$("#grid td").click(function()
{
alert("Clicked!");
$("#grid td").addClass("clicked");
});
function grid()
{
var grid = document.getElementById("grid");
for(var r = 0; r<18; r++)
{
var tr = grid.appendChild(document.createElement('tr'));
for(var c = 0; c<18; c++)
{
var cell = tr.appendChild(document.createElement('td'));
}
}
}
grid.css:
.grid { margin:1em auto; border-collapse:collapse }
.grid td {
cursor:pointer;
width:30px; height:30px;
border:1px dotted #ccc;
text-align:center;
font-family:sans-serif; font-size:16px
}
.grid td.clicked {
background-color:red;
}
test.html:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf8">
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<link href="grid.css" rel="stylesheet">
<script src="grid.js"></script>
</head>
<body>
<table class="grid" id="grid">
</table>
</body>
</html>
I would change the event handler. I built a little sample in jsfiddle that might help. If not, please let us know specifically what you are having trouble with.
http://jsfiddle.net/richbuff/gLF4W/
$("td").bind("click", function(){
alert( $(this).text() );
// change style here
$(this).addClass("clicked");
});
Edit: Please put the click handler inside the ready() handler like this:
$(document)ready({
grid();
$("td").bind("click", function(){
alert( $(this).text() );
// change style here
$(this).addClass("clicked");
});
The issue is that the table (#grid) does not exist when the handler is being defined. You could also try putting the handler after the table tag.
Related
I am looking for javascript command that would do the following:
Click on image -> open spoiler
Click on image again -> hide spoiler
Here is what I got so far:
javascript in my html
<script>
function myFunction() {
document.getElementById("prvy").innerHTML = document.getElementById('spoiler_id').style.display='';}
</script>
Spoiler
<a id="show_id"
onclick="document.getElementById('spoiler_id').style.display=''; document.getElementById('show_id').style.display='none';"
class="link"></a><span id="spoiler_id"
style="display: none">[Show]<button onclick="document.getElementById('spoiler_id').style.display='none';
document.getElementById('show_id').style.display='';"
class="link">[Hide]</button>
<br><h1 id="bz">Heading</h1><br><br><p>text</p></span>
And my button:
<div id="prvy" onclick="myFunction()"></div>
What I managed to do, is to click on a image, wich will open spoiler. Hovewer, I've been unable to do the second part, onclick again it will close the spoiler.
I also did serach for solution alredy, nothing worked for me, not even this: Link
I also tired if{} else{} statement but didn't work for me either.
Help would be really appreciated, as I am getting desperate on this one.
You can use jQuery .toggle() to toggle show/hide
$("#prvy").click(function() {
$("#spoiler_id").toggle();
});
Note : You need to include jQuery in your document as
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Working snippet :
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<a id="show_id"
onclick="document.getElementById('spoiler_id').style.display=''; document.getElementById('show_id').style.display='none';"
class="link"></a><span id="spoiler_id"
style="display: none">[Show]<button onclick="document.getElementById('spoiler_id').style.display='none';
document.getElementById('show_id').style.display='';"
class="link">[Hide]</button>
<br><h1 id="bz">Heading</h1><br><br><p>text</p></span>
<div id="prvy" onclick="myFunction()">button</div>
<script>
$("#prvy").click(function() {
$("#spoiler_id").toggle();
});
</script>
In the JavaScript where you click the button use the simple jQuery function toggle.
$('#spoiler_id').toggle();
Toggle will hide the element selected if it is currently shown or display the element if it is currently hidden.
you would need some state that flips when the function is called.
like this.
<script>
var state = false;
function myFunction() {
state = !state;
if(state){
//do something
}else{
//do something else
}
}
</script>
Is that all of your code, it would be easier for you and less confusing too if you just gave the buttons an on click function and then called that function in your js.
Can I see all of your html
I am giving an example to concerned question using javascript.
HTML:
<script type="text/javascript">
var permit = 'true';
function showhide() {
var getcont = document.getElementsByClassName('hidshowcont');
if (permit === 'true') {
permit = 'false';
getcont[0].style.display = 'block';
}
else {
permit = 'true';
getcont[0].style.display = 'none';
}
}
</script>
<style type="text/css">
.hidshowcont{
height: 200px;
width: 300px;
border: 1px solid #333333;
display: none;
}
</style>
<img src="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcR1cSDTn18ufwjuMihttTvCPJOnFY-4hxbPcaOVd87nSPaQakbP9IERaQ" />
<br />
<br />
<div class="hidshowcont">
This is an example of hide and show the container by clicking of an image.
</div>
This will help u much
I have a this html page, Whenever the element with class name FreeSeat is clicked I want to change the colour of that div element.Below is my html page
<html>
<head>
<title>
QuickBus
</title>
<link type="text/css" rel="stylesheet" href="Seat.css">
</head>
<body>
<div id="Bus">
<div class="Row">
<div class="FreeSeat" ></div>
<div class="FreeSeat" ></div>
<div class="ResSeat" ></div>
<div class="ResSeat" ></div>
<div class="ResSeat" ></div>
</div>
</div>
<body>
</html>
It will be very helpful if anyone can help me out with this .
Considering that you want to use pure JS and not any library, you'd have to manually add event listeners to your classes.
And it has been solved for a similar problem here
var freeclass = document.getElementsByClassName("FreeSeat");
var myFunction_Free = function() {
this.style.color = "blue";
}
for(var i=0;i<freeclass.length;i++){
freeclass[i].addEventListener('click', myFunction_Free, false);
}
But for your case, here's a working fiddle
JQuery is amazing for these sorts of things.
Say you have a div with id 'box1'
<div id='box1'></div>
Style it with css
#box1 {
width:100px;
height:100px;
background-color:white;
border:1px solid black;
}
Using JQuery, you can make this call:
$( "#box1" ).click(function() {
$('#box1').css('background-color', 'red');
});
And now whenever your div is clicked, the colour will change, you can customise this however much you like.
Here is a JSFiddle demo.
Also, since you didn't specify exactly what you want to change the colour of, in my example jquery, it is telling the browser that when a div with an id of box1is clicked, change the background-color of the div with an id of box1, you can change anything though.
If you have a <p> tag you can change that too when the div is clicked, hope this helped!
You can use the following method to change the background color of an element by class:
const free_seat = document.getElementsByClassName('FreeSeat');
free_seat[0].style.backgroundColor = '#ff0';
Each element can be referenced by its index:
free_seat[0] // first div
free_seat[1] // second div
Therefore, we can create a function that will be called whenever the click event is delivered to the target:
const change_color = () => {
this.style.backgroundColor = '#ff0';
};
for (let i = 0; i < free_seat.length; i++) {
free_seat[i].addEventListener('click', change_color);
}
Note: You can also use document.querySelectorAll('.FreeSeat') to obtain a NodeList of elements of a certain class.
You can use simply the css focus pseudo-class for this:
#foo:focus {
background-color:red;
}
<div id="foo" tabindex="1">hello world!</div>
Dont forget to set the tabindex.
Okay, I think my head is being dense. But I cant seem to get this to work. I'm doing a website for a photographer, and he wants to be able to let a user change the frame that they would like from a choice of 3. Easiest way I thought to do this was to create a div, and then have it change class based on a button click. So it would change the background image. However I cant get it to do this. Any ideas would be well received, as I'm guessing theres probably a javascript version that does it quicker and easier.
<html>
<head>
<title>Untitled</title>
<style>
#pictureframe {
width:200px;
height:200px;
}
.wooden {
background-image:url(frame.png);
}
.plain {
background-image:url(clear.png);
}
.black {
background-image:url(black.png);
}
</style>
</head>
<body>
<div id="pictureframe">
</div>
<div style="height:20px;border:1px solid #617779;width:90px;text-align:center;background-color:white;" onclick = "pictureframe.style.className = 'wooden'">Make it wood</div>
<br>
<div style="height:20px;border:1px solid #617779;width:90px;text-align:center;background-color:white;" onclick = "pictureframe.style.className = 'clear'">Make it Frameless</div>
<br>
<div style="height:20px;border:1px solid #617779;width:90px;text-align:center;background-color:white;" onclick = "pictureframe.style.className = 'wooden'">Make it Black Bezel</div>
</body>
className is not part of the style object in the DOM element, but a direct property:
document.getElementById("pictureframe").className = 'wooden';
It's not
pictureframe.style.className = ...
but
pictureframe.className = ...
DEMO
Try this:
onclick ="pictureframe.className = 'wooden'"
If you want to use some other class for style, than you probably need to go with something like this:
function replaceClass(className) {
$('#pictureframe').removeClass('plain black wooden');
return $('#pictureframe').addClass(className);
}
This way you can keep class with styles http://jsfiddle.net/NjTea/5/
In my index.html page, I have an empty table defined as following:
<body>
...
<table width="500" border="0" cellpadding="1" cellspacing="0" class="mytable">
<tr></tr>
</table>
<script src="my.js"></script>
</body>
As you saw above, there is an JavaScript file my.js is included.
my.js(which is used to update the table row):
var items = ARRAY_OF_OBJECTS_FROM_SERVER; //e.g. items=[{'John', '023567'},{'Bill', '055534'},...];
//Each object element in the "items" array contain "name" and "phone" attribute.
var mytable = $('.mytable tr:first');
for(var i=0; i<items.length; i++){
var obj = items[i];
mytable.after("<tr>");
mytable.after("<td> </td>");
mytable.after(" <td>"+obj.name+"</td>");
mytable.after("<td>"+obj.phone+"</td>");
mytable.after("</tr>");
}
I successfully get the dynamical table working, but when I try to add mouse hover effect on each row, I just failed. What I tried is by using CSS:
.mytable tr:hover
{
background-color: #632a2a;
color: #fff;
}
I would like the mouse hover with color highlight effect to be working on IE 7+, firefox and chrome, what is the correct way to implement the table row mouse hover effect in my case??
----EDIT----
Here is my index.html page:
index.html
<!DOCTYPE HTML>
<html>
<head>
<script type="text/javascript" src="https://getfirebug.com/firebug-lite.js"></script>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<title>my test</title>
<link href="mystyle.css" rel="stylesheet" type="text/css" media="screen" />
</head>
<body>
<table width="500" border="0" cellpadding="1" cellspacing="0" class="mytable">
<tr>
</tr>
</table>
<script src="my.js"></script>
</body>
</html>
--SOLUTION----
#manji 's solution solved my problem. That's change in JavaScript to use append instead of after inside for loop. Then, the CSS way of highlighting row is working.
You are writing the <td> outside of <tr> with this:
mytable.after("<tr>");
mytable.after("<td> </td>");
mytable.after(" <td>"+obj.name+"</td>");
mytable.after("<td>"+obj.phone+"</td>");
mytable.after("</tr>");
For example, first one will add a <tr> and close it, then 3 closed <td>s before the <tr> and the last one is incorrect and will have no effect.
Try it this way and it will work:
mytable.after("<tr>"
+"<td> </td>"
+"<td>"+obj.name+"</td>"
+"<td>"+obj.phone+"</td>"
+"</tr>");
and it's better to use .append() (it will add the objects in their list order):
var mytable = $('.mytable'); // mytable selector is changed to select the table
// you can remove the empty <tr>
for(var i=0; i<items.length; i++){
var obj = items[i];
mytable.append("<tr>"
+"<td> </td>"
+"<td>"+obj.name+"</td>"
+"<td>"+obj.phone+"</td>"
+"</tr>");
Try the following:
.mytable tr:hover td
{
background-color: #632a2a;
color: #fff;
}
Given your list of browser support, CSS is the proper solution. It's important to note that the cells (<td>) cover the row (<tr>). So it's their background that you want to modify.
You're best bet is to use jquery's hover: Click Here
IE 7 did not have hover support on elements other than anchor tags. (or maybe that was just 6) either way, since you are using jquery already you can get your hover effect done easily.
$("tr").hover(
function () {
$(this).addClass('hover_class');
},
function () {
$(this).removeClass('hover_class');
}
);
Note: IE 7 will only allow :hover if you are running in HTML 4.01 STRICT for your doctype. Otherwise you need to use javascript to accomplish what you are looking to do.
If you cannot get the css solution to work use a delegate function to handle the dynamic rows.
$("table.mytable").delegate("tr", "hover", function(){
$(this).toggleClass("hover");
});
jQuery:
$('.mytable tr').hover(function() {
$(this).addClass('active');
}, function() {
$(this).removeClass('active');
});
CSS:
.mytable tr.active td
{
background-color: #632a2a;
color: #fff;
}
Check out the working example: http://jsfiddle.net/JpJFC/
Use jquery delegate method which is the best way to do it from performance point of view.
$(".mytable").delegate("tr", "mouseover", function(e) {
$(this).addClass('mouseoverClass');
});
$(".mytable").delegate("tr", "mouseout", function(e) {
$(this).removeClass('mouseoverClass');
});
I'm in the process of learning Javascript and I'm trying to create a simple dropdown menu. An example of my desired functionality can be seen on the google homepage in the top menu with the "more" and "settings" dropdown. Specifically when you click off the menu, the menu disappears.
What code do I need to place in the hideMenus function in Javascript to hide the visible uls when a click occurs anywhere on screen?
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
<title>Untitled 1</title>
<style type="text/css">
a
{
color:blue;
}
.info ul.submenu
{
border: solid 1px #e0e0e0;
background-color: #fff;
position: absolute;
padding: 0;
z-index: 2;
display: none;
}
.info ul.submenu li
{
display: block;
border-top: solid 1px #e0e0e0;
margin: 0px 10px 0 10px;
}
.info ul.submenu li a
{
display: block;
padding: 7px 0px 6px 0;
color: #1177ee;
cursor:pointer;
}
</style>
<script type="text/javascript">
function hideMenus()
{
//TODO
}
function menu(id) {
var myLayer = document.getElementById(id);
myLayer.onblur = function() {
myLayer.style.display = 'none';
};
if (myLayer.style.display == "none" || myLayer.style.display == "") {
myLayer.style.display = "block";
} else {
myLayer.style.display = "none";
}
}
</script>
</head>
<body onclick="hideMenus();">
<div class="info">
Some Text Boom A <a onclick="menu('id1');">Link</a> | More text
<a onclick="menu('id2');">Another Link</a> | more text
<ul id="id1" class="submenu">
<li>A1</li>
<li>A2 This is Long</li>
<li>A3</li>
</ul>
<ul id="id2" class="submenu">
<li>B1</li>
<li>B2</li>
<li>B3</li>
</ul>
</div>
</body>
</html>
I do not want to use jQuery.
It looks like you have a pretty decent setup as-is. You'll likely run into some event bubbling problems (for more info, take a look at PPK's Event Order Article). That seems to be outside of the scope of your current question, so I'll just give you what you asked for:
hideMenus()
{
var uls = document.getElementsByTagName('ul'), i;
for (i = 0; i < uls.length; i++)
{
if (uls[i].className === 'submenu' && uls[i].style.display !== 'none')
{
uls[i].style.display = 'none';
}
}
}
First, we get all the <ul>'s on the page. Then, we loop through all of them, check to see if it's a submenu, and if it's currently displayed. If both are true, then we hide it.
There are a couple faults with this code:
If the uls have more than one class (class="animal submenu"), then it will not hide the menu
It will look through all the <ul>'s on the page. This isn't exactly efficient, but it's the only way to do it without cross-browser support for getElementsByClass.
These aren't huge faults, especially if you're only using this to learn about javascript, and if you closely control your code (i.e. no other developers are working on it). All in all, it's a good stepping stone.
In the future, I'd suggest using addEvent - a fairly common function that allows you to add event handlers to elements without using onclick="...". There are a couple different implementations of it, but they (almost) all work the same from your perspective. Here are links to Dean Edwards's Version and John Resig's Version
Good luck!
Here is more or less the logic we use in our web app for drop down menus:
<html>
<head>
<title></title>
</head>
<body>
<div style="position:relative;width:250px">
<a id="link" href="javascript:" onclick="showDiv(this)">Show menu</a>
<ul id="entries" style="display:none;background:#DEF;padding:0;margin:0">
<li>item 1</li>
<li>item 2</li>
</ul>
<input id="inp" style="position:absolute;left:-30px;width:0" />
</div>
<script>
function showDiv(lnk){
var entries = document.getElementById('entries'),
inp = document.getElementById('inp'),
nh = 'data-nohide';
//show the entries
entries.style.display = 'block';
entries.removeAttribute(nh);
inp.focus();
//if mouse over, can't close it
entries.onmouseover = function(){
this.setAttribute(nh, true);
inp.focus();
};
//if mouse out, can close it
entries.onmouseout = function(){
this.removeAttribute(nh);
};
entries.onclick = function(e){
//code when the user clicks on the menu...
alert((e.target||e.sourceElement).innerHTML);
this.style.display = 'none';
};
//if the user press ESC
inp.onkeyup = function(e){
if(e.keyCode === 27){
this.style.display = 'none';
this.removeAttribute(nh);
}else{
//do something else with other keys(ie:down, up, enter)...
inp.focus();
}
};
//click somewhere else input onblur
inp.onblur = function(){
if(!entries.getAttribute(nh)){
entries.style.display = 'none';
entries = inp = null;
}
};
}
</script>
</body>
</html>
The trick is to use an input field that has the focus, and when it looses it an onblur is triggered and close the menu.
The mouseover, mouseout are there to prevent the onblur to fire when the user click an item in the menu.
To have a toggle effect like an open/close on the link, I guess 2 links that hide each other are needed.
You can capture a click anywhere if you put onclick on the body.
Because of the javascript event propagation model, if you click anywhere on any element and you don't stop the event from propagating, it will reach body and hide the menus.
So basically this means that you want to capture body onclick and make it to hide the menus so when you click on any area of the page, it will close the menus.
But this hides a bit of unwanted behaviour - when you click on the button to show the menu, the menu will display and quickly after that hide (when the event reaches body). To prevent this, you will want to stop the event from propagating when you click on the button which shows the menu (you can see how this works in the code I posted below). The code shows where you need to touch to make it work nicely.
// this function stops event e or window.event if e is not present from
// propagating to other elements.
function stop_event(e) {
if(!e) {
e = window.event;
}
if (e.stopPropagation) e.stopPropagation();
e.cancelBubble = true;
if (e.preventDefault) e.preventDefault();
e.returnValue = false;
return false;
}
// now you just hide all the menus in your hideMenus
function hideMenus()
{
//pseudocode!
for all visible menus - hide // or if you want you can hide all menus,
// the hidden will remain hidden
}
Now the important part.
function menu(id) {
// your stuff here
stop_event(); // this will stop the event going down to the body
// and hiding it after showing it
// this means it will not flicker like: show-hide
}
And finally on your whole UL element:
//partly pesudocode
ul.onclick = function() { stop_event(); }
To explain again what this does:
1st. You hook your hideMenu function to body.onclick. This means that it will always hide the menus if we don't stop the event.
2nd. When you click the menu button, you show the menu and then we stop the event from going to the body. This way, the body.onclick will not fire and it will not hide the menu right after we opened it.
3rd. The ul.onclick means that the menu will not hide itself when we click on it (though if you want the menu to hide when you click the menu itself, you can remove this part).