Node.prototype.contains() Polyfill
The `node-contains` package, currently at version 1.0.0 and last published in September 2014, was designed to provide a cross-browser polyfill for the `Node.prototype.contains()` DOM method. Its original purpose was to ensure consistent behavior across older web browsers that lacked native support for this functionality. However, this method has been natively supported by all major web browsers since July 2015. Consequently, this package is now largely obsolete and considered abandoned for modern web development. While it might still be encountered in projects targeting extremely legacy environments, for any contemporary application, including `node-contains` introduces unnecessary overhead and potential compatibility issues. It does not follow a regular release cadence and offers no unique differentiators over native browser implementations.
Common errors
-
ReferenceError: Node is not defined
cause Attempting to include or execute this browser-specific polyfill in a non-browser (e.g., Node.js server-side) environment.fixThis package is explicitly for client-side browser environments. Ensure it is only included in your client-side bundles and excluded from server-side Node.js code. Use appropriate build tool configurations (e.g., Webpack targets, browser field in package.json) to achieve this separation. -
TypeError: undefined is not a function (evaluating 'element.contains(otherElement)')
cause This error typically occurs when `Node.prototype.contains` is invoked on an object that is not a valid DOM `Node` or if the polyfill (or native support) has not been loaded/executed before the method call in a very old browser context. In modern browsers, this indicates `element` is not a `Node`.fixVerify that the `element` variable is indeed a DOM `Node` (e.g., obtained via `document.getElementById()`). If targeting extremely old browsers, ensure `import 'node-contains';` (or `require('node-contains');`) is executed at the very beginning of your application's entry point before any DOM manipulation code that relies on `contains`. -
Error: Module not found: Error: Can't resolve 'node-contains'
cause The `node-contains` package has not been installed as a dependency in your project, or there is a typo in the import/require statement or package name.fixInstall the package using your package manager: `npm install node-contains` or `yarn add node-contains`. Then, double-check the import or require statement for any spelling errors and ensure it matches the package name exactly.
Warnings
- breaking This polyfill is effectively obsolete. The `Node.prototype.contains()` method has been natively supported by all major web browsers since July 2015, making this package redundant for nearly all modern web development environments. Including it introduces unnecessary bundle size and may lead to subtle compatibility issues or conflicts if other polyfills or libraries also modify `Node.prototype`.
- gotcha The package is unmaintained, with its last update in September 2014. Using unmaintained dependencies can expose projects to security vulnerabilities (e.g., supply chain attacks, unpatched bugs) as no further patches or updates are released for discovered issues.
- gotcha As a polyfill, `node-contains` modifies the global `Node.prototype`. While this is its intended function, in complex applications or environments where multiple polyfills or libraries might attempt to patch or define the same method, this could lead to unexpected behavior, overwrites, or conflicts, making debugging difficult.
Install
-
npm install node-contains -
yarn add node-contains -
pnpm add node-contains
Imports
- Node.prototype.contains
import { contains } from 'node-contains';import 'node-contains';
- Node.prototype.contains (CommonJS)
const contains = require('node-contains');require('node-contains');
Quickstart
import 'node-contains'; // Apply the polyfill (though likely unnecessary in modern browsers)
function checkContains() {
const parentDiv = document.createElement('div');
parentDiv.id = 'parent';
const childSpan = document.createElement('span');
childSpan.id = 'child';
parentDiv.appendChild(childSpan);
document.body.appendChild(parentDiv);
// Using Node.prototype.contains() after the polyfill (or native support)
const isContained = parentDiv.contains(childSpan);
const selfContained = parentDiv.contains(parentDiv); // Node is considered to contain itself
const notContained = document.body.contains(document.createElement('p'));
console.log('Is childSpan contained in parentDiv?', isContained); // Expected: true
console.log('Is parentDiv contained in itself?', selfContained); // Expected: true
console.log('Is new P not contained in body?', notContained); // Expected: false (unless appended)
document.body.removeChild(parentDiv);
}
// Run the check when the DOM is ready
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', checkContains);
} else {
checkContains();
}