Why is doing
var consoleElem = document.getElementById("debug");
consoleElem.appendChild(msgElement)
the same thing as
document.getElementById('debug').appendChild(msgElement);
It seems to me that the DOM element (debug) is its own variable, and then to copy it to another variable means I have two copies of the debug element... why should any changes I make to the new copy (var consoleElem) make changes to the original DOM element?
What is in the consoleElem isn't the DOM element itself but instead a reference to it.. so any change that's done through the reference is actually applied to the DOM element itself..
If you want to modify an element without actually changing the original element itself then you should clone it.. jQuery offers a clone functionality.
The call document.getElementById returns a reference to a DOM element. All that the line
var consoleElem = document.getElementById("debug");
does is store that reference in a variable; it doesn't create anything. You can have a dozen variables referring to the same element, and it's still just one element.
If you want to create an element, use document.createElement. If you want to copy an element, use newElement = oldElement.cloneNode().
Related
If I want to append some HTML (a <p> tag in this case) to an element in Vanilla JS then it seems I have to do this:
const $Element = document.getElementById("ElementID");
$Element.insertAdjacentHTML("afterbegin", "<p></p>");
That works great, but what I don't understand is if I'm storing a reference to #ElementID in a $Element variable, why does manipulating the variable cause the DOM to update?
Say I wanted to do many changes to $Element like first add a <h1> tag and then a <h2> and then multiple <p> tags. I would like all of them to be done first and then ask JS to update the DOM instead of it doing it in real-time. Is that even possible in Vanilla JS?
I'm storing a reference to #ElementID in a $Element variable, why does manipulating the variable cause the DOM to update?
Because that's how references work. You can place the same reference in any number of variables, you still only have one object, and if you modify that object, the other variables "pointing" to that reference will reflect those changes, because they are all simply handles to the same object in memory.
If you want to batch changes, make a new DOM element, prepare it, and then add it to the DOM.
To accomplish what you are looking for you can always use cloneNode to clone the element you want to change, make the changes, then replace it in the dom with replaceChild on the element's parent.
var elem = document.querySelector('#target');
var clone = elem.cloneNode(true);
clone.innerHTML = "TeST";
clone.style.backgroundColor = "red";
elem.parentNode.replaceChild(clone, elem);
<div id="target"></div>
I'm creating a JQuery object(let's call it $dummyHTML) and setting some html content inside it. Then I go through each of it's child nodes including text ones, do some checks, and append them to a new different JQuery Object(let's call it $refinedHTML).
But the problem is that the contents of $dummyHTML seems to be empty even before I append them to $refinedHTML!
Now, I know that JQuery append function doesn't copy a node, it actually transfers the node to the other JQuery object. So I'm guessing the append function triggers before I mean it to?
Here is a minified example of the issue.
var $dummyHTML = $('<div/>');
$dummyHTML.html('Hello there, <span>myself!</span>');
var $refinedHTML = $('<div/>');
console.log($dummyHTML[0]);
$dummyHTML.contents().each(function() {
$refinedHTML.append($(this));
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
But if I remove the .contents part the programs works as expected.
.contents() extracts the content of a DOM element .When you create an object on the fly,it is not yet a DOM element so .contents() will not work however you can manipulate the object data in other ways.
Reference here:
Given a jQuery object that represents a set of DOM elements, the .contents() method allows us to search through the immediate children of these elements in the DOM tree and construct a new jQuery object from the matching elements.
I'm using a pretty cool JavaScript/jQuery library called OpenSeaDragon. It's for displaying deep zoom images. It also have a method for adding 'overlays', essentially creating a div and putting it over the image with coordinates though a viewer object. There's also a method for removing the overlays: https://openseadragon.github.io/docs/OpenSeadragon.Viewer.html#removeOverlay
viewer.removeOverlay(element or element id);
As the doc states regarding the input param: "A reference to the element or an element id which represent the ovelay content to be removed." I'm creating a whole bunch of overlays -- creating a grid out of rectangles -- so I've given them a class. Passing the class to this method doesn't work. So I'm trying to understand what they mean by "element". Is there a way I can use JQuery or JavaScript to select an "element" and pass it to the method? Or some such thing?
thanks
It usually means an element in your document, i.e. a DOM node. So, a div, or a span, or somesuch.
You can select an element with jQuery pretty easily:
var $obj = $('#elementId');
and then grab the underlying DOM node from the jQuery object that results:
var elm = $obj[0];
Thanks everyone. Here's how to do it:
var n = $(".gridcell").length
for(i=0; i<n; i++) {
viewer.removeOverlay($(".gridcell")[0]);
}
At first I though I could iterate through the array, calling removeOverlay() on each item index successively. This was causing half the overlays to be deleted on each run. So, for 16 overlay, I have to run it 4 times. After a few minutes it clicked... Each time you get the elements $(".gridcell"), it returns a new array.
I created an iframe using jQuery that I want to insert into an existing div element. However, when I use innerHTML to insert it, it shows up as: "[object HTMLIFrameElement]"
What could be the reason for this?
Here is the example: http://jsfiddle.net/MarkKramer/PYX5s/2/
You want to use the appendChild method rather than innerHTML. Change the last line in the JSFiddle from
iframediv.innerHTML = iframe;
to
iframediv.appendChild(iframe);
Edit to actually answer your question:
Your variable iframe is a reference to a DOM element. It's object representation is an <iframe> element while its textual representation is simply [object HTMLIFrameElement].
By using innerHTML you are attempting to insert its textual representation into the DOM. This is just how the method works. You may come across JS code where elements are added to the DOM via innerHTML, but it's always with text, e.g.
element.innerHTML = '<div>some text</div>';
In this case the browser will correctly add a <div> node as a child of element.
For your <iframe> element to be inserted into the DOM using the variable iframe, you must use the appendChild method which will add the IFrame object as a child node to iframediv.
$('#iframecontainer').append(iframe);
instead of
var iframediv = document.getElementById('iframecontainer');
iframediv.innerHTML = iframe;
should fix the problem
var new_iframe = $("<iframe></iframe>");
new_iframe.appendTo($("#div_to_insert_into"));
The idea behind (most) of the posted solutions is that you can work with your iframe and it's container as jQuery objects instead of regular dom elements. A jQuery object is a reference to a div or an iframe that has access to all of jQuery's awesome methods... like .append() and .click().
Generally speaking, jQuery's real purpose is to turn lines of code like
var iframediv = document.getElementById('iframecontainer');
...into ...
var iframediv = $("#iframecontainer");
...which you can then use to do with whatever you please, like
iframediv.appendTo("#anotherDiv");
Good luck.
So, say I have selected, in JQuery, a singular DOM div.
I then proceed to create a new DIV like so:
var DIV = $("<div>Hello, world</div>");
After that, I attempt to place that DIV inside the original one like so:
$(OriginalDiv).append(DIV);
Okay, that works.
Now I want to edit DIV further.
Calls to .click, .html, .addClass, (And likely more) do not work!
Okay, instead I do:
var OriginalDiv = $("someSelector");
var DIV = $("<div>Hello, world</div>");
DIV = $(OriginalDiv).append(DIV);
That appears to work at first; However, instead, it sets DIV to reference the same DOM object as OriginalDiv and NOT the newly appended DOM object. Naturally, this does not allow me to edit DIV.
So, then, I try two more methods:
var OriginalDiv = $("someSelector");
var DIV = $("<div>Hello, world</div>");
$(DIV).appendTo(OriginalDiv);
and
var OriginalDiv = $("someSelector");
var DIV = $("<div>Hello, world</div>");
DIV = $(DIV).appendTo(OriginalDiv);
Not even these work.
If I haven't done a very good job explaining, here is my exact dilemma
I am trying to create a DOM object in jquery, then append it to another DOM object using jquery. The problem is, once it gets appended, there seems to be no way for me to directly access it without using somethign like .children.
I'd like very much to be directly returned somewhere along in that process a reference to the DOM object which I am appending. As in the one that actually gets appended.
I'm not sure how to do this in JQuery. Anybody know a solution?
Thanks
--G
Yes, append won't work as it returns a reference to the element the new element was appended to. jQuery supports method chaining, so this should work easily:
$("<div>Hello, world</div>")
.click(function() {
// something
})
.appendTo('someSelector');
But even
var $ele = $("<div>Hello, world</div>").appendTo('someSelector');
will work. appendTo returns a reference to the element which was appended. If this does not work for you, you have your problem elsewhere.
Comments on your code: This is not your problem, however it is important for you to know what is going on here.
This part
var OriginalDiv = $("someSelector");
var DIV = $("<div>Hello, world</div>");
$(DIV).appendTo(OriginalDiv);
is the same as
$($("<div>Hello, world</div>")).appendTo($("someSelector"));
You see, you have a nested call to jQuery, because DIV is already a jQuery object. There is no need to pass it again to jQuery.
You can also pass a selector directly to appendTo.
you could try this;
var DIV = document.createElement('div');
then you can use;
$(div).html('Test!');
or what ever you want to use with.
You don't have to get anything back from the DOM. Once you create the element with jQuery, you already have a reference to the DOM element. Inserting it into the document does not do anything special.
// this will create the DOM element, and the jQuery
// object wrapping that newly created DOM object
// is assigned to DIV.
var DIV = $("<div>Hello, world</div>");
// Don't worry about getting a return value from this
// append() call. What we need is already available inside
// the variable DIV.
$(OriginalDiv).append(DIV);
// continue using DIV as you normally would. It is referring
// to the same DOM object that was just appended to the document.
DIV.addClass('green');