简体   繁体   中英

How to know if element created with document.createElement still exists

I'm creating an anchor element using document.createElement in my PhantomJS tests like this:

var mockLink = null;

beforeEach(function() {
  mockLink = document.createElement('a');
});

it('should foo', function() {
  // Use mockLink in some way
});

I want to clean up the element in the afterEach code so that each test will have a newly-created instance of it. Unfortunately, element.remove() isn't supported in PhantomJS. Source

afterEach(function() {
  mockLink.remove();  // Error!
});

And I want to do this without adding the webpage plugin .

removeChild is supported by PhantomJS, but my newly-created element doesn't have a parent:

mockLink.parentElement // undefined
mockLink.parentElement.removeChild(mockLink); // doesn't work
mockLink.parentNode // also undefined

My newly-created link also doesn't seem to be on the document at all.

mockLink.href = 'www.google.com';
document.getElementsByTagName('a'); // doesn't contain google.com

So I can't do

document.removeChild(mockLink);

mockLink.ownerDocument.contains(mockLink) also returns false

It seems like there are no references to mockLink stored anywhere besides my mockLink variable, meaning that I can just set mockLink equal to null if I want to let that memory be freed up by garbage collection. But how do I verify this works? If I set any other variable to mockLink and then console.log it, it will still come out as defined since it will be a new reference to the same space in memory. How do I verify that mockLink is really being deleted when I set the variable to null ?

You've found yourself a conundrum.

If you kill all references to the element by setting mockLink = null and making sure there are no other references to the element, then the garbage collector should be able to free that object.

But, you cannot verify that because in order to verify that the element is no longer available, you'd have to keep a reference to it, but that would prevent it from getting garbage collected in the first place. Thus, the conundrum.

This is an issue that can't really be measured directly from Javascript itself.

If you want to design a one-time test to make sure the memory is being reclaimed, then you can take a memory snapshot, create a several hundred thousand objects stored in an array, clear the array, wait a short time for GC to run, take another memory snapshot, repeat the same process several more times and verify that memory usage of the process is not steadily increasing or study the memory snapshot to make sure none of those objects appear in the memory footprint.

If your javascript environment supports weak references then you can create a weak reference to the node. Depending on the implementation notification mechanisms such as callbacks or reference queues that tell you when it has been collected may also be available.

Unprivileged javascript contexts in web browsers currently don't offer such an API. Node.js, Nashorn and browser addon environments do.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM