2012-06-22 2 views
12

Я создал пользовательское событие jquery под названием 'loading' в моем приложении. Я хочу добавить элемент маскировки с помощью счетчика, когда это событие будет запущено. Я могу понять эту часть без проблем. Однако некоторые элементы (изображения, входы формы и т. Д.) Не могут добавлять дочерние элементы. Мне нужно выяснить, может ли объект этого события принимать дочерние элементы. Если это невозможно, я добавлю маска spinner & к ее родительскому элементу.Как вы обнаруживаете, может ли элемент html добавлять дочерние узлы?

ответ

5

Вы должны проверить имя:

/*global $, jQuery */ 

function isVoid(el) { 
    var tags = ['area', 'base', 'br', 'col', 'command', 'embed', 'hr', 'img', 'input', 
       'keygen', 'link', 'meta', 'param', 'source', 'track', 'wbr'], 
     i = 0, 
     l, 
     name; 

    if (el instanceof jQuery) { 
     el = el[0]; 
    } 

    name = el.nodeName.toLowerCase(); 

    for (i = 0, l = tags.length; i < l; i += 1) { 
     if (tags[i] === name) { 
      return true; 
     } 
    } 
    return false; 
} 

И использовать его как это:

var el = document.getElementById('el'), 
    elj = $('#el'); 

if (!isVoid(el)) { 
    // append 
} 
+0

indexOf не является перекрестным браузером для массивов: https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/indexOf – Joe

+0

Используйте _.indexOf, если вы поддерживаете IE8 и старше – jasssonpet

+0

Nice. Может быть, стоит добавить '' # text'' на случай, если текстовый узел найдет свой путь. –

1

Вы можете добавить дочерние элементы, они просто не будут визуализированы. Это может звучать как семантическое различие, но это имеет решающее значение для вашей проблемы: DOM не знает, независимо от того, отображается ли конкретный тег или нет.

Лучше всего проверить руководство:

var allowChildren = function(elem) { 
    return ! (elem.nodeName in { INPUT : true, IMG : true }) ; 
}; 
+0

Я никогда не видел, что булева синтаксис. Это действительно? Поэтому я предполагаю, что могу найти спецификацию для элементов void и добавить ее в этот хеш. – demersus

+1

Я думаю, что создание таблицы элементов void станет единственным реальным решением. Хотя я предполагаю, что вы имеете в виду 'return! {Input: true, img: true} [elem.nodeName]' –

+0

http://jsfiddle.net/mblase75/eGyRH/3/ - Chrome позволяет добавить дочерний элемент в ' 'тег, даже если он вообще не отображается. Это видно в отладчике DOM, а не в окне браузера. – Blazemonger

0

http://jsfiddle.net/mblase75/eGyRH/3/ - Chrome позволяет добавить дочерний элемент в тег <input>, хотя он вообще не отображается. Это видно в отладчике DOM, а не в окне браузера.

Однако, я могу проверить это .width() и видеть, что это равно нулю или нет: http://jsfiddle.net/mblase75/eGyRH/4/

alert($('.element').append('<span>asdf</span>').children().width());​ 

Однако, это также будет нулевой ширины, если, например, я добавляю промежуток к скрытым div: http://jsfiddle.net/mblase75/eGyRH/5/ - так что это тоже не совсем так.

0

Принятый ответ имеет очень хороший эффект на основе which types of nodes can be void. Он может быть заменен Jquery однострочника:

node.is("area,base,br,col,command,embed,hr,img,input,keygen,link,meta,param,source,track,wbr")

Смежные вопросы