For a reason I can't Identify, this isn't being successfully called, I've tried everything I can think of, but nothing seems to get this to work, it has no errors.
<img id="risk" src="assets/R0.png" width="100" height="150" style="border: dotted;"><br>
<button id="ContinueBtn" onclick="Continue()">Continue</button>
if (document.getElementById("risk").src == "assets/R0.png"){
document.getElementById("risk").src = "assets/R1.png";
}
else if (document.getElementById("risk").src == "assets/R1.png"){
document.getElementById("risk").src = "assets/R2.png";
}
else if (document.getElementById("risk").src == "assets/R2.png"){
document.getElementById("risk").src = "assets/RF.png";
document.getElementById("happiness").src = "assets/PF.png";
document.getElementById("main").src = "assets/fired.png";
alert("Debug")
var Cont = document.getElementById("ContinueBtn");
Cont.parentNode.removeChild(Cont);
}
When I add an else statement to it, it by passes the if and elseif's, making it seem like it is not finding anything for "risk",
else{
alert("An error has occured! Try refreshing your page.")
}
Short answer:
When you test the .src property in JS, some browsers report the full path of the image even when your original markup only specified a relative path. Which means your == comparison will fail.
Long answer:
Assuming that block of code is called after the elements have been created, I think you'll find that the problem is that the src you set in your html is not the same as what is reported when you test the .src property. If your source code sets a relative path for the src you may find the .src property value reported by the browser is actually the full path. So, e.g.:
<img src="assets/R0.png">
...and then:
console.log(document.getElementById("risk").src);
...will log "http://www.yourdomainhere.com/fullpath/assets/R0.png"
Which of course won't be equal when you compare with ==. Obviously you can easily test this by adding a console.log() statement just before the first if (or use an alert() if you must). Whenever you find an if statement isn't doing what you expect the first thing to try is adding a console.log() of the variables involved in the expression so that you can be sure they have the values you think they do.
If that is what's happening, then you obviously just need to use string functions to extract the last path of the path. E.g.:
var imgEl = document.getElementById("risk"),
imgSrc = imgEl.src.split("/").pop();
if (imgSrc == "R0.png"){
imgEl.src = "assets/R1.png";
} else if (imgSrc == "R1.png") {
imgEl.src = "assets/R2.png";
}
// etc.
The code imgEl.src.split("/").pop() that I've used takes the full path and uses .split() to create an array with all of the pieces between the forward slashes and then .pop() to take the last "piece", i.e. the last array element.
(I've also introduced a variable imgEl to reference your img element, because that's much neater and more efficient than repeatedly calling document.getElementById() for the same element.
Try using RegExp:
var risk = document.getElementById("risk");
if (risk.src.match("assets/R0.png")){
risk.src = "assets/R1.png";
} else if(condition) {
...
} else {
...
}
Related
I know there is many questions like this asked, but I have been searching for hours and can't find any answers. I have this method, which takes in a parameter, which should be ID of two selects. Using this parameter, I want to determine which select is used and execute the if statement, but to no avail. When I run it, it shows no errors in console in Chrome and it does nothing. Can anyone shed some light on it, this is the method in one export class:
static styleCircle(select) {
if(this.select === ELEMENTS.ELEMENT_COLOR_SELECT) {
var getColor = ELEMENTS.ELEMENT_COLOR_SELECT;
var colorValue = getColor.options[getColor.selectedIndex].value;
ELEMENTS.ELEMENT_STYLE_CIRCLE.style.backgroundColor = colorValue;
} else if(select == ELEMENTS.ELEMENT_BORDER_SELECT) {
var getRadius = ELEMENTS.ELEMENT_BORDER_SELECT;
var radiusValue = getRadius.options[getRadius.selectedIndex].value;
ELEMENTS.ELEMENT_STYLE_CIRCLE.style.borderRadius = radiusValue;
}
}
This is it being called in another class, on two select elements, and the class is imported at the top of the file:
ELEMENTS.ELEMENT_COLOR_SELECT.onchange = Script.styleCircle(this);
ELEMENTS.ELEMENT_BORDER_SELECT.onchange = Script.styleCircle(this);
ELEMENTS is a file with constants, which are just being used to get ID's from the HTML file. I used other methods like this, with onclick events, but none had parameters, and now I'm stuck here. Thanks in advance.
You don't want to call the functions right now but instead you probably want to pass functions. Through that you can access the proper this and pass it to styleCircle:
ELEMENTS.ELEMENT_COLOR_SELECT.onchange = function() {
Script.styleCircle(this);
};
ELEMENTS.ELEMENT_BORDER_SELECT.onchange = function() {
Script.styleCircle(this);
};
Additionally this.select is probably causing you troubles as window.select is undefined.
First step would be to try debugging and ensure select is equivalent to either of those constants. Make sure you have full branching coverage in your debugging. That would mean start by adding an else statement to that if/else if statement - it's possible that your select is not equal to either constant and so neither branch is run.
I am new on this website, and I am also new at Javascript.
What I would do is get a value from a link, eg:
http://bricks.couponmicrosite.net/JavaBricksWeb/LandingPage.aspx?O=107905&C=MF&CPT=qwbc74g7HdLtKVVQ1oNe&P=test&tqnm=td3ffdn764156741
I need to take this value: O=107905, if it is only one code I need to run a file (file A),
if it look like this: O=107905~107906, then I need to run a different file (file B).
What I thought is create a function with javascript where if it is (~) is missing, then will be used the file A, if there is one or more than one of (~) then the file B will start to work.
Many thanks in advance!
Well. We really do encourage you to provide your own code first before providing solutions, but this is a fairly simple problem in javascript. Here's my take on it.
The first problem you have to solve is actually getting the query string parameters in a meaningful format. Here I create an object that uses the query string keys as the object keys (IE 9+ only because of the forEach)
var tmpObject = {}
location.search.substr(1).split('&').forEach(function(item){
var o = item.split('=');
tmpObject[o.shift()] = o.shift();
});
Then it's just a matter of making sure the query string contained the target object (in this case "O") and determine if there is more than one.
if(tmpObject.hasOwnProperty('O') && tmpObject.O.split('~').length > 1) {
console.log('return multiple files');
} else {
console.log('return one file');
}
Try this
var url = "http://bricks.couponmicrosite.net/JavaBricksWeb/LandingPage.aspx?O=107905&C=MF&CPT=qwbc74g7HdLtKVVQ1oNe&P=test&tqnm=td3ffdn764156741";
var search = url.substring(url.indexOf("?")+1);
var map={};
search.forEach(function(val){var items=val.split("="); map[items[0]]=items[1];});
if (map["O"].indexOf("~") != -1)
{
//O value has ~ in it
}
else
{
//O has no ~ in it
}
Possible solution to get the paramter would be there : How to get the value from the GET parameters?
Once you have the parameter value, you can for sure look if you find '~' with String.prototype.indexOf.
String.prototype.indexOf returns the position of the string in the other string. If not found, it will return -1.
I am getting this error message in my Javascript.
Unable to get property 'style' of undefined or null reference
document.getElementById('BS2').style.display='block';
What is going on it that sometimes the Element ID is not showing. Is there a way to check if the element is there then do this else, go to the next line of code?
function showb() {
if(document.getElementById('BS1').style.display=='none') {
document.getElementById('BS1').style.display='block';
document.getElementById('BS2').style.display='block';
document.getElementById('BS3').style.display='block';
document.getElementById('BS4').style.display='block';
}
return false;
}
Sometimes the BS1 is showing, BS3 is Showing and BS4... etc.
document.getElementById() returns an object just like anything else. You can assign it to a variable and check the null-ness of the variable:
var bs1 = document.getElementById('BS1');
if (bs1) {
.. do stuff if bs1 is present
} else {
.. do stuff if bs1 is not there
}
AS pointy said in his comment, you should chekc whether there is an element with the desired ID before trying to read its properties. You could use a piece of code like this:
var element = document.getElementById('BS2'); // or any other ID
if (element) { // if no element is found, this evaluates as a logical false.
element.style.display='block';
}
Getting the element in a variable also has the advantage that your code becomes more readable. And since you use this multiple times, you could create a function to encapsulate that logic. Good luck!
Well if the property style hasn't been modified it means that it is just ("")
function showb() {
if(document.getElementById('BS1').style.display) {
document.getElementById('BS1').style.display='block';
document.getElementById('BS2').style.display='block';
document.getElementById('BS3').style.display='block';
document.getElementById('BS4').style.display='block';
}
return false;
}
it is going to be solved just like that because ("") is a falsy value
i'm implementing a charcounter in the UI, so a user can see how many characters are left for input.
To count, i use this simple function:
function typerCount(source, layerID)
{
outPanel = GetElementByID(layerID);
outPanel.innerHTML = source.value.length.toString();
}
source contains the field which values we want to meassure
layerID contains the element ID of the object we want to put the result in (a span or div)
outPanel is just a temporary var
If i activate this function, while typing the machine really slows down and i can see that FF is using one core at 100%. you can't write fluently because it hangs after each block of few letters.
The problem, it seems, may be the value.length() function call in the second line?
Regards
I can't tell you why it's that slow, there's just not enough code in your example to determine that. If you want to count characters in a textarea and limit input to n characters, check this jsfiddle. It's fast enough to type without obstruction.
It could be having problems with outPanel. Every time you call that function, it will look up that DOM node. If you are targeting the same DOM node, that's very expensive for the browser if it's doing that every single time you type a character.
Also, this is too verbose:
source.value.length.toString();
This is sufficient:
source.value.length;
JavaScript is dynamic. It doesn't need the conversion to a string.
I doubt your problem is with the use of innerHTML or getElementById().
I would try to isolate the problem by removing parts of the function and seeing how the cpu is used. For instance, try it all these ways:
var len;
function typerCount(source, layerID)
{
len = source.value.length;
}
function typerCount(source, layerID)
{
len = source.value.length.toString();
}
function typerCount(source, layerID)
{
outPanel = GetElementByID(layerID);
outPanel.innerHTML = "test";
}
As artyom.stv mentioned in the comments, cache the result of your GetElementByID call. Also, as a side note, what is GetElementByID doing? Is it doing anything else other than calling document.getElementById?
How would you cache this you say?
var outPanelsById = {};
function getOutPanelById(id) {
var panel = outPanelsById[id];
if (!panel) {
panel = document.getElementById(id);
outPanelsById[id] = panel;
}
return panel;
};
function typerCount(source, layerId) {
var panel = getOutPanelById(layerId);
panel.innerHTML = source.value.length.toString();
};
I'm thinking there has to be something else going on though, as even getElementById calls are extremely fast in FF.
Also, what is "source"? Is it a DOMElement? Or is it something else?
So in jQuery, I have a global variable "currentSubNav" that stores a current visible element. The following code executes on "mouseenter".
I need it to get store element's ID, check to see if there was one. If there wasn't, set the new visible element to the default.
$('#mainMenu a').mouseenter(function() {
var newName = $(this).attr("id");
if(newName == ''){
var newName = "default";
}
Then it checks to see if the new element matches the current one. If so, it returns. If not, it performs the animations to bring in the new one.
if(newName == currentSubNav){
return;
}else{
$("div[name=" + currentSubNav + "]").animate({"left": "+=600px", "opacity": "toggle"}, "slow");
$("div[name=" + newName + "]").css({"margin-top": "0"});
$("div[name=" + newName + "]").fadeIn(2000);
$("div[name=" + currentSubNav + "]").animate({"left": "-=600px"}, 0);
currentSubNav = newName;
return;
}
});
I'm using Chrome at the moment, and according to the dev tools that isn't what happens.
Problem #1
"$(this).attr("id");" isn't returning undefined as the documentation claims. It seems to be returning "". BUT, when I have the if statement as I do above, it skips over the statement entirely. I set a breakpoint, but it never pauses execuation, so the statement is never evaluated.
Problem #2
After the animations occur, instead of using the return at the end of the statements it goes back and uses the return for the "newName == currentSubNav" if statement. I guess that not a big deal, but it's not the intended behavior.
I'm fairly new to JavaScript, and it appears I'm missing something about how JavaScript works. But I can't find what anywhere. Any help?
EDIT: It seems to be working in FireFox, (though jQuery isn't returning undefined, it is returning ''). So this is a Chrome problem at the moment.
I would change the assignment of "newName" as follows:
var newName = $(this).attr('id') || 'default';
That's more idiomatic, and it'll handle cases where you're getting null instead of an empty string, or vice-versa, and when it doesn't really matter anyway.
I suspect that some of the "problems" you're seeing are more a matter of the Chrome debugger than the actual way that the code is running.