.appendChild() is not a function when using jQuery - javascript

I am trying to transition from pure JavaScript to jQuery. I have a for loop that dynamically creates HTML elements with data from an API. Here is my old code:
recipeDiv = [];
recipeDiv[i] = document.createElement("div");
recipeDiv[i].setAttribute("class", "recipeBlock");
recipeDiv[i].appendChild(someElement);
However, when I transitioned to jQuery and used this instead
recipeDiv = [];
recipeDiv[i] = $("<div/>").addClass("recipeBlock");
recipeDiv[i].appendChild(someElement);
I get the following error: recipeDiv[i].appendChild is not a function
I know that .appendChild() isn't jQuery (JS), but shouldn't it still work? Even if I use the jQuery .append() function, I still get an error.
Any help is greatly appreciated.

You seem to be confusing yourself by inter-changing jQuery and DOM APIs. They cannot be used interchangeably. document.createElement returns an Element and $("<div />") returns the jQuery object. Element object has the appendChild method and jQuery object has the append method.
As a good practice, I would suggest you choose between DOM APIs or jQuery, and stick to it. Here is a pure jQuery based solution to your problem
var recipeContainer = $("<div/>")
.addClass("recipeContainer")
.appendTo("body");
var recipeDiv = [];
var likes = [];
for (var i = 0; i < 20; i++) {
//Create divs so you get a div for each recipe
recipeDiv[i] = $("<div/>").addClass("recipeBlock");
//Create divs to contain number of likes
likes[i] = $("<div/>")
.addClass("likes")
.html("<b>Likes</b>");
//Append likes blocks to recipe blocks
recipeDiv[i].append(likes[i]);
//Append recipe blocks to container
recipeContainer.append(recipeDiv[i]);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

Maybe someElement is not created? Does the code need to be as follows?
recipeDiv = [];
var someElement = $("<div/>").addClass("recipeBlock");
recipeDiv[i].appendChild(someElement);

Related

How to select nested elements by variables? Js

var a = document.getElementsByClassName("lamp");
var b = document.getElementsByTagName("div");
a[0].b[1].style.color = "white";
Why this code is wrong??
Both a and b are nodelists. A language doesnt work how you think it should.
You need to filter the Class Collection by their tagName, than loop trough and add the style ;)
document.getElementsByClassName("lamp").filter(e=>e.tagName=="div").forEach(e=>e.style.color="white";);
However, jquery (a library) is quite useful in such a case:
$("div .lamp").each(function(){
this.css("color","white");
});

How can I dynamically update a HTML attribute

I have this code
<div class="g-popupgrid-item g-zoom" data-size="395x385">
I want to populate the 395x385 dynamically with the image size.
I have a JS function which gets the image size, I don't know how to print/echo/document.write it to be within the HTML tag.
I would avoid using jQuery for such a trivial task unless you are already using it in your project. Plain javascript:
var div = document.querySelector('.g-popupgrid-item');
var newSize = '100x100'; // for example
div.setAttribue('data-size', newSize);
Get the Node using JavaScript, then modify it to fit your needs:
var container = document.querySelector(".g-popupgrid-item .g-zoom")
container.setAttribute("data-size", value)
Keep in mind this will only affect the first element with those classes, if you want affect them all, use the code below:
var containers = document.querySelectorAll(".g-popupgrid-item .g-zoom")
containers.forEach(function(container) {
container.setAttribute("data-size", value)
})
Also keep in mind that containers is not an Array it's a NodeList. Read more here
EDIT: According to #Eoin, the .forEach() method on NodeLists is not supported in Firefox. You can also use a standard for loop in place of it:
var containers = document.querySelectorAll(".g-popupgrid-item .g-zoom")
for (var i = 0; i < containers.length; i++) {
containers[i].setAttribute("data-size", value)
}

How to use function on every element by class name?

Now I am using "Perfect Scroller" which is a custom scroll bar plugin.
I followed the Document to setup.Here
I use code like below and every was good.
var container = document.getElementById('container');
Ps.initialize(container);
However, I want to use it by "ClassName" not by "ID" because there are lots of areas.
I know I can use
var container = document.getElementsByClassName('selected_area')[0];
But this is only one element.
My question is how to do it by ClassName?
You can do in a loop:
var container = document.getElementsByClassName('selected_area');
for(var i in container) {
Ps.initialize(container[i]);
}
This iterates all containers and initialize it independently.
var container = document.getElementsByClassName('selected_area');
for(var i = 0; i < container.size; i++){
Ps.initialize(container[i]);
}
Although I haven't had a look at this plugin you are using, so I don't know if it should be initialised more than once. Hope this helps
you can also use:
var container = document.querySelectorAll('.selected_area');
furthermore you can transform it to an array(it's only necessary if you want to use standard array methods)
var contArr = [].slice.call(container)
in this case you can then use it with forEach
contArr.forEach(function(x){Ps.initialize(x)}

Beginner Javascript error with getAttribute

I've searched quite a bit on both google and stackoverflow, but a lack of knowledge on how to ask the question (or even if I'm asking the right question at all) is making it hard to find pertinent information.
I have a simple block of code that I am experimenting with to teach myself javascript.
var studio = document.getElementById('studio');
var contact = document.getElementById('contact');
var nav = document.getElementById('nav');
var navLinks = nav.getElementsByTagName('a');
var title = navLinks.getAttribute('title');
I want to grab the title attribute from the links in the element with the ID 'nav'.
Whenever I look at the debugger, it tells me that Object #<NodeList> has no method 'getAttribute'
I have no idea where I'm going wrong.
The nodetype and nodevalue for navLinks comes back as undefined, which I believe may be part of the problem, but I'm so new to this that I honestly have no idea.
The getElementsByTagName method returns an array of objects. So you need to loop through this array in order to get individual elements and their attributes:
var navLinks = nav.getElementsByTagName('a');
for (var i = 0; i < navLinks.length; i++) {
var link = navLinks[i];
var title = link.title;
}
Calling nav.getElementsByTagName('a') returns list of objects. And that list doesn't have getAttribute() method. You must call it on ONE object.
When you do:
navLinks[0].getAttribute('title')
then it should work - you will get title of the first matched element.
var navLinks = nav.getElementsByTagName('a');
getElementsByTagName returns multiple elements (hence Elements), because there can be multiple elements on one page with the same tag name. A NodeList (which is a collection of nodes as returned by getElementsByTagName) does not have a getAttribute method.
You need to access the property of the element that you actually need. My guess is that this will be the first element you find.
var title = navLinks[0].getAttribute('title');

Trying to append to an element using js?

I am trying to add to all <object>'s on a page a snippet of html. I understand I can access elements by tag name and that I can change the element, but can I simple append to it instead?
In addition, I want to add it to the contents of each tag, not the end of the document. Which of these methods will work?
Assuming no library...
var elementToAppend = document.createElement(tagName); // Your tag name here
// Set attributes and properties on elementToAppend here with
// elementToAppend.attribute = value (eg elementToAppend.id = "some_id")
// You can then append child text and elements with DOM methods
// (createElement or createTextNode with appendChild)
// or with innerHTML (elementToAppend.innerHTML = "some html string")
var objects = document.getElementsByTagName('object');
for(var i = 0; i < objects.length; i++) {
elementToAppend = elementToAppend.cloneNode(true);
objects[i].appendChild(elementToAppend);
}
Using innerHTML or outerHTML as other answers have suggested will likely cause problems for whatever you've embedded with <object>.
appendChild is what you're looking for.

Categories