We can do this,
var someDiv1 = document.createElement('div');
someDiv1.setAttribute('class', 'someClass');
Because of the above code, we naturally tempt to think that below code may work also.
var someDiv2 = document.createElement('div').setAttribute('class', 'someClass');
Actually it works. But the problem is when we try to do this
document.querySelector(".container").appendChild(someDiv2);
It gives an error!!!
Uncaught TypeError: Failed to execute 'appendChild' on 'Node':
parameter 1 is not of type 'Node'.
at HTMLImageElement.
Even though the second code block is working it is useless. Because we can't show the created "div" element.
What is the reason?
The term you're looking for is method chaining.
Each method returns an object, allowing the calls to be chained together in a single statement without requiring variables to store the intermediate results.
Which is NOT the case here.
For this to effectively work, each of the function should return an instance of the created object, which is not the case. .createElement() will return an HTMLDivElement, then you call .setAttribute on the object return by createElement but .setAttribute doesn't return anything. What is assigned to someDiv2 is what is returned by .setAttribute, so nothing. If it would have returned the HTMLDivElement, you could have done a one-liner.
The first code block of the question gives a "div" element as the output. If you run below code
console.log(someDiv1);
you can see the output of someDiv1 variable like this.
<div class="test"></div>
If you execute the above code before the second line of the first code block of the question you will get
<div></div>
as the output. Because it hasn't added the class attribute to the created "div" element yet. And by executing the second line it will add the class attribute to that "div" element.
But if you do the same thing to the someDiv2 variable the output will be undefined. That means the second code block of the question has no output. That's why it gives an error when trying to use appendChild(). But Why ????
The reason is the latter part of the second code block.
.setAttribute('class', 'someClass');
It sets the class attribute to the created "div" element. But doesn't output anything instead it just does something. Even though the former part of the second code block gives an output, the latter part is the one which gives the final output for being assigned to the variable. Since it doesn't give any output there is no value for someDiv2 variable.
But actually that second code block is executed without any problem. The only problem is the variable has no value. So it wouldn't give any errors until we are going to use the someDiv2 variable in somewhere. But the problem is to show the created "div" element we definitely have to use the someDiv2 variable.
So concatenating "setAttribute()" and "createElement()" is useless.
So what if do this instead of assigning to a variable.
document.querySelector(".container").appendChild(document.createElement('div').setAttribute('class', 'someClass');
NO. This would not work as well. You can understand it, since the concatenation of setAttribute() and createElement() doesn't give exact output, appendChild() function has no input too. So it gives errors.
This is same for other functions like setAttribute() and createElement(). Like if you try to concatenate,
getElementsByClassName() and setAttribute()
createElement() and classList.add()
createElement() and className
getElementById() and classList.add()
getElementsByClassName() and className()
those will definitely be executed without any problem but no exact output. Actually those are some examples. There are many combinations like that.
Yes. we usually use that kind of concatenations exactly. But we have to bear in mind that it these kind of concatenations doesn't give any output. Specially if we use "createElement()" it will matter a lot. Because we have to show the output in somewhere.
Related
This is original code:
h1tag= document.getElementById("myHeading");
h1tag.addEventListener("mouseover", ()=>{h1tag.style.backgroundColor="blue"});
After combining:
h1tag= document.getElementById("myHeading").addEventListener("mouseover", ()=>{h1tag.style.backgroundColor="blue"});
What is the reason behind this?
The problem with this line :
h1tag= document.getElementById("myHeading").addEventListener("mouseover", ()=>{h1tag.style.backgroundColor="blue"});
Is that the statement is evaluated from left to right, so the last method that will be called is addEventListener, so in other words you are trying to store the returned result from addEventListener in your h1tag variable while addEventListener doesn't have a return type so it will return undefined.
To expand on the previous answers, the key issue here is that h1tag is not defined (because addEventListener doesn't return a value) and you are trying to change it's properties.
Fortunately, javascript provides a way to access the element that an event is called on, through an argument passed to the event function.
Try running
document.getElementsById("myHeading")
.addEventListener("mouseover", (e)=>{e.target.style.backgroundColor = "blue"})
h1tag is not defined in your second attempt.
document.getElementById("myHeading").addEventListener("mouseover", (e)=>{e.currentTarget.style.backgroundColor="blue"});
if you still want to kep a reference to the element:
(h1tag=document.getElementById("myHeading")).addEventListener("mouseover", (e)=>{e.currentTarget.style.backgroundColor="blue"});
I am investigating a bug in some software that has uses an in-house developed Javascript library. The error that I am dealing with appears on the line below:
GetVal1("dispLetter")(GetVal1("dispLetter").selectedIndex).value + '~' + (bFinal == true ? '1' : '0');
I initially wasn't sure if this line was even valid, however, according to source control this line was around since this file was created while the error is relatively recent. When I debugged I discovered that this line throws an error that says GetVal1(...) is not a function. I double checked to confirm that the Javascript file with the function definition is included, the header looks like this:
function GetVal1(strHTMLId)
So, I guess my question is, is this line valid Javascript code? Is there anything you can tell that could be throwing the error? Thank you.
GetVal1("dispLetter")(GetVal1("dispLetter").selectedIndex).value + ...
does the following:
calls GetVal1 with the argument "dispLetter".
calls GetVal1 with the argument "dispLetter", again.
retrieves the property selectedIndex of the return value of the second invocation of GetVal1
Calls the return value of the first invocation of GetVal1, with one argument, the value of selectedIndex. This fails your case, and complains the value is not callable.
The return value's value property is dereferenced. String concatenation follows.
In other words, this code seems to assume that the first invocation of GetVal1("dispLetter") returns a function (which is unusual), and the second invocation returns an object with the property selectedIndex (which is unusual, given the first invocation returns a function).
Some ideas:
If there used to be a new keyword before the line. Then the first invocation would be a constructor call. It is unexpected that a constructor call would return a function while a non-constructor call would not, though.
If there used to be a trailing period on the previous line (or is now), GetVal1 would refer (or refers now) to a property of some object. I smell a violation of naming conventions, though, if GetVal1 is meant to be an object property.
The global GetVal1 is (or recently ceased to be) shadowed by a function of the same name. Once again, I smell a violation of naming conventions.
Most likely, GetVal1 itself has changed. Verify GetVal1 can return a function when given this string as the first argument.
Perhaps the state bound to the GetVal1 function has changed (say, one more extra call somewhere before the code. This most likely a design error, though, if this function returns a different type of object on each invocation with the same arguments. But then again, there likely is a design error or naming violation somewhere in the code.
Another plausible explanation is that this line was there from the beginning, but it was never reached before. In this case, it could have been wrong the whole time.
I'm using jQuery for a dynamic content behavior on a website. I've got an error:
TypeError: $("#id").attr("src",
thisContent.attr("data-attr")).show is not a function
Firstly I thought that it was browser related, but it turns out that it isn't. The error is on this line:
$('#id').attr('src', thisContent.attr('data-attr')).show();
If the second argument of .attr() is undefined the getter will be invoked.
Seems like the getter is invoked instead of the setter.
Getter:
$(...).attr(String) // returns String which has no method .show()
Setter:
$(...).attr(String, String) // returns jQuery object, which has method .show()
thisContent.attr('data-attr') might return undefined in some cases, and therefor the getter gets invoked instead of the desired setter method.
Try the following.
Rename your data-attr to something else.
see if data-attr exists inside thisContect.attr.
Log the following line and go to the Console. There you will see the data-attr does not exist or is at the wrong place.
console.log(thisContent);
Random question, but to be sure...
Are you accessing jQuery via their CDN?
If you are, do both machines load the jQuery code in ok? Both can see the CDN with no issues (both connected to the internet)? and other bits of jQuery code are working?
It's very rare that a browser would have a difference in the way it renders/handles JS as it is such a well established language. So my suggestion is, rather than being a browser based issue, it's something outside of your code.
Just an idea..
Does anyone know why this would not work in IE7/8?
drop_area = $('div#drop_area');
It works perfectly in IE9, FF2/3, and Chrome. Internet Explorer 7/8 gives the following error:
SCRIPT438: Object doesn't support this property or method
Edit: This is the HTML that goes with my javascript:
http://pastebin.com/nwxx8RzW
IE has a weird behaviour to register some properties in global scope. Elements with an given ID may be accessed simply by using the ID.
So you have a element with the ID "drop_area", it's accessible in IE by using this ID, try:
alert(drop_area.tagName)
..to check it.(should give "DIV")
So what happens: You try to assign something else to this element when using drop_area = $('div#drop_area'); , but this is an invalid operation on an DOMElement.
So use the var-keyword to clarify that you want to create a variable
var drop_area = $('div#drop_area');
or in the case that you have to create a global variable inside a function, assign the variable to the global context:
window['drop_area'] = $('div#drop_area');
The code you've shown on pastebin has numerous global variable issues. In other words, you are coding assuming that variables you are declaring are local in scope, whereas in reality they turn out to be global. Examples include set, box_handle, elements, i, id, drop_area, element, row, image_id, etc. All of your functions are global in scope as well, when they can easily be encapsulated in an other function.
Now I don't know if there's some subtle interactions going on, whether some code has hammering (global) data set by other code, but it certainly seems as if something is getting overwritten and hence methods and properties are disappearing. I would start by going through the code and adding var to local variables. Next I'd be encapsulating most of this code in an anonymous autoexecuting function.
Usually that error shows, that you use jQuery on a website that also uses Prototype. That's why get an error (which is actually throw by Prototype). The other possibility is, that you try to call the code, before the jQuery lib was included into the HTML.
To make sure it's not my first guess, add this code to your JS code:
$.noConflict();
Therefore it is important that Prototype is included into the HTML, before jQuery is included: http://api.jquery.com/jQuery.noConflict/
If you than replace all occurrences of $() with jQuery() and it works, it was the first issue with using jQuery and Prototype at the same time.
Have you got an element with an id of 'drop_area'? ie 6/7/8 auto assigns a global var to the dom element using the element id. Some more code would be helpful.
I wrote an own document method and it works. Consider the use of it like this:
document.myMethod();
How can I dynamically find out what dot notations were used before myMethod?
document.getElementsByTagName('div')[0].myMethod();
I tried this but it does not work. Any ideas?
Update: I'm making my own getElementsByClass('class'). So I have to know what elements should be checked. document.myMethod() should check all of the elements but document.getElementById('id').myMethod() only the childs of #id. How do I do that?
First of all, myMethod does not exist on 'all' DOM Elements unless you put it on Element.prototype etc, and you really don't want to go down this path.
But if you do, then this will refer to the Element on which the method is invoked on.
Chaining dot notation functions is (I think) just syntactic sugar - you're basically calling the last function on the output of the previous function. As far as I'm aware myMethod() would have no way to know what the function was that provided it's input was, unless you provided it as some kind of parameter on the function, for instance:
document.getElementsByTagName('div')[0].myMethod('getElementsByTagName');
Why do you want this information?