jQuery replaceWith find new element - javascript

I'm writing a script to replace some images with divs in jQuery. I'm currently using the replaceWith() method, which works fine, but returns the original (removed) element instead of the new element.
The .replaceWith() method, like most
jQuery methods, returns the jQuery
object so that other methods can be
chained onto it. However, it must be
noted that the original jQuery object
is returned. This object refers to the
element that has been removed from the
DOM, not the new element that has
replaced it.
How can I get a reference to the new DOM element I just created?

$.fn.replaceWithPush = function(a) {
var $a = $(a);
this.replaceWith($a);
return $a;
};
See a working demo

I believe replaceAll() returns the new content. It has the target and source reversed from replaceWith().
var newobj = $( "<p>New paragraph" ).replaceAll( "#replaceme" );

Precede your call to replaceWith() with a jQuery call to find the parent node and then use the parent to find the new node that was inserted with the replaceWith() function.
Here's an example inside the success handler of a $.ajax() function that replaces a form:
success: function(data,textStatus,jqXHR){
var $li=$form.parents('li');
$form.replaceWith(data);
var $form=$li.find('form');
//...
},
In this example, there was a unique form for each li. You may need to tailor your approach depending on how you construct your DOM.

Related

JavaScript vs jQuery Selector

I was wondering what the difference between jQuery selectors $("#fake-div) and JavaScript selectors getElementById("fake-div"). First, are these even called JavaScript selectors?. I know jQuery returns the jQuery object whereas JavaScript selectors returns the DOM element; however, given these two blocks of code:
jQuery Selector
var post = $("#postid");
var reply_list = post.find(".replies_ul");
var current_reply = document.createElement("li");
current_reply.setAttribute("class", "reply_li");
reply_list.insertBefore(current_reply, reply_list.firstChild);
JS Selector
var content_list = document.getElementById("content_ul");
var current_post = document.createElement("li");
current_post.setAttribute("class","content_li");
content_list.insertBefore(current_post, content_list.firstChild);
The jQuery Selector ends up removing the list from the DOM when the last line of code is called, and the JavaScript selector successfully inserts the list item at the top of the list. I'm looking for an explanation as to what is going on.
The jQuery insertBefore in your code is invalid, it takes two arguments whereas the jQuery accepts only one:
.insertBefore( target )
Description: Insert every element in the set of matched elements before the target.
And the normal one:
Node.insertBefore
Description: Inserts the specified node before a reference element as a child of the current node.
parentElement.insertBefore(newElement, referenceElement)
The difference is not on the selector but on the method / function that you are calling.
You are using the jQuery insertBefore function and comparing it with the javascript insertBefore function.
In jQuery the insertBefore function has only one parameter and therefore you are using it wrong.
If you want to make use of the Javascript function insertBefore instead of the jQuery one, then you have to convert your jQuery object reply_list to a Javascript one.
You can do this by using .get(0) or [0] like so:
reply_list[0].insertBefore(current_post, content_list.firstChild);
//or like this
reply_list.get(0).insertBefore(current_post, content_list.firstChild);
In your first block of code, the reply_list is a jQuery object; meaning it doesn't actually have a .firstChild property.
Change it to this:
reply_list.get(0).insertBefore(current_reply, reply_list.get(0).firstChild);
Please note the differences between jQuery's insertBefore and JavaScript's insertBefore

getElementById vs $('#element')

Before today, I thought that getElementById and $('#element') accomplished the same thing. However, when I tried the following:
// Assuming I have jQuery imported already
var $scrollHolder = $('#element');
var scrollDiv = document.getElementById("element");
scrollDiv.scrollTop = scrollDiv.scrollHeight;
//$scrollHolder.scrollTop = $scrollHolder.scrollHeight;
The commented line didn't work, and the uncommented line did. Do the two methods listed above return different things, or is there an error in my code? Should the commented line be working? I'm very confused and would appreciate insight. Thank you.
you have to get the DOM element from jQuery Object
$scrollHolder[0].scrollTop = $scrollHolder[0].scrollHeight;
or
.get( index )
$scrollHolder.get(0).scrollTop = $scrollHolder.get(0).scrollHeight;
$('#element'); is jQuery Object. It creates an array of matched Objects . But here you have id-selector so you only get one Object you can refer to the Native DOM object by using array index [index] or using .get(index).
document.getElementById("element"); is a native DOM Object
FYI
jQuery way of doing it.
.scrollTop()
.prop()
$scrollHolder.scrollTop($scrollHolder.prop('scrollHeight'));
$('#id) returns jquery objects which doesn't have native DOM properties and document.getElementById('id') returns you a native DOM element which has scrollTop property.
Note that you can make any DOM element act as jquery object by wrapping it with $( ) and you can make jquery object to DOM element by accessing index.
An other solution is using the correct jQuery-Wrapper for that:
$scrollHolder.scrollTop($scrollHolder.scrollHeight);
JQuery selector method always returns an Array of elements.
So commented line will not return what you expect.

JQuery select by ID vs document.GetElementByID

I'm just starting with JQuery and am working through a tutorial vid. At one point the presenters go for javascript instead of a JQuery selector. Just wondering why the javascript getElementById below works fine when passing an object to a function, but the second one doesn't?
Thanks!
// works
addTask(document.getElementById('taskText'), evt);
// doesn't
addTask($('#taskText'), evt);
getElementById() returns a DOM element reference.
jQuery's selector returns a jQuery object. You can get the element reference from the jQuery object using
$('#taskText').get(0);
See http://api.jquery.com/get/
To add to the other answer, regarding the result, if you want to use jQuery (which is easier to read), you can get the dom node directly like so:
addTask($('#taskText')[0], evt);
$('#taskText') returns a jQuery object reference.
document.getElementById('taskText') returns a DOM element reference.
If your addTask() function doesn't know how to convert them to what it needs, then that would be the issue since one of them will need a conversion.
If you want to get the first DOM element reference from the jQuery object, you can do so with this:
$('#taskText').get(0)
So these two should be identical:
$('#taskText').get(0)
document.getElementById('taskText')
Both are not exactly same
document.getElementById('taskText'); //returns a HTML DOM Object
var contents = $('#taskText'); //returns a jQuery Object
var contents = $('#taskText')[0]; //returns a HTML DOM Object
so you have to change it to get HTML Dom Object
addTask($('#taskText')[0], evt);
As #Phil and #jfriend00 have pointed out, document.getElementById('taskText') is a DOM element, and $('#taskText') is a jQuery object. The latter is an object of all DOM elements that match the selector.
Think of it as a zero based array, you could pass in the DOM element by doing this:
addTask($('#taskText')[0], evt);

How i can do this in jQuery? any trick to pass selector instead of jQuery object in $

In JavaScript if I append a child which has an ID to another place then it's removed from original location where they currently are.
In javascript I have an event where I can get selector by using this inside the function
$('.').event(function(){
this
});
This is passed to another function and they work fine. Now I want to pass the clone instead of the object; and remember that this does not have ID.
The old code works by passing this to function as DoSomething(this)
if I make a clone using jQuery clone then I have the jQuery object. So how do I get a reference to this instead of the jQuery object when working with the clone?
var clone = $(this).clone() // this is jQuery object.
//how do I get this out of clone?
if I append a child which has an ID to another place then it's removed from original location where they currently are.
Yes, but the same is true of a child node that doesn't have an id attribute as well. An id is only an easy way for you to get a reference to the Element node object; it makes no difference to DOM insertion of cloning behaviour.
In javascript I have an event where I can get selector by using this inside the function
No, this in an event handler gives you the DOM Element node object, not a selector string. A Node can be turned into a jQuery wrapper around it using $(node) and a selector can be turned into a jQuery wrapper on the list of matching nodes using $(selector) but other than this overloading in the jQuery API they're completely different animals.
To pull a Node back out of a jQuery wrapper you can use the get() method or simple array-like access:
var clonedNode= $(this).clone()[0];
var clonedNode= $(this).clone().get(0);
to taste. (get() has some extra features which you don't need here.)
To get the selector used to create a jQuery wrapper you can use the selector property, but this won't return anything if the wrapper was created from a node object ($(this)) rather than a selector.
$(this).clone().get(0). This will get the first matching DOMElement from the jQUery object.
To get the DOMElement object from a jQuery object use get(0):
var clone = $(this).clone(); // this is jQuery object.
var el = clone.get(0); // this is DOMElement object

How to get handle to replaced child?

obj.parentNode.replaceChild(elem,obj)
Now I want to have a handle to that inserted node.
The "elem" handle is still valid even if it has been inserted into the DOM.
So you can simply use elem to access the element that has replaced the old element.
Use the reference you already have: elem. That's the element you just added. The replaceChild call doesn't create any new nodes.
If you're doing something like this:
obj.parentNode.replaceChild(document.createElement('div'),obj)
...you'll not end up with any reference to the new element. You'll need to first retain it manually:
var elem = document.createElement('div'); // Create & reference the new element
obj.parentNode.replaceChild(elem,obj); // Perform the replace
MDC Docs

Categories

Resources