Javascript Bug: set audio object controls attribute True = = False - javascript

I'm rather new to this and don't know exactly how to report a bug, but I first want to confirm it's a bug and then go on from there. But here's what I'm finding:
1) When creating an audio object controls attribute, the controls attribute will respond to a string as if it's a boolean.
For Instance:
<button onclick="example()">Try this</button>
<script>
function example() {
var aud = document.createElement("AUDIO");
aud.setAttribute("src","example.mp3");
aud.setAttribute("controls", "controls");
}
Okay, we've put controls in there because it makes controls equal controls:
Thing is, you can put any old string in there and it works just fine -- apple, banana, pear, anything.
2) Isn't the value suppose to be a boolean? Well when you try a boolean, false for example, you still get true. (False == True) It works just as if you typed in true.
...and if you put anything else other than true or false (just type anything other than an integer, string, or true or false value), you get false (or it just doesn't work).
Everything equals true and a non-string, non-integer equals false (or just doesn't work).
Finally, you can even try setting the controls attribute on an accessed audio element:
var aud = document.getElementById("idhere");
function accessAudioElement() {
aud.controls = false;
}
At least here the true and false actually work as true and false, but once again, any string or integer will also get you true and any non-string/non-integer will break the code.
Can somebody help me out here because I don't think this is suppose to work this way... and if does, what's the point of using a boolean value when most anything else will work?
Of course I'm still learning, so maybe this is not a bug, maybe for some reason this is suppose to work this way, but if that's the case would someone please share the logic behind this with me.
I'm just not understanding.
Thanks Magic

This is an extended answer of what #nnnnnn suggested in the comments.
aud.controls = false; doesn't set the attribute, it sets the property.
You need to use setAttribute() method to add the specified attribute to an element.
aud.setAttribute("controls", "controls");
And use removeAttribute() method removes the specified attribute from an element.
aud.removeAttribute("controls");
For more reading on these methods, have a look at the hyperlinks attached.
Element.setAttribute()
Element.removeAttribute()
When to use setAttribute vs .attribute= in JavaScript?
HTML - attributes vs properties

You might want to read/search more about Javascript Truthy $ Falsey. It is very important.
https://j11y.io/javascript/truthy-falsey/

Related

Javascript: localStorage paralyzes if-statements?

Made a boolean variable "disableReplaceDate", used in if-statements. Have to save the variable somehow because the page reloads and I need to use it to "check a status" sort of, so it doesn't return to default every time the page reloads.
Then, to save myself a lot of time and trouble, because I can't send them in the URL as parameters(it's occupied already by a complicated java file which manipulates it all and I'm no good at java at all), I decided to use window.localStorage setItem, getItem and removeItem etc., so basically
var disableReplaceDate = false;
window.localStorage.setItem("dRD", false);
disableReplaceDate = window.localStorage.getItem("dRD");
But now the if-statement, which looked as follows:
if(disableReplaceDate == true){/*do some stuff*/}
didn't work anymore! But then when I changed it to
if(disableReplaceDate){/*do some stuff*/}
It starts working suddenly.
And if that wasn't uncanny enough, it won't do this for all if-statements using the variable, I tried changing them to (!disableReplaceDate) and such, but it doesn't make them work.
Why is this? And how do I solve it?
localStorage only stores strings. And "false" evaluates as true in a context where a boolean is needed (for example a if statement).
You should change
disableReplaceDate = window.localStorage.getItem("dRD");
to
disableReplaceDate = window.localStorage.getItem("dRD") === "true";
I think because the type of your variable is "string" see this
typeof(disableReplaceDate)
The output will be string
I think you need to test this way if(disableReplaceDate === "false")

What does the jQuery function $('#myelement').is('*') do?

What does the following code do:
$('#myelement').is('*')
What does the asterisk signify? Since there is only one element, #myelement, I can't understand the point of using is(), which checks if an element matches a set of elements?
This is some seriously existential JavaScript.
$('#myelement').is('*')
It will fail whenever #myelement doesn't exist, and return true otherwise.
Basically check to see if an element exists or not. Not the best method...
is checks the element fits the criteria. In this case, "*" means all elements.
So, it simply returns true if the previous selector returns anything.
Take a look here for an example: http://jsfiddle.net/b7DwB/
http://api.jquery.com/is/
Pretty much what it does well from my understanding of it at least, and how I tend to use it. Is return true or false on whatever its called on.
Example I have a checkbox that I want to make sure is checked before I submit my form via AJAX I would do something like
if( $('input#tosCheck').is(':checked') ){
/*its checked submit form*/
}else{
alert('Error');
}
All in all the link to the API from jQuery better describes it then I ever could, but I wanted to at least share an example of use to help you gauge some idea.
Can't say I've ever seen that jQuery code used before, but it seems to be a poor way of checking for the existence of an element. Since * is the universal selector, the expression in question will always return true if #myelement exists, otherwise it will return false.
I say this is a "poor" way of checking the existence of an element because you can simply check the length of the jQuery object instead:
$('#myelement').length > 0
I haven't done any testing, but I assume the above is faster since it doesn't have the overhead of the is() function call.

Setting a property via property or setAttribute

Is one of these more preferable than the other? Why? How about performance--if these are being called thousands of times?
A) element.setAttribute("disabled", true);
B) element.disabled = true;
They both seem to disable an input[text] element in FF 4.
In general…
Use properties. For a long time (until version 7 or 8 IIRC) Internet Explorer had a seriously broken implementation of setAttribute that would set the property not the attribute (the classic point of failure was class since there is no class property (it is className).
In this case in particular… element.setAttribute("disabled", true); is wrong. It should be element.setAttribute("disabled", "disabled");
element.setAttribute("disabled", some_bool) doesn't work like you'd think it will. In particular, standardswise, disabled is what's known as a boolean attribute; its very presence, regardless of its value, makes it true. disabled="", disabled="disabled", disabled="true" and even disabled="false"(!!!) all mean the same thing in most browsers. (Although the last two are actually invalid HTML, most browsers will consider them equivalent to disabled="disabled" for truth purposes. Including every one of the Big Four.) You set a boolean attribute to true by setting a value -- any value, even if it's falsy -- and you set it to false by removing the attribute entirely.
If you care about the actual string value of the attribute (which in this case you shouldn't), and particularly if the attribute isn't already exposed via the DOM (that is, it doesn't have a corresponding property), then use (get/set)Attribute. In most cases (particularly if you care about how it affects the element, like in this case where you're trying to disable an element), use the DOM property.
IE needs some attributes to be set with setAttribute, but not all. I don't have a list though, you just have to check if it works or not. Also, using setAttribute will put the attribute in the DOM, so it can be shown when doing view source.
Only one tip: element.setAttribute('class',xxx) doesnt works in some versions of IE.
Prefer element.className = xxx instead

Why doesn't IE7 think these two strings are equal?

I have an event handler that will remove an element from a list of the corresponding checkbox is unchecked. In the handler for the click event for the checkbox, first I copy the value of the label for that checkbox:
var label = $(this).next().html();
Then, I iterate over the list items and compare each of them to that label:
$("#sortable li").each(function() {
if ($(this).html() === label) {
$(this).remove();
}
});
In Internet Explorer 8 and in Firefox, this works exactly as I'd expect. In Internet Explorer 7, it does not. The condition in the "if" statement is never true. What am I missing here?
By request, the strings being compared are, "Charge" and "Charge" in one case.
Try alert(label) and alert($(this).html()) to see exactly what's being compared.
I'm not seeing any reason to use strict comparison (===), and you could conceivably benefit from using ordinary comparison (==).
As a method of doing what you're saying you want to do, this all seems pretty crazy. I'd always recommend identifying corresponding DOM elements by something more designed-for-the-purpose than their HTML contents, such as an ID.
Why don't you use the Script Debugger and see exactly why that comparison is false? Just set a breakpoint in the if and watch the variables.
The IE8 internal script debugger will help you, just switch to compatibility mode to run the script in the IE7 javascript runtime
Have you tried debugging it? Use alert to see what the two values hold, check that the function is actually called in IE7 and check that they have the same type.
Not an answer to your direct question, but here's another method that uses jQuery's data method to set and read a flag directly on the element:
$(this).next().data("toRemove", true);
//...
$("#sortable li").each(function() {
if ($(this).data("toRemove")) {
$(this).remove();
}
});
Of course, if you were manipulating label at any point then this wouldn't be what you want. I just mention this because .data() is a very useful jQuery feature that I haven't heard much about. I didn't even know about it until a week ago.

jQuery 1.3 - Issue with Setting an Attribute Value

This is my first stackoverflow question, so try to be nice. ;-D
My issue is this, I am refactoring some existing javascript code and using jQuery to do it. In several places I've come across javascript code similar to the following:
// some js code working with the customAttribute value
javascriptElementObject.customAttribue = void(0);
The javascriptElementObject is now a jQuery object and I have been attempting to use the following code to do the same thing:
// some js code working with the customAttribute value
javascriptElementObject.attr("customAttribute", void(0));
However, this does not seem to be doing anything. The following code works however:
javascriptElementObject.get(0).customAttribute = void(0);
I'm aware of jQuery's removeAttr() function, but have not used it so far because I don't know if it's equivalent to setting the attribute value to void(0).
So I guess that really means I have 2 questions:
Why doesn't the first jQuery version work?
Are .get(0).customAttribue = void(0); and .removeAttr("customAttribute); equivalent?
Thanks.
jQuery likes to overload its methods so:
obj.attr( name ) //retrieves the attribute value
obj.attr( name, value ) //sets the attribute
obj.attr( name, void(0) ) == obj.attr( name, null ) == obj.attr( name ) //i.e retrieving the attribute
You might want to try the following if you want to set an empty attribute
obj.attr( name, '' )
This will also apply to other methods jQuery.html() for example
What are you trying to accomplish?
If the goal is to remove the value in the name/value pair, you might as well just remove the attribute entirely. I'm not aware of any intrinsic value in maintaining an attribute that has no value; in less standards-compliant browsers it may even cause a problem.
In general, the syntax of $(selector).attr(name, value) and $(selector).removeAttr(name) work very well (at least I've never seen it fail.)
If you're trying to use void(0) to keep A HREFs from firing you'd be better off using a "return false" as the click event on those A tags.
The only way to work with custom attributes via jQuery objects is:
obj.get(0).myCustomAttr = 'some value';
That is because jQuery's attr() method will not work with custom attributes (except while applied on a XML-document).
Note also that meouw's answer regarding jQuery overloading functions is not precisely correct, because jQuery checks for the parameters passed to it in such a manner that:
jQuery.funcname(param)
and
jQuery.funcname(param, null)
differ, becacuse null !== undefined. For example:
var params_test = function(a) {
if (a === undefined) {
return 'called with no parameters';
} else {
return 'called with one parameter: ' + a;
}
};
params_test(); // results in 'called with no parameters'
params_test(null); // results in 'called with one parameter: null'
Uhmm, try this:
javascriptElementObject.attr("customAttribute", void(0));
var _void = javascriptElementObject.attr("customAttribute");
alert(_void);

Categories

Resources