I am creating 3 jsp pages. There are 4 boxes with different id in each pages (i.e. box1, box2, box3, box 4 in page 1; box 5, box6, box7, box8 in page 2; box9, box10, box11, box12 in page 3). Below is the sample code in page 1:
<div class="dragableBox" id="box1">CAT</div>
<div class="dragableBox" id="box2">DOG</div>
<div class="dragableBox" id="box3">HORSE</div>
<div class="dragableBox" id="box4">TIGER</div>
In each page there is also a script. In the script I deliberately use all those ids above as parameters of a function. Below is the sample code in page 1:
dragDropObj.addSource('box1',true);
dragDropObj.addSource('box2',true);
dragDropObj.addSource('box3',true);
dragDropObj.addSource('box4',true);
dragDropObj.addSource('box5',true);
dragDropObj.addSource('box6',true);
dragDropObj.addSource('box7',true);
dragDropObj.addSource('box8',true);
dragDropObj.addSource('box9',true);
dragDropObj.addSource('box10',true);
dragDropObj.addSource('box11',true);
dragDropObj.addSource('box12',true);
I must do this because as far as I know this is the only way for my program to work. The problem I encounter is that each time the program started, a warning appears:
"The source element with id box5 does not exist"
Although the program still works fine with this warning, I still want to eliminate the warning.
My question here is:
How can I stop such warning from appearing?
Is there a kind of error catching method in HTML?
Check the existence of element before adding them.
if (typeof document.getElementById('box5') !== 'undefined'){
// continue
}
Try this: this will grab all 'dragableBox' on page and run 'dragDropObj.addSource(...,true);' on them if they have an id=box[x] without using JQuery:
boxes = document.getElementsByClassName('dragableBox');
for (i=0; i < boxes.length; ++i) {
var id = boxes[i].id;
if(id.substring(0,3)==='box')
dragDropObj.addSource(id,true);
}
if (document.getElementById('box1')){
dragDropObj.addSource('box1',true);
dragDropObj.addSource('box2',true);
dragDropObj.addSource('box3',true);
dragDropObj.addSource('box4',true);
}
if (document.getElementById('box5')){
dragDropObj.addSource('box5',true);
dragDropObj.addSource('box6',true);
dragDropObj.addSource('box7',true);
dragDropObj.addSource('box8',true);
}
if (document.getElementById('box9')){
dragDropObj.addSource('box9',true);
dragDropObj.addSource('box10',true);
dragDropObj.addSource('box11',true);
dragDropObj.addSource('box12',true);
}
EDIT:
A better solution:
groupFirstMember = 1;
if (document.getElementById('box5')){
groupFirstMember = 5;
}
else if (document.getElementById('box9')){
groupFirstMember = 9;
}
for(i=0;i<4;i++){
dragDropObj.addSource("box"+str(groupFirstMember+i),true);
}
Related
I'm making a hangman game using JavaScript and need to hide some HTML for a few seconds to display an error message, and then revert back to the original HTML. I've tried using setTimeout(); and setInterval(); but those seem to just wait a few seconds before displaying the error message.
Here's the code for reference:
<div class="row text-center">
<div id="alredGuess" class="col">
<div>
<span id="guessedLetters"></span> <br>
</div>
<div>Guesses left:<span id="guessesLeft">10</span></div>
<div>Wins:<span id="wins">0</span></div>
<div>Losses:<span id="losses">0</span></div>
</div>
</div>
JS:
if (gameRunning === true && guessedLetterBank.indexOf(letter) === -1) {
// run game logic
guessedLetterBank.push(letter);
// Check if letter is in picked word
for (var i = 0; i < pickedWord.length; i++) {
//convert to lower case
if (pickedWord[i].toLowerCase() === letter.toLowerCase()) {
//if match, swap placeholder
pickedWordPlaceholderArr[i] = pickedWord[i];
}
}
$placeholders.textContent = pickedWordPlaceholderArr.join("");
checkIncorrect(letter);
} else if (gameRunning === false) {
$placeholders.textContent = "Press \"A\" To Begin!"
} else {
//alert("You've already guessed this letter.")
function newAlert() {
var hideDiv = document.getElementById("alredGuess");
if (hideDiv.style.display = "block") {
hideDiv.style.display = "none";
}
}
hideDiv.textContent("You've already guessed this letter!");
function showDiv() {
var showDiv = document.getElementById("alredGuess");
if (hideDiv.style.display = "none") {
hideDiv.style.display = "block";
}
}
}
}
setInterval(newAlert, 3000);
}
Tip 1
Well, first of all i don't recommend using display: block|none to show or hide DOM elements. Instead try using visibility: visible|hidden or better, toggle a css class name such as : .hidden. That's because when you set a DOM element's display to none, its width and height are gonna be set to zero, often causing an unwanted loss of space because the DOM node visually collapses. With the visibility property, for example, the element just disappears without loss of space.
Tip 2
Error/status messages should always live within their own containers. Do not display messages in substitution of some content you need to revert back after.
It is always better to prepare an empty <div>, hide it by default with a generic .hiddenCSS class and then remove this one as soon as you need to display the container.
Suggested solution
Now, in your case, i think you're using setIntervalin the wrong way. You have to immediately show the alert message, then make it disappear after a few seconds.
As suggested above, this should be done by toggling CSS classes, using different containers and using setTimeout in order to remove/add the CSS classes as soon as the interval is over. Basically, the setTimeout restores everything to its original state.
So, given this HTML code:
<div id="alredGuess">This is the original text</div>
<div id="alertbox" class="hidden"></div>
and this CSS code:
.hidden { visibility: hidden; }
try this:
var alertTimeout = 1000; // Timeout in milliseconds.
function showAlertMessage() {
// This is your original text container.
var alredGuess = document.getElementById("alredGuess");
// This is the new error message container named #alertbox
var alertBox = document.getElementById("alertbox");
// Now let's fill it with the specific error text (better using HTML here).
alertBox.innerHTML = "You've already guessed this letter!";
// Hide the original container by adding an .hidden css class.
alredGuess.classList.add('hidden');
// Show the error message container by removing its default .hidden css class.
alertBox.classList.remove('hidden');
// Then set up an interval: as it ends, revert everything to its original state.
setTimeout(function() {
alertBox.classList.add('hidden');
alredGuess.classList.remove('hidden');
}, alertTimeout);
}
// Call the function.
showAlertMessage();
Fiddle: https://jsfiddle.net/qyk4jspd/
Hope this helps.
For a project, I'm trying to highlight the logical fallacy of circular reasoning and have precious few lines of code later to be inserted into a separate webpage.
I am trying to create a simple process of clicking the displayed text to switch back and forth between the two questions. I've tried buttons and it only complicates and make no progress. Half a day gone, still banging my head on desk, as the phrase goes.
I read elsewhere that creating a var tracker facilitates, though I see it only for images, rather than displayed text. It feels like approaching my wits end, but I lack the time to walk away and try again.
This is my code thus far:
<!doctype html>
<head>
<script>
function change() {
var paragraph = document.getElementById("whytrust");
paragraph.innerHTML="I am trustworthy, but how can you be sure?";
}
</script>
</head>
<body>
<p id="whytrust" onclick="change();">You can trust me, but how can you be sure?</p>
</body>
</html>
You need some place to hold the old message so you can put it back again after you toggle the contents.
<!doctype html>
<head>
<script>
var newMsg = "I am trustworthy, but how can you be sure?";
function change() {
var paragraph = document.getElementById("whytrust");
var oldMsg = paragraph.innerHTML;
paragraph.innerHTML = newMsg;
newMsg = oldMsg;
}
</script>
</head>
<body>
<p id="whytrust" onclick="change();">You can trust me, but how can you be sure?</p>
</body>
</html>
This a quick and dirty implementation of what you want. I added a data-textindex attribute to the html element. There I stored an index for the currently shown text. In the javascript I check the current value, update data-textindex and replace it with new text.
function change() {
let paragraph = document.getElementById("whytrust");
let currentlyshown = paragraph.getAttribute('data-textindex');
if(currentlyshown == 0){
paragraph.innerText="I am trustworthy, but how can you be sure?";
paragraph.setAttribute('data-textindex', '1');
}else if(currentlyshown == 1){
paragraph.innerText="You can trust me, but how can you be sure?";
paragraph.setAttribute('data-textindex', '0');
}
}
<p id="whytrust" data-textindex="0" onclick="change();">You can trust me, but how can you be sure?</p>
On a sidenote: You can improve this code a lot. Like storing your text in a json-object. Or maybe using the ternary operator if you are 100% sure there will always be 2 choices. maybe give the function some arguments so you can apply it in a more general scenario.
Try tracking some sort of 'state' for your paragraph -- be it on/off, active/inactive...
Each time the change() function gets called, it doesn't remember what the paragraph was or was supposed to be. So, by setting a state of some sort (in my example a data-state attribute assigned to the paragraph element) the code can know how to behave.
function change() {
var paragraph = document.getElementById("whytrust");
var output = '';
// data-* can be anything, but handy for referencing things
var state = paragraph.getAttribute('data-state');
// check if data-state even exists
if( !state ){
// set it to the default/original state
paragraph.setAttribute('data-state', 'inactive');
state = 'inactive';
}
// toggle the state
// and assign the new text
if( state === 'inactive' ){
paragraph.setAttribute('data-state', 'active' );
output = "I am trustworthy, but how can you be sure?";
}else{
paragraph.setAttribute('data-state', 'inactive');
output = "You can trust me, but how can you be sure?";
}
paragraph.innerHTML = output;
}
<p id="whytrust" onclick="change();">You can trust me, but how can you be sure?</p>
Another option, without tracking state could be hiding and showing the paragraph you want displayed. You don't really need to track state or save the alternating text...
// get the elements from the DOM that you want to hide/show
// you can get tricky and add alternative ways to track
// the paragraph elements, but this works nice for a demo
const whytrust = document.getElementById('whytrust'),
answer = document.getElementById('whytrust-answer');
function change( element ){
// the element parameter being passed is the paragraph tag
// that is present/visible
if( element.id === 'whytrust' ){
answer.className = ''; // clear the .hide class
whytrust.className = 'hide'; // add the .hide class
}else{
whytrust.className = ''; // clear the .hide class
answer.className = 'hide'; // add the .hide class
}
}
.hide{ display: none; }
<p id="whytrust" onclick="change(this);">I am trustworthy, but how can you be sure?"</p>
<p id="whytrust-answer" class="hide" onclick="change(this);">You can trust me, but how can you be sure?</p>
What I like about this solution is that it keeps the content in the HTML and the JavaScript just worries about what to hide/show.
In Javascript, I'm trying to create a user script that will automatically click on a 'Blue Button'. Normally, I would do this:
var bluebutton = "document.getElementById("blue_button")"
if (bluebutton) {
bluebutton.onclick();
}
But NOW, the blue button does not have its own obvious ID. It's ID is randomized, and could be either button1, button2, or button3.
Here's the HTML that I'm talking about:
<div class="button_slot">
<div id="button1" style="cursor:pointer; padding-left:30px" onclick="buttonsubmit('button1')" onmouseover="infopane.display('Blue Button','I'm a blue button!')" onmouseout="infopane.clear()">
<div class="button_slot">
<div id="button2" style="cursor:pointer; padding-left:30px" onclick="buttonsubmit('button2')" onmouseover="infopane.display('Red Button','I'm a red button!')" onmouseout="infopane.clear()">
<div class="button_slot">
<div id="button3" style="cursor:pointer; padding-left:30px" onclick="buttonsubmit('button3')" onmouseover="infopane.display('Yellow Button','I'm a yellow button!')" onmouseout="infopane.clear()">
After a bit of reading, I've concluded that the only way to direct my onclick() to the correct element/string is by using ".toString().match(name)" as shown below:
function clickbutton(name) {
var button_list = document.querySelectorAll('.button_slot > div');
for (var i=0; i<button_list.length; i++) {
var button = button_list[i];
if (button.onmouseover && button.onmouseover.toString().match(name)) {
button.onmouseover();
button.onclick();
break;
}
}
}
clickbutton('Blue');
(note: sometimes I use clickbutton('Red'); or clickbutton('Yellow'); just to experiemen)
Now here's the problem. This method works so horribly... Sometimes, my script completely misses the button (as in, nothing gets clicked) EVEN THOUGH there is definitely a string with the word 'Blue' in it.
If someone could identify what I'm doing wrong, or perhaps even suggest a more effective method, I would appreciate it so much! Thank you!
First, I'm not sure why you can't give each button an ID which corresponds to it's color, because I believe that would be the easiest way to achieve this. But assuming that, for some reason, your button ID's must be randomized (or for that matter, maybe they don't even have an ID).
In this case, what I would do is give each button a data-button-type attribute, for instance:
<div data-button-type="Blue" id="..." style="..." onclick="..." onmouseover="..." onmouseout="...">
Now, I can check the attribute when looking for which button to click, for example:
function clickbutton(name) {
var button_list = document.querySelectorAll('.button_slot > div');
for (var i=0; i<button_list.length; i++) {
var button = button_list[i];
if (button.getAttribute('data-button-type') == name) {
button.onmouseover();
button.onclick();
break;
}
}
}
clickbutton('Blue');
I'm pretty sure you want to use indexOf although I think its most likely a timing issue.
First just try invoking it in a setTimeout function, so the document has (probably) loaded fully when you execute. It would explain it sometimes working sometimes not.
setTimeout(function(){ clickbutton(name) }, 3000);
I would do:
var clickButton = function(name){
var button_list = document.querySelectorAll('.button_slot > div');
for(var i = 0; i < button_list.length; i++){
var button = button_list[i];
if(button.getAttribute('onmouseover').indexOf(name) !== -1){
button.onclick.apply(); // They seem to have parameters in your example?
}
break;
}
}
setTimeout(function(){ clickButton('blah') }, 3000);
As a first attempt...
I am trying to write a JS code to change color of the current link. For example, if page one address is www.abc.com/abc, and page 2 is www.abc.com/abc/product, then page one will turn red.Basically if page 2 is subpage of page1, then page 1 will turn red.
Here is my idea:
compare char one by one in page1 and page2
if(currentpage.href!=one of a.href)
flag=false;
if(flag==true)
then turn red
else
then turn blue
Here are my codes below:
<div id="changeColor" class="horizontalcssmenu" style="padding-left:7px;">
<a href="linkeadress" >HOME</a>
<a href="linkaddress" >SHOP</a>
</div>
<script type="text/javascript">
var links = document.getElementById("changeColor");
var a = links.getElementsByTagName("a");
var thisLocationHref = window.location.href;
var counter=0;
for(var i=0;i<a.length;i++){
var flag="true";
var tempLink=a[i];
while(counter<=a[i].length){
if(thisLocationHref[counter]!=tempLink.href[counter])
{flag="false";}
counter++;
}
if(flag=="true")
{tempLink.style.color=red";
}
else
{
tempLink.style.color="blue";
}
}
Thank you for time!
While on the surface of it, the answer is trivial, it appears that it is fairly common to do this kind of comparison wrong.
DO NOT DO:
// compare at most `haystack.length - needle.length' characters
// haystack is usually the longest string
haystack.indexOf(needle) == 0
DO:
// compare at most `needle.length' characters
// but never compare any characters, if the haystack is
// smaller then the needle
haystack.length >= needle.length &&
haystack.substr(0, needle.length) == needle
It is really not possible to determine if a link actually IS pointing to a "parentpage" or a "subpage", but according to the examples given you can try to evaluate if the current page
is a "subpage" of a link by their lengths and the current page prepends the link.
<div id="changeColor" class="horizontalcssmenu" style="padding-left:7px;">
HOME <!-- www.abc.com/abc -->
SHOP <!-- www.abc.com/abc/prodct -->
</div>
<script type="text/javascript">
var links=document.getElementsByTagName('a');
for (var i=0;i<links.length;i++) {
//is length of the link less than current page?
if ((parseInt(links[i].href.length)<parseInt(window.location.href.length)) &&
//does the link prepending the current page?
(window.location.href.indexOf(links[i].href)>-1)) {
//probably this is a link to the "parentpage", eg "page 1"
links[i].style.color='#ff0000';
}
}
</script>
Please - i really dont want to be downvoted for this. It does what the question angles for, strange questions gives strange answers :)
hey guys having trouble figuring out how to make it so that i can make it only open one table at once, once you open another the other should close any help here?
function showRow(cctab){
if (document.getElementById(cctab)) {
document.getElementById(cctab).style.display = '';
}
}
function hideRow(row1){
if (document.getElementById(cctab)) {
document.getElementById(cctab).style.display = 'none';
}
}
function toggleRow(cctab){
if (document.getElementById(cctab)) {
if (document.getElementById(cctab).style.display == 'none') {
showRow(cctab)
} else {
hideRow(cctab)
}
}
}
Now I want to make it so that only one table "cctab" opens after I suggest the onClick="javascript:toggleRow(cctab);" anyhelp?
Well you could save a reference to the previously shown item and hide it when another is shown:
var currentTab;
function showRow(cctab){
if (document.getElementById(cctab))
document.getElementById(cctab).style.display = '';
if (currentTab && currentTab != cctab)
hideRow(currentTab);
currentTab = cctab;
}
Note that doing inline event handler attributes is so 1999, but assuming you're sticking with it for whatever reason you don't need the javascript: in onClick="javascript:toggleRow(cctab);". (Just say onClick="toggleRow(cctab);")
First you need to store the old row somewhere.
What you've got is a system where you're using <element onclick="..."> to pass the id of the current element into the controller that shows or hides the row.
But if you look at that, what you're missing is a way of telling what the last open row was.
So what your code will need is a central object, or variables which store the old element and the new element.
How you do this is up to you, but if you did something like this:
var table_rows = { current : null /* or set a default */, previous : null };
function rowController (cctab) {
var newRow = document.getElementById(cctab);
if (newRow === table_rows.current) { toggleRow(newRow); }
else {
table_rows.previous = table_rows.current;
table_rows.current = newRow;
showRow(table_rows.current);
hideRow(table_rows.previous);
}
}
Note:
This deals with elements directly, so you don't have to do getById in your functions;
that's handled one time, and then that element is passed around and saved and checked against.
It assumes that the click is happening on the row itself, and not on anything inside of the row;
that's a separate issue that your code has.
Unless it's obvious and easy to click on the row, and not the cells inside of the row, it's difficult to tell how you want users to be able to open and close rows.
What I mean is if only the table-row has an onclick, and somebody clicks on a table-column, then then onclick isn't going to fire.