Làm cách nào để kiểm tra xem Đối tượng JavaScript có phải là Đối tượng DOM không?


247

Tôi đang cố gắng để có được:

document.createElement('div')  //=> true
{tagName: 'foobar something'}  //=> false

Trong các tập lệnh của riêng tôi, tôi thường chỉ sử dụng điều này vì tôi không bao giờ cần tagNamelàm tài sản:

if (!object.tagName) throw ...;

Vì vậy, đối với đối tượng thứ hai, tôi đã đưa ra một giải pháp nhanh như sau - phần lớn hoạt động. ;)

Vấn đề là, nó phụ thuộc vào các trình duyệt thực thi các thuộc tính chỉ đọc, điều mà không phải tất cả đều làm được.

function isDOM(obj) {
  var tag = obj.tagName;
  try {
    obj.tagName = '';  // Read-only for DOM, should throw exception
    obj.tagName = tag; // Restore for normal objects
    return false;
  } catch (e) {
    return true;
  }
}

Có một sự thay thế tốt?


3
Tôi có đang khó hiểu khi tự hỏi liệu "Đối tượng DOM" không chỉ bao gồm các Phần tử mà còn bao gồm tất cả các Nút (Nút văn bản, Thuộc tính, v.v.)? Tất cả các câu trả lời và cách bạn đặt ra câu hỏi có xu hướng gợi ý câu hỏi này cụ thể là về các yếu tố ...
loài gặm nhấm

Câu trả lời:


300

Điều này có thể được quan tâm:

function isElement(obj) {
  try {
    //Using W3 DOM2 (works for FF, Opera and Chrome)
    return obj instanceof HTMLElement;
  }
  catch(e){
    //Browsers not supporting W3 DOM2 don't have HTMLElement and
    //an exception is thrown and we end up here. Testing some
    //properties that all elements have (works on IE7)
    return (typeof obj==="object") &&
      (obj.nodeType===1) && (typeof obj.style === "object") &&
      (typeof obj.ownerDocument ==="object");
  }
}

Đây là một phần của DOM, Level2 .

Cập nhật 2 : Đây là cách tôi triển khai nó trong thư viện của riêng mình: (mã trước đó không hoạt động trong Chrome, vì Node và HTMLEuity là các chức năng thay vì đối tượng dự kiến. Mã này được thử nghiệm trong FF3, IE7, Chrome 1 và Opera 9).

//Returns true if it is a DOM node
function isNode(o){
  return (
    typeof Node === "object" ? o instanceof Node : 
    o && typeof o === "object" && typeof o.nodeType === "number" && typeof o.nodeName==="string"
  );
}

//Returns true if it is a DOM element    
function isElement(o){
  return (
    typeof HTMLElement === "object" ? o instanceof HTMLElement : //DOM2
    o && typeof o === "object" && o !== null && o.nodeType === 1 && typeof o.nodeName==="string"
);
}

11
Điều đáng chú ý là điều này sẽ không hoạt động trên các yếu tố thuộc về các cửa sổ / khung khác. Gõ vịt là cách tiếp cận được đề xuất
Andy E

2
Bạn có thể đánh lừa nó bằng:function Fake() {}; Fake.prototype=document.createElement("div"); alert(new Fake() instanceof HTMLElement);
Kernel James

11
WTF fact: Firefox 5 và trước đó trở lại truecho [] instanceof HTMLElement.
Cướp

6
Btw, HTMLElementluôn luôn là một function, vì vậy typeofsẽ ném bạn ra khỏi đường đua và sẽ thực hiện phần thứ hai của tuyên bố. Bạn có thể thử nếu bạn muốn instanceof Object, bởi vì hàm sẽ là một thể hiện của Object, hoặc chỉ kiểm tra rõ ràng typeof === "function", bởi vì NodeHTMLElementcả hai hàm đối tượng gốc.
Roland

2
Khi bạn gọi isElement(0), nó trả về 0, không sai ... Tại sao lại như vậy và làm cách nào tôi có thể ngăn chặn điều đó?
Jessica

68

Mã siêu đơn giản tương thích IE8 sau đây hoạt động hoàn hảo.

Các câu trả lời được chấp nhận không phát hiện tất cả các loại phần tử HTML. Ví dụ, các yếu tố SVG không được hỗ trợ. Ngược lại, câu trả lời này hoạt động cho HTML cũng như SVG.

Xem nó trong hành động ở đây: https://jsfiddle.net/eLuhbu6r/

function isElement(element) {
    return element instanceof Element || element instanceof HTMLDocument;  
}

3
'Phần tử' không được xác định trên IE7
Dan

49
Tôi cho rằng bất cứ ai vẫn sử dụng IE7 nên dành năm giây để tải xuống một trình duyệt tốt hơn thay vì đưa chúng tôi đầu tư nhiều ngày hoặc nhiều tuần làm việc xung quanh việc từ chối của họ để có được thời gian.
mopsyd

1
Tôi đồng ý với @mopsyd, nhưng tác giả của câu trả lời cho biết, nó hoạt động trong IE7, có thể cần được cập nhật để đảm bảo tính chính xác.
Lajos Meszaros

1
Cập nhật để nói IE9. Tôi không chắc chắn nếu IE8 hỗ trợ nó.
Monarch Wadia

1
@MonarchWadia có nó được hỗ trợ trong IE8. Nhưng lưu ý rằng điều này không trả về true cho documentphần tử (trong tất cả các trình duyệt). nếu bạn cần, bạn nên thử:x instanceof Element || x instanceof HTMLDocument
S.Serpooshan

11

Tất cả các giải pháp trên và dưới (giải pháp của tôi bao gồm) đều có khả năng không chính xác, đặc biệt là trên IE - hoàn toàn có thể (xác định lại) một số đối tượng / phương thức / thuộc tính để bắt chước một nút DOM khiến thử nghiệm không hợp lệ.

Vì vậy, tôi thường sử dụng thử nghiệm kiểu gõ vịt: Tôi kiểm tra cụ thể cho những thứ tôi sử dụng. Ví dụ: nếu tôi muốn sao chép một nút, tôi sẽ kiểm tra nó như thế này:

if(typeof node == "object" && "nodeType" in node &&
   node.nodeType === 1 && node.cloneNode){
  // most probably this is a DOM node, we can clone it safely
  clonedNode = node.cloneNode(false);
}

Về cơ bản nó là một chút kiểm tra độ tỉnh táo + thử nghiệm trực tiếp cho một phương thức (hoặc một tài sản) tôi đang dự định sử dụng.

Ngẫu nhiên thử nghiệm ở trên là một thử nghiệm tốt cho các nút DOM trên tất cả các trình duyệt. Nhưng nếu bạn muốn ở bên an toàn, hãy luôn kiểm tra sự hiện diện của các phương thức và thuộc tính và xác minh các loại của chúng.

EDIT: IE sử dụng các đối tượng ActiveX để biểu diễn các nút, vì vậy các thuộc tính của chúng không hoạt động như đối tượng JavaScript thực sự, ví dụ:

console.log(typeof node.cloneNode);              // object
console.log(node.cloneNode instanceof Function); // false

trong khi nó sẽ trả về "hàm" và truetương ứng. Cách duy nhất để kiểm tra các phương thức là xem nếu được xác định.


"typeof document.body.cloneNode" không trả về "đối tượng" trong IE của tôi
Dennis C

Đây có vẻ là một câu trả lời đàng hoàng. Xem câu trả lời của tôi dưới đây, stackoverflow.com/a/36894871/1204556
Monarch Wadia

8

Bạn có thể thử nối nó vào một nút DOM thực sự ...

function isDom(obj)
{
    var elm = document.createElement('div');
    try
    {
        elm.appendChild(obj);
    }
    catch (e)
    {
        return false;
    }

    return true;
}

11
Nó có hoạt động không? Nó vẫn là một giải pháp. Một sáng tạo ở đó.
Justin Meyer

3
+1 cho sự sáng tạo và chắc chắn cung cấp này. Tuy nhiên, nếu nút tình cờ là một phần của DOM, bạn đã xóa nó! Vì vậy, ... câu trả lời này không đầy đủ mà không thực hiện công việc để thêm lại phần tử vào DOM nếu cần thiết.
Svidgen

4
Tôi đã đọc nó sau gần 5 năm và tôi nghĩ đó là một trong những điều tuyệt vời nhất. Nó chỉ cần được tinh chế. Bạn có thể thử nối một bản sao của nút vào một phần tử tách rời, ví dụ. Nếu đó không phải là một đối tượng DOM. một cái gì đó chắc chắn sẽ đi sai Vẫn còn là một giải pháp đắt tiền.
MaxArt

Hoặc thay vì cố gắng sao chép bản sao của phần tử, chỉ cần cố gắng sao chép nó là đủ : obj.cloneNode(false). không có tác dụng phụ.
mauroc8

1
Điều này thực sự tốn kém và phức tạp không cần thiết. Xem câu trả lời của tôi dưới đây, stackoverflow.com/a/36894871/1204556
Monarch Wadia


6

Còn Lo-Dash thì_.isElement sao?

$ npm install lodash.iselement

Và trong mã:

var isElement = require("lodash.iselement");
isElement(document.body);

1
Tôi thích giải pháp này. Nó đơn giản và nó hoạt động trong Edge và IE, ngay cả đối với các phần tử trong iframe riêng biệt, không giống như hầu hết các giải pháp được bình chọn cao nhất ở đây.
Elias Zamaria

Câu trả lời này rất hữu ích, mặc dù người ta sẽ cần Webpack để chạy các mô-đun NPM trong trình duyệt.
Edwin Pratt

5

Đây là từ thư viện JavaScript đáng yêu MooTools :

if (obj.nodeName){
    switch (obj.nodeType){
    case 1: return 'element';
    case 3: return (/\S/).test(obj.nodeValue) ? 'textnode' : 'whitespace';
    }
}

12
Mã này không khẳng định rằng đối tượng là một phần tử DOM; chỉ có điều nó trông hơi giống một. Bất kỳ đối tượng nào cũng có thể được cung cấp một thuộc tính nodeName và nodeType và đáp ứng mã này.
thomasrutter

Câu trả lời này không phát hiện tất cả các loại yếu tố HTML. Ví dụ, các yếu tố SVG không được hỗ trợ. Xem câu trả lời của tôi dưới đây.
Monarch Wadia

Không thực sự hoạt động trên tất cả các yếu tố, ví dụ như SVG. Xem câu trả lời của tôi dưới đây, stackoverflow.com/a/36894871/1204556
Monarch Wadia

4

Việc sử dụng phát hiện gốc được tìm thấy ở đây , chúng ta có thể xác định xem ví dụ: cảnh báo có phải là thành viên của thư mục gốc hay không, có khả năng là một cửa sổ:

function isInAnyDOM(o) { 
  return (o !== null) && !!(o.ownerDocument && (o.ownerDocument.defaultView || o.ownerDocument.parentWindow).alert); // true|false
}

Để xác định xem đối tượng là cửa sổ hiện tại thậm chí còn đơn giản hơn:

function isInCurrentDOM(o) { 
  return (o !== null) && !!o.ownerDocument && (window === (o.ownerDocument.defaultView || o.ownerDocument.parentWindow)); // true|false
}

Điều này dường như ít tốn kém hơn so với giải pháp thử / bắt trong luồng mở.

Don P


Tôi đã thử nghiệm điều này trong Chrome và FF mới nhất, cũng như trong IE11 và nó hoạt động ở mọi nơi, cũng cho các nút văn bản và các đối tượng được tạo thông qua document.createElement()nhưng không được chèn vào DOM. Tuyệt vời (: Cảm ơn bạn
Geradlus_RU

Đây có vẻ là một câu trả lời đàng hoàng, mặc dù tôi làm rất nhiều thứ tương tự và ít phức tạp hơn. stackoverflow.com/a/36894871/1204556
Monarch Wadia

4

chủ đề cũ, nhưng đây là một khả năng được cập nhật cho người dùng eg8 và ff3.5 :

function isHTMLElement(o) {
    return (o.constructor.toString().search(/\object HTML.+Element/) > -1);
}

4

Tôi đề nghị một cách đơn giản để kiểm tra nếu một biến là một phần tử DOM

function isDomEntity(entity) {
  if(typeof entity  === 'object' && entity.nodeType !== undefined){
     return true;
  }
  else{
     return false;
  }
}

hoặc như HTMLGuy đề xuất:

const isDomEntity = entity => {
  return typeof entity   === 'object' && entity.nodeType !== undefined
}

1
Cách quá dài dòng. Việc so sánh sẽ trả về một boolean:return typeof entity === 'object' && typeof entity.nodeType !== undefined;
HTMLGuy

1
Rất thú vị! Đôi khi, tùy thuộc vào Loại bạn có trên objects và / hoặc dân số của bạn, điều này có thể rất tiện dụng! Tx, @Roman
Pedro Ferreira

3
var IsPlainObject = function ( obj ) { return obj instanceof Object && ! ( obj instanceof Function || obj.toString( ) !== '[object Object]' || obj.constructor.name !== 'Object' ); },
    IsDOMObject = function ( obj ) { return obj instanceof EventTarget; },
    IsDOMElement = function ( obj ) { return obj instanceof Node; },
    IsListObject = function ( obj ) { return obj instanceof Array || obj instanceof NodeList; },

// Trong thực tế tôi có nhiều khả năng sử dụng các nội tuyến này, nhưng đôi khi thật tốt khi có các phím tắt này cho mã thiết lập


obj.constructor.name không hoạt động trong IE, vì trong IE, các hàm không có thuộc tính tên. Thay thế bằng obj.constructor! = Object.
mathheadinclouds

3

Điều này có thể hữu ích: isDOM

//-----------------------------------
// Determines if the @obj parameter is a DOM element
function isDOM (obj) {
    // DOM, Level2
    if ("HTMLElement" in window) {
        return (obj && obj instanceof HTMLElement);
    }
    // Older browsers
    return !!(obj && typeof obj === "object" && obj.nodeType === 1 && obj.nodeName);
}

Trong đoạn mã trên, chúng tôi sử dụng toán tử phủ định kép để lấy giá trị boolean của đối tượng được truyền dưới dạng đối số, theo cách này chúng tôi đảm bảo rằng mỗi biểu thức được đánh giá trong câu lệnh có điều kiện là boolean, lợi dụng Đánh giá ngắn mạch , do đó hàm trả lại truehoặcfalse


Bất cứ điều gì giả mạo nên ngắn mạch boolean của bạn. undefined && window.spam("should bork")không bao giờ đánh giá spamchức năng giả , ví dụ. Vì vậy, không !!cần thiết, tôi không tin. Điều đó, bạn có thể cung cấp một trường hợp cạnh [không hàn lâm] trong đó vấn đề sử dụng của nó không?
ruffin

Cảm ơn bạn đã tuyên bố của bạn. Tôi đã sử dụng phủ định kép * !! * để chuyển đổi tất cả biểu thức thành giá trị boolean, không trung thực hoặc giả.
jherax

Đúng, nhưng không có lý do thực tế để làm điều đó, tôi không nghĩ - xem ở đây . Và chắc chắn không cần thiết phải tận dụng lợi thế của Short-Cut eval ở đây. Ngay cả khi bạn không mua đối số " !!không bao giờ cần thiết" ( và nếu bạn không, tôi tò mò tại sao không ), bạn có thể chỉnh sửa dòng đó return !!(obj && typeof obj === "object" && obj.nodeType === 1 && obj.nodeName);và để nó hoạt động tương tự.
ruffin

Đó là những gì tôi đã làm;) sạch sẽ hơn và hiệu quả tương tự. cảm ơn bạn.
jherax

2

Bạn có thể xem nếu đối tượng hoặc nút trong câu hỏi trả về một loại chuỗi.

typeof (array).innerHTML === "string" => false
typeof (object).innerHTML === "string" => false
typeof (number).innerHTML === "string" => false
typeof (text).innerHTML === "string" => false

//any DOM element will test as true
typeof (HTML object).innerHTML === "string" => true
typeof (document.createElement('anything')).innerHTML === "string" => true

3
typeof ({innerHTML: ""}).innerHTML === "string"
Qtax

NÓNG BỨC! Phản ứng này nên là người chiến thắng trò chơi. if (typeof obj.innerHTML! == 'chuỗi') // không phải là phần tử dom.
dùng3751385

1
Ban đầu tôi đã phản ứng chống lại sự phê phán của @Qtax và thomasrutter về một câu trả lời trước đó , nhưng tôi đang bắt đầu mua nó. Mặc dù tôi đã không gặp phải những con chó quậy phá như vịt chính xác như thế này trước đây, tôi có thể thấy ai đó không kiểm tra xem có gì đó là một nút, đang chạy hay không notANode.innerHTML = "<b>Whoops</b>";, sau đó có mã đó chuyển obj bị ô nhiễm sang mã này . Mã phòng thủ === mã tốt hơn, tất cả những thứ khác đều bằng nhau và điều này cuối cùng không phải là phòng thủ.
ruffin


2

Tôi nghĩ rằng tạo mẫu không phải là một giải pháp rất tốt nhưng có lẽ đây là giải pháp nhanh nhất: Xác định khối mã này;

Element.prototype.isDomElement = true;
HTMLElement.prototype.isDomElement = true;

hơn là kiểm tra đối tượng của bạn là thuộc tính isDomEuity:

if(a.isDomElement){}

Tôi hi vọng cái này giúp được.


1
1) thay đổi đối tượng bạn không sở hữu là không nên. 2) điều này không phát hiện ra các yếu tố không phải là một phần của cùng một tài liệu.
fregante

2

Theo md

Elementlà lớp cơ sở tổng quát nhất mà từ đó tất cả các đối tượng trong một Documentkế thừa. Nó chỉ có các phương thức và thuộc tính chung cho tất cả các loại phần tử.

Chúng tôi có thể thực hiện isElementbằng nguyên mẫu. Đây là lời khuyên của tôi:

/**
 * @description detect if obj is an element
 * @param {*} obj
 * @returns {Boolean}
 * @example
 * see below
 */
function isElement(obj) {
  if (typeof obj !== 'object') {
    return false
  }
  let prototypeStr, prototype
  do {
    prototype = Object.getPrototypeOf(obj)
    // to work in iframe
    prototypeStr = Object.prototype.toString.call(prototype)
    // '[object Document]' is used to detect document
    if (
      prototypeStr === '[object Element]' ||
      prototypeStr === '[object Document]'
    ) {
      return true
    }
    obj = prototype
    // null is the terminal of object
  } while (prototype !== null)
  return false
}
console.log(isElement(document)) // true
console.log(isElement(document.documentElement)) // true
console.log(isElement(document.body)) // true
console.log(isElement(document.getElementsByTagName('svg')[0])) // true or false, decided by whether there is svg element
console.log(isElement(document.getElementsByTagName('svg'))) // false
console.log(isElement(document.createDocumentFragment())) // false


1

Tôi nghĩ rằng những gì bạn phải làm là thực hiện một kiểm tra kỹ lưỡng của một số tính năng mà sẽ luôn luôn được trong một phần tử dom, nhưng sự kết hợp của họ sẽ không có khả năng nhất là trong đối tượng khác, như vậy:

var isDom = function (inp) {
    return inp && inp.tagName && inp.nodeName && inp.ownerDocument && inp.removeAttribute;
};

1

Trong Firefox, bạn có thể sử dụng instanceof Node. Điều đó Nodeđược định nghĩa trong DOM1 .

Nhưng điều đó không dễ dàng trong IE.

  1. "instanceof ActiveXObject" chỉ có thể nói rằng đó là một đối tượng gốc.
  2. "typeof document.body.appendChild == 'object'" nói rằng nó có thể là đối tượng DOM, nhưng cũng có thể là một cái gì đó khác có cùng chức năng.

Bạn chỉ có thể đảm bảo đó là phần tử DOM bằng cách sử dụng hàm DOM và bắt nếu có ngoại lệ. Tuy nhiên, nó có thể có tác dụng phụ (ví dụ: thay đổi trạng thái bên trong đối tượng / hiệu năng / rò rỉ bộ nhớ)


1

Có lẽ đây là một sự thay thế? Đã thử nghiệm trong Opera 11, FireFox 6, Internet Explorer 8, Safari 5 và Google Chrome 16.

function isDOMNode(v) {
  if ( v===null ) return false;
  if ( typeof v!=='object' ) return false;
  if ( !('nodeName' in v) ) return false; 

  var nn = v.nodeName;
  try {
    // DOM node property nodeName is readonly.
    // Most browsers throws an error...
    v.nodeName = 'is readonly?';
  } catch (e) {
    // ... indicating v is a DOM node ...
    return true;
  }
  // ...but others silently ignore the attempt to set the nodeName.
  if ( v.nodeName===nn ) return true;
  // Property nodeName set (and reset) - v is not a DOM node.
  v.nodeName = nn;

  return false;
}

Chức năng sẽ không bị đánh lừa bởi vd

isDOMNode( {'nodeName':'fake'} ); // returns false

2
Thử tốt, nhưng xử lý ngoại lệ là một chi phí quá đắt nếu có thể tránh được. Ngoài ra, ES5 cho phép bạn xác định các thuộc tính chỉ đọc cho các đối tượng.
Andy E

1

Đây là những gì tôi đã tìm ra:

var isHTMLElement = (function () {
    if ("HTMLElement" in window) {
        // Voilà. Quick and easy. And reliable.
        return function (el) {return el instanceof HTMLElement;};
    } else if ((document.createElement("a")).constructor) {
        // We can access an element's constructor. So, this is not IE7
        var ElementConstructors = {}, nodeName;
        return function (el) {
            return el && typeof el.nodeName === "string" &&
                 (el instanceof ((nodeName = el.nodeName.toLowerCase()) in ElementConstructors 
                    ? ElementConstructors[nodeName] 
                    : (ElementConstructors[nodeName] = (document.createElement(nodeName)).constructor)))
        }
    } else {
        // Not that reliable, but we don't seem to have another choice. Probably IE7
        return function (el) {
            return typeof el === "object" && el.nodeType === 1 && typeof el.nodeName === "string";
        }
    }
})();

Để cải thiện hiệu suất, tôi đã tạo một chức năng tự gọi chỉ kiểm tra các khả năng của trình duyệt một lần và chỉ định chức năng phù hợp.

Thử nghiệm đầu tiên sẽ hoạt động trong hầu hết các trình duyệt hiện đại và đã được thảo luận ở đây. Nó chỉ kiểm tra nếu phần tử là một thể hiện của HTMLElement. Rất đơn giản.

Cái thứ hai là cái thú vị nhất. Đây là chức năng cốt lõi của nó:

return el instanceof (document.createElement(el.nodeName)).constructor

Nó kiểm tra xem el có phải là một thể hiện của hàm tạo không. Để làm điều đó, chúng ta cần truy cập vào phần tử của phần tử. Đó là lý do tại sao chúng tôi đang thử nghiệm điều này trong if-Statement. IE7 ví dụ thất bại này, bởi vì (document.createElement("a")).constructorundefinedtrong IE7.

Vấn đề với phương pháp này là đó document.createElementthực sự không phải là chức năng nhanh nhất và có thể dễ dàng làm chậm ứng dụng của bạn nếu bạn đang thử nghiệm nhiều yếu tố với nó. Để giải quyết điều này, tôi quyết định lưu trữ các hàm tạo. Đối tượng ElementConstructorscó nodeNames là các khóa với các hàm tạo tương ứng của nó làm các giá trị. Nếu một hàm tạo đã được lưu vào bộ đệm, nó sẽ sử dụng nó từ bộ đệm, nếu không, nó tạo ra Element, lưu trữ hàm tạo của nó để truy cập trong tương lai và sau đó kiểm tra lại nó.

Thử nghiệm thứ ba là dự phòng khó chịu. Nó kiểm tra xem el là một object, có một thuộc nodeTypetính được đặt thành 1và một chuỗi như nodeName. Tất nhiên điều này không đáng tin cậy lắm, tuy nhiên đại đa số người dùng thậm chí không nên quay lại cho đến nay.

Đây là cách tiếp cận đáng tin cậy nhất mà tôi đã đưa ra trong khi vẫn giữ hiệu suất cao nhất có thể.


1

Kiểm tra nếu objkế thừa từ Node .

if (obj instanceof Node){
    // obj is a DOM Object
}

Nút là một Giao diện cơ bản mà HTMLEuity và Text kế thừa.


1

phân biệt một đối tượng js thô từ HTMLE bổ sung

function isDOM (x){
     return /HTML/.test( {}.toString.call(x) );
 }

sử dụng:

isDOM( {a:1} ) // false
isDOM( document.body ) // true

// HOẶC LÀ

Object.defineProperty(Object.prototype, "is",
    {
        value: function (x) {
            return {}.toString.call(this).indexOf(x) >= 0;
        }
    });

sử dụng:

o={}; o.is("HTML") // false o=document.body; o.is("HTML") // true


0

Đây là một mẹo sử dụng jQuery

var obj = {};
var element = document.getElementById('myId'); // or simply $("#myId")

$(obj).html() == undefined // true
$(element).html() == undefined // false

Vì vậy, đặt nó trong một chức năng:

function isElement(obj){

   return (typeOf obj === 'object' && !($(obj).html() == undefined));

}

2
jQuery đang làm nội bộ như elem.nodeType === 1vậy tại sao không lưu chi phí cuộc gọi và phụ thuộc jQuery và chức năng isEuity của bạn tự làm điều đó?
Joseph Lennox

Đó là năm 2016, chỉ cần nói "không".
Thomas McCabe

0

Không can thiệp vào điều này hoặc bất cứ điều gì nhưng đối với các trình duyệt tuân thủ ES5 tại sao không chỉ:

function isDOM(e) {
  return (/HTML(?:.*)Element/).test(Object.prototype.toString.call(e).slice(8, -1));
}

Không hoạt động trên TextNodes và không chắc chắn về Shadow DOM hoặc DocumentFragments, v.v. nhưng sẽ hoạt động trên hầu hết các thành phần thẻ HTML.


0

Điều này sẽ làm việc cho hầu hết mọi trình duyệt. (Không phân biệt giữa các phần tử và nút ở đây)

function dom_element_check(element){
    if (typeof element.nodeType !== 'undefined'){
        return true;
    }
    return false;
}

trước hết, bạn không cần trả về true hoặc return false, chỉ cần trả về câu lệnh if. Thứ hai, điều này sẽ trả về true cho {nodeType: 1}
bluejayke

0

Một phương thức đúng tuyệt đối, kiểm tra mục tiêu là một mã chính của phần tử html thực sự :

    (function (scope) {
        if (!scope.window) {//May not run in window scope
            return;
        }
        var HTMLElement = window.HTMLElement || window.Element|| function() {};

        var tempDiv = document.createElement("div");
        var isChildOf = function(target, parent) {

            if (!target) {
                return false;
            }
            if (parent == null) {
                parent = document.body;
            }
            if (target === parent) {
                return true;
            }
            var newParent = target.parentNode || target.parentElement;
            if (!newParent) {
                return false;
            }
            return isChildOf(newParent, parent);
        }
        /**
         * The dom helper
         */
        var Dom = {
            /**
             * Detect if target element is child element of parent
             * @param {} target The target html node
             * @param {} parent The the parent to check
             * @returns {} 
             */
            IsChildOf: function (target, parent) {
                return isChildOf(target, parent);
            },
            /**
             * Detect target is html element
             * @param {} target The target to check
             * @returns {} True if target is html node
             */
            IsHtmlElement: function (target) {
                if (!X.Dom.IsHtmlNode(target)) {
                    return false;
                }
                return target.nodeType === 1;
            },
            /**
             * Detect target is html node
             * @param {} target The target to check
             * @returns {} True if target is html node
             */
            IsHtmlNode:function(target) {
                if (target instanceof HTMLElement) {
                    return true;
                }
                if (target != null) {
                    if (isChildOf(target, document.documentElement)) {
                        return true;
                    }
                    try {
                        tempDiv.appendChild(target.cloneNode(false));
                        if (tempDiv.childNodes.length > 0) {
                            tempDiv.innerHTML = "";
                            return true;
                        }
                    } catch (e) {

                    }
                }
                return false;
            }
        };
        X.Dom = Dom;
    })(this);

Kiểm tra trong IE 5


0

Mỗi DOMEuity.constructor trả về hàm HTML ... Element () hoặc [Object HTML ... Element] nên ...

function isDOM(getElem){
    if(getElem===null||typeof getElem==="undefined") return false;
    var c = getElem.constructor.toString();
    var html = c.search("HTML")!==-1;
    var element = c.search("Element")!==-1;
    return html&&element;
}

0

Tôi có một cách đặc biệt để làm điều này chưa được đề cập trong các câu trả lời.

Giải pháp của tôi dựa trên bốn bài kiểm tra. Nếu đối tượng vượt qua cả bốn, thì đó là một yếu tố:

  1. Đối tượng không phải là null.

  2. Đối tượng có một phương thức gọi là "appendChild".

  3. Phương thức "appendChild" được kế thừa từ lớp Node và không chỉ là một phương thức mạo danh (một thuộc tính do người dùng tạo với một tên giống hệt nhau).

  4. Đối tượng là của Node Type 1 (Element). Các đối tượng kế thừa các phương thức từ lớp Node luôn là các Nút, nhưng không nhất thiết phải là Các phần tử.

H: Làm cách nào để kiểm tra xem một tài sản nhất định có được thừa kế không và không chỉ là kẻ mạo danh?

Trả lời: Một thử nghiệm đơn giản để xem liệu một phương thức có thực sự được kế thừa từ Node hay không là trước tiên xác minh rằng thuộc tính có một loại "đối tượng" hoặc "hàm". Tiếp theo, chuyển đổi thuộc tính thành một chuỗi và kiểm tra xem kết quả có chứa văn bản "[Mã gốc]". Nếu kết quả trông giống như thế này:

function appendChild(){
[Native Code]
}

Sau đó, phương thức đã được kế thừa từ đối tượng Node. Xem https://davidwalsh.name/detect-native-f ghép

Và cuối cùng, mang tất cả các bài kiểm tra lại với nhau, giải pháp là:

function ObjectIsElement(obj) {
    var IsElem = true;
    if (obj == null) {
        IsElem = false;
    } else if (typeof(obj.appendChild) != "object" && typeof(obj.appendChild) != "function") {
        //IE8 and below returns "object" when getting the type of a function, IE9+ returns "function"
        IsElem = false;
    } else if ((obj.appendChild + '').replace(/[\r\n\t\b\f\v\xC2\xA0\x00-\x1F\x7F-\x9F ]/ig, '').search(/\{\[NativeCode]}$/i) == -1) {
        IsElem = false;
    } else if (obj.nodeType != 1) {
        IsElem = false;
    }
    return IsElem;
}

0
(element instanceof $ && element.get(0) instanceof Element) || element instanceof Element

Điều này sẽ kiểm tra ngay cả khi đó là phần tử jQuery hoặc JavaScript DOM


0

Cách duy nhất để bảo đảm bạn đang kiểm tra HTMLEement thực tế và không chỉ là một đối tượng có cùng thuộc tính với Phần tử HTML, là xác định xem nó có kế thừa từ Node hay không, vì không thể tạo Node () mới trong JavaScript. (trừ khi chức năng Node gốc bị ghi đè, nhưng sau đó bạn không gặp may). Vì thế:

function isHTML(obj) {
    return obj instanceof Node;
}

console.log(
  isHTML(test),
  isHTML(ok),
  isHTML(p),
  isHTML(o),
  isHTML({
    constructor: {
      name: "HTML"
    }
  }),
  isHTML({
    __proto__: {
      __proto__: {
        __proto__: {
          __proto__: {
            constructor: {
              constructor: { 
                name: "Function"
                
              },
              name: "Node"
            }
          }
        }
      }
    }
  }),
)
<div id=test></div>
<blockquote id="ok"></blockquote>
<p id=p></p>
<br id=o>
<!--think of anything else you want--!>

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.