Ok so I have a function set up already and it gets added in the div as numbers and letters
"var elCamLocation = $( "TEST" )"
Right!
Now I want to use a function to keep track on what is in the innerHTML of the "TEST" div and if the contents of the div changes to "0.00x2.00z0.00" then I want it to do something for example lets just say change url to keep it simple.
Here is what I have..
var Numbs = getElementById("TEST").innerHTML;
function TE()
{
if(Numbs = "0.00x2.00z0.00")
{
window.location.assign("http://google.com")
}
};
But it isn't working the window.location.assign("http://google.com")isn't triggering at all
any idea's?
= is for assignment. You should test for equality using the === operator.
if(Numbs === "0.00x2.00z0.00")
{
//etc.
}
Related
I'm trying to make a click handler that calls a function; and that function gets a string and basically slices the last character and adds it to the front, and each time you click again it should add the last letter to the front.
It seem so easy at first that I thought I could just do it using array methods.
function scrollString() {
var defaultString = "Learning to Code Javascript Rocks!";
var clickCount = 0;
if (clickCount === 0) {
var stringArray = defaultString.split("");
var lastChar = stringArray.pop();
stringArray.unshift(lastChar);
var newString = stringArray.join('');
clickCount++;
} else {
var newArray = newString.split("");
var newLastChar = newArray.pop();
newArray.unshift(newLastChar);
var newerString = newArray.join("");
clickCount++;
}
document.getElementById('Result').innerHTML = (clickCount === 1) ? newString : newerString;
}
$('#button').on('click', scrollString);
Right now it only works the first time I click, and developer tools says newArray is undefined; also the clickCount stops incrementing. I do not know if it's an issue of scope, or should I take a whole different approach to the problem?
Every time you click you are actually reseting the string. Check the scope!
var str = "Learning to Code Javascript Rocks!";
var button = document.getElementById("button");
var output = document.getElementById("output");
output.innerHTML = str;
button.addEventListener("click", function(e){
str = str.charAt(str.length - 1) + str.substring(0, str.length - 1);
output.innerHTML = str;
});
button{
display: block;
margin: 25px 0;
}
<button id="button">Click Me!</button>
<label id="output"></label>
It is, in fact, a scoping issue. Your counter in inside the function, so each time the function is called, it gets set to 0. If you want a counter that is outside of the scope, and actually keeps a proper count, you will need to abstract it from the function.
If you want to keep it simple, even just moving clickCount above the function should work.
I do not know if it's an issue of scope
Yes, it is an issue of scope, more than one actually.
How?
As pointed out by #thesublimeobject, the counter is inside the function and hence gets reinitialized every time a click event occurs.
Even if you put the counter outside the function, you will still face another scope issue. In the else part of the function, you are manipulation a variable (newString) you initialized inside the if snippet. Since, the if snippet didn't run this time, it will throw the error undefined. (again a scope issue)
A fine approach would be:
take the counter and the defaultString outside the function. If the defaultString gets a value dynamically rather than what you showed in your code, extract its value on page load or any other event like change, etc. rather than passing it inside the function.
Do not assign a new string the result of your manipulation. Instead, assign it to defaultString. This way you probably won't need an if-else loop and a newLastChar to take care of newer results.
Manipulate the assignment to the element accordingly.
You can use Javascript closure functionality.
var scrollString = (function() {
var defaultString = "Learning to Code Javascript Rocks!";
return function() {
// convert the string into array, so that you can use the splice method
defaultString = defaultString.split('');
// get last element
var lastElm = defaultString.splice(defaultString.length - 1, defaultString.length)[0];
// insert last element at start
defaultString.splice(0, 0, lastElm);
// again join the string to make it string
defaultString = defaultString.join('');
document.getElementById('Result').innerHTML = defaultString;
return defaultString;
}
})();
Using this you don't need to declare any variable globally, or any counter element.
To understand Javascript Closures, please refer this:
http://www.w3schools.com/js/js_function_closures.asp
I have a dialog feature on an app I'm making the messages are output in html divs like this:
<div class="chat-message error">Message example here</div>
<div class="chat-message error">Message example here</div>
<div class="chat-message error">Latest message</div>
I want to check the last message in javascript and see if it's the same as the previous one if it is do nothing if not run my existing dialog code. New chat messages are stored in a variable called chatBoxMessage.
I think I need something like this -
oldMsg = $('.chat-message').html();
if (oldMsg == chatBoxMessage) {
//do nothing
} else {
dialog code
}
You can use the jquery last method :
oldMsg = $('.chat-message').last().html();
you can use jquery last and prev
var lastMessage = $('.chat-message').last();
var previousMessage = lastMessage.prev();
console.log(lastMessage.text() === previousMessage.text());
Your oldMsg variable holds an array of all the elements with the class chat-message. So a better meaningful name for this variable should be chatMsgs
var chatMsgs = $('.chat-message');
var msgsLen = chatMsgs.length;
Now your oldMsg would be.
var oldMsg = chatMsgs[msgsLen - 1].text(); // Remember array indexes are zero based
Or if you think that's too much array manipulation you can use the easier last() jQuery method (As pointed out by #Shai). What it does is return the last element from the array of elements. So,
var oldMsg = $('.chat-message').last().text();
Now happily do your conditioning..
if ( oldMsg === chatBoxMessage ) {
// do nothing
}
else {
// dialog code
}
I am trying to create clickable divs that will set a variable once they are clicked.
For example,
If my program had to do with playing with balls.
When a user inputs a name, and what kind of ball they want (lets say name= Johnny and Ball=BasketBall) and then clicks "Create a Ball", My program will create a div called "Ball0". The "Ball0" div will display Johnny's name. When a user Clicks on his name it will say "Johnny has a BasketBall.
Here is how I am trying to do this code
var ballRefrence = -1;
function createBall() {
ballRefrence +=1;
var myElement = document.createElement('div');
myElement.id = 'individualBall'+ballRefrence;
ballArea.appendChild(myElement);//ball area is where I want to list the divs
myElement.style.width = "550px";
myElement.innerHTML= userName+" has bought a ball!";
createEventListner();
}
function createEventListner() {
var iBall = document.getElementById("individualBall"+ballRefrence);
iball.addEventListener("click",showBall,false);
}
function playCaption() {
//I am not sure how to pull the individual up here.
//Since I am using the "BallRefrence"variable
//it will always be the last person clicked..
//(Basically I cannot say
//alert.(ballRefrence);
}
I guess what I am trying to say is this,
I have my "BallRefrence" that goes up by 1 each time.
I store all the items in an array. (so first person will go to index 0, second will go to index 1...ect)
I am having problems refrencing the element, because I am not sure how to pull the corrisponding numbe from the div.
Example:
After 3 clicks of "create ball" my html will look something like this.
<div id = "individualBall0></div>
<div id = "individualBall1></div>
<div id = "individualBall2></div>
Since each individual div will match up to the element in the array I want, How will tell my program
"When you click individualBall0, I want ball[0].."
or
"when you click indivdualBall2, I want ball[2]"
I hope this makes more sense.
One solution that doesn't really follow your updated requirements (but I believe does something simpler) is on JSFiddle. This stores the username and ball type in a local closure related to the event listener for that DIV. The code is fairly simple, and it removes some clutter from the global namespace, revealing only createBall:
var createBall = (function() {
var ballReference = -1;
var ballArea = document.getElementById('ballArea');
var showBall = function(userName, ballType) {
return function(event) {
alert(userName + ' has a ' + ballType);
};
};
return function() {
++ballReference;
var userName = document.getElementById('name').value;
var ballType = document.getElementById('ball').value;
var myElement = document.createElement('div');
myElement.id = 'individualBall'+ballReference;
ballArea.appendChild(myElement);
myElement.innerHTML= userName+" has bought a ball!";
myElement.addEventListener("click",showBall(userName, ballType),false);
};
}());
To perform your updated requirements, it should be pretty easy. Your event handler will run in the context of your element, so something like this:
this.id.substring('individualBall'.length) //=> '0', '1', etc
should return a string representing the index of the div. You can use that directly for indexing various arrays, or, if that makes you squeamish, turn it into an integer with parseInt, the Number constructor, or the unary + operator.
But note that the suggestions from Bergi, jfriend00, and RobG are all good. There are many good ways of going about this.
I am currently learning jQuery. I know that jQuery is a custom library for JavaScript.
I am doing some learning examples in a book that is only using JavaScript, and to further my learning experience, I am trying to make use of jQuery for anything that might be more efficient.
So, I have this code:
function addLetter(foo) {
$(foo).unbind('click');
var tileLetter = $(foo).attr('class').split(' ');
var letter = tileLetter[2].charAt(1);
if (document.getElementById('currentWord').childNodes.length > 0) {
$('#currentWord p').append(letter);
} else {
var p = document.createElement('p');
var txt = document.createTextNode(letter);
p.appendChild(txt);
$('#currentWord').append(p);
}
}
Question #1:
If I change document.getElementById('currentWord').childNodes.length to $('#currentWord').childNodes.length it doesn't work. I thought the jQuery selector was the same thing as the JS document.getElementById as that it brought me back the DOM element. If that was the case, it'd make sense to be able to use the .childNodes.length functions on it; but it doesn't work. I guess it's not the same thing?
Question #2:
The code is textbook code. I have added all the jQuery that there is in it. My jQuery knowlede is limited, is there a more efficient way to execute the function?
The function's purpose:
This function is supposed to create a p element and fill it with a Text Node if it's the first time it's run. If the p element has already been created, it simply appends characters into it.
This is a word generating game, so you click on a letter and it gets added to a 'currentWord' div. The tile's letter is embedded in the 3rd css class, hence the attr splitting.
Thanks!
document.getElementById('currentWord')
returns a DOM object whereas $('#currentWord') returns a DOM object wrapped inside a jQuery object.
To get the plain DOM object you can do
$('#currentWord').get(0)
So
$('#currentWord').get(0).childNodes.length
should work.
Question #1:
jQuery returns a jQuery object. To return it to a regular javascript object use $(object)[0] and you can then treat it as a plain javascript (or DOM) object.
Question #2:
The efficiency looks good to me. Although you might want to use spans instead of p elements.
I guess one thing you could do (even though yours looks to run very fast) is cache the dom element:
function addLetter(foo) {
$(foo).unbind('click');
var tileLetter = $(foo).attr('class').split(' ');
var letter = tileLetter[2].charAt(1);
var currentWord = document.getElementById('currentWord');
if (currentWord.childNodes.length > 0) {
$(currentWord).find('p').append(letter);
} else {
var p = document.createElement('p');
p.innerHTML = letter;
currentWord.appendChild(p);
}
}
Calls to the jQuery() function ($()) return a jQuery object containing the matching elements, not the elements themselves.
Calling $('#some-id') will, then, return a jQuery object that contains the element that would be selected by doing document.getElementById('some-id'). In order to access that element directly, you can get it out of that jQuery object, using either the .get() function or an array index syntax: $('#some-id')[0] (it's 0-indexed).
I think you can replace all of this with a call to the text function.
function addLetter(foo) {
$(foo).unbind('click');
var tileLetter = $(foo).attr('class').split(' ');
var letter = tileLetter[2].charAt(1);
var currentWordP = $('#currentWord p');
if (currentWordP.size() > 0) {
currentWordP.text(currentWordP.text() + letter);
} else {
$('#currentWord').append("<p>" + letter + "</p>");
}
}
1: Use $.get(0) or $[0] to get the DOM element. e.x. $('#currentWord')[0].childNodes.length.
2: Try this:
function addLetter(foo) {
$(foo).unbind('click');
var tileLetter = $(foo).attr('class').split(' ');
var letter = tileLetter[2].charAt(1);
if ($('#currentWord p').length > 0) {
$('#currentWord p').append(letter);
} else {
$('#currentWord').append(
$('<p />', { text: letter })
);
}
}
Question #1:
document.getElementById returns DOM object. more
childNodes.length is property of Node object which is returned by document.getElementById.
jQuery selector returns jQuery object more. You can get DOM object from jQuery object using .get
$('#IDselector').get(0) = document.getElementById('IDselector')
Question #2:
function addLetter(foo) {
$(foo).unbind('click');
var tileLetter = $(foo).attr('class').split(' ');
var letter = tileLetter[2].charAt(1);
if ($('currentWord p').length > 0) {
$('#currentWord p').append(letter);
} else {
var p = $('<p />').text(letter);
$('#currentWord').append(p);
}
}
I have a dynamic table populated from an array.
When building the table I have the following inside of a loop:
var tdRecord = trRecord.insertCell(trRow.cells.length);
var tdRecordId = dataArray[j][0];
tdRecord.onclick = function() { alert(tdRecordId); }
The problem is that alert will only alert the last set tdRecordId in the array. If I click on any of the other td rows they all alert the same number.
Anyone know how I can fix this?
This should work:
(function( id ) {
tdRecord.onclick = function() {
alert( id );
};
}( tdRecordID ));
You seem to be running your code inside a loop. In that case, all click handlers will point to the same tdRecordId value. If you want to capture the value of the current iteration, you have to use a function wrapper which will do that for you.
tdRecord.onclick = function () { alert('123'); };
You could use jQuery's data feature: http://jsfiddle.net/zRXS6/.
$(function(){
var number = 1;
var div1 = $('<div>a</div>');
div1.data('number', number);
div1.click(function() {window.alert($(this).data('number'))});
number = 2;
var div2 = $('<div>b</div>');
div2.data('number', number);
div2.click(function() {window.alert($(this).data('number'))});
$('body').append(div1).append(div2);
});
tdRecord.onclick = "alert(" + tdRecordId + ")";
Set it as a literal, rather then a dynamic. :)
In what you're doing, it will always refer to the variable, rather then the current value.
So as the variable changes, what the function alerts will change.
In this, it actually inserts the value, rather then the variable itself, so it will stay the same instead of changing.