Задать свойства для анонимных элементов DOM через JavaScript? - PullRequest
1 голос
/ 08 января 2009

Допустим, я генерирую разметку через код на стороне сервера. Я генерирую кучу тегов HTML, но я хочу добавить пользовательское поведение на стороне клиента.

С помощью JavaScript (если бы у меня была ссылка на узел DOM), я мог бы написать:

var myDOMNode = ...
myDOMNode.myCustomAttribute = "Hi!";

Теперь проблема в том, что я не хочу квалифицировать каждый элемент с уникальным идентификатором только для инициализации данных. И мне действительно странно, что не существует более простого и ненавязчивого способа привязать поведение на стороне клиента.

Если я правильно помню это, то это действительный материал IE.

<div onload="this.myCustomAttribute='Hi!'"></div>

Если бы я смог это сделать, я бы смог получить доступ к его «контексту данных» через идентификатор «myCustomAttribute», который на самом деле и нужен.

Ответы [ 10 ]

1 голос
/ 26 апреля 2012

В HTML5 атрибуты данных HTML5 введены именно для случая.

<!DOCTYPE html>
<div data-my-custom-attribute='Hi!'></div>

теперь работает, проверяя html. Вы можете использовать любое имя, начинающееся с data- в любом количестве.

Существует jQuery .data метод взаимодействия с ними. Используйте .data( key ), чтобы получить, .data(key, value), чтобы установить data-key атрибут. Например,

$('div').each(function () {
     $(this).html($(this).data('myCustomAttribute')).data('processed', 'OK');
});
1 голос
/ 08 января 2009

Прежде всего вы должны получить доступ к пользовательским атрибутам, используя методы getAttribute и setAttribute, если вы хотите, чтобы ваш код работал в других браузерах, отличных от IE.

Что касается вашего вопроса об обработчике событий, который действительно зависит от того, как вы добавляете обработчик событий. Присвоение функции непосредственно элементу в свойстве onXXXX позволит вам получить доступ к элементу через this.

Если вы используете IE attachEvent, вы не можете использовать this, вы можете получить доступ к элементу, который сгенерировал событие, используя event.srcElement, но это может быть дочерний элемент div. Следовательно, вам нужно будет проверить наличие myCustomAttribute и искать предков, пока не найдете его.

1 голос
/ 09 мая 2011

Я оцениваю входные данные, но я наконец-то понял это, и вот как я иду инициализация , которая была занозой на моей стороне.

То, что вы никогда не захотите сделать, - это загрязнить свое глобальное пространство имен набором недолговечных идентификаторов. Каждый раз, когда вы помещаете id="" в элемент, вы делаете именно это (то же самое для любой функции верхнего уровня). Опираясь на jQuery, данные HTML5 и CSS, я нашел решение моей проблемы, которое я считаю довольно элегантным.

Что я делаю, так это то, что я резервирую класс CSS для определенного поведения, а затем использую данные HTML5 для параметризации поведения. Когда документ готов, я запрашиваю документ (используя Query) для класса CSS, который представляет поведение, и инициализирую поведение на стороне клиента.

Я много работал над ASP.NET, и в этом контексте id="" и name="" принадлежат ASP.NET и довольно бесполезны для чего-то еще, кроме внутреннего ASP.NET. Обычно вы получаете доступ к серверному свойству ClientID, к которому вы можете обратиться из клиентского JavaScript, это очень хлопотно. Они сделали это проще в 4.0, но, по сути, я думаю, что это в значительной степени сломано.

Использование этого гибридного CSS, данных HTML5 и jQuery решает эту проблему в целом. Вот пример присоединенного поведения, которое использует регулярные выражения для проверки ввода текстового поля.

<input type="text" class="-input-regex" data-regex="^[a-z]+$" />

А вот и сценарий:

$(function () {

    function checkRegex(inp) {
        if (inp.data("regex").test(inp.val()))
            inp.data("good-value", inp.val());
        else
            inp.val(inp.data("good-value"));
    }

    $(".-input-regex")
        .each(function () {
            // starting with jQuery 1.5 
            // you can get at HTML5 data like this
            var inp = $(this);
            var pattern = inp.data("regex");
            inp.data("regex", new RegExp(pattern));
            checkRegex(inp);
        })
        .keyup(function (e) {
            checkRegex($(this));
        })
        .change(function (e) {
            checkRegex($(this));
        })
        .bind("paste", undefined, function (e) {
            checkRegex($(this));
        })
        ;

});

Абсолютно чисто, без фанков id="" или навязчивой зависимости.

1 голос
/ 08 января 2009

Следующее будет работать, но не проверять:

<div myattribute="myvalue"></div>

Но если вы внедряете его в HTML с помощью Javascript, то, возможно, это вас не касается. В противном случае вы можете использовать что-то вроде jQuery для обработки элементов перед их добавлением в DOM:

$(elements).each(function(){
     $(this).attr('myattribute','myvalue');
});
0 голосов
/ 06 мая 2011

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

var domNode = ...
var myObject = { ... }
$(domNode).data('mydata', mymyObj);

тогда вы можете вызвать данные таким же образом, используя ваш ключ.

var myObect = $(domNode).data('mydata');

Полагаю, вы могли бы также сохранить ссылку на это в этом объекте, но это может быть больше информации, чем вы действительно хотите. Надеюсь, я смогу помочь.

0 голосов
/ 18 февраля 2009

Посмотрите на следующие функции (особенно walk_the_dom one):

// walk_the_DOM visits every node of the tree in HTML source order, starting
// from some given node. It invokes a function,
// passing it each node in turn. walk_the_DOM calls
// itself to process each of the child nodes.
var walk_the_DOM = function walk(node, func) {
    func(node);
    node = node.firstChild;
    while (node) {
        walk(node, func);
        node = node.nextSibling;
    }
};

// getElementsByAttribute takes an attribute name string and an optional
// matching value. It calls walk_the_DOM, passing it a
// function that looks for an attribute name in the
// node. The matching nodes are accumulated in a
// results array.
var getElementsByAttribute = function (att, value) {
    var results = [];

    walk_the_DOM(document.body, function (node) {
        var actual = node.nodeType === 1 && node.getAttribute(att);
        if (typeof actual === 'string' &&
                (actual === value || typeof value !== 'string')) {
            results.push(node);
        }
    });
    return results;
};

Имея две вышеуказанные функции под рукой, теперь мы можем сделать что-то вроде этого:

<a href="#" dreas="">some link</a>
<script>
var els = getElementsByAttribute('dreas');
if (els.length > 0) {
    els[0].innerHTML = 'changed text';
}
</script>

Обратите внимание, как теперь я делаю поиск этого конкретного элемента (который имеет атрибут с именем dreas) без использования идентификатора или имени класса ... или даже имени тега

0 голосов
/ 08 января 2009

Событие onload используется для событий на стороне сервера. Не является частью стандартных событий html-элемента.

0 голосов
/ 08 января 2009
<div style="width:100px;height:100px;border:solid black 1px" myCustomAttribute='Hi!' onclick="alert(myCustomAttribute);"></div>
0 голосов
/ 08 января 2009

Поскольку вы пытаетесь сделать это для нескольких элементов, вы можете попробовать name атрибуты и getElementsByName.

<div name="handleonload">...</div>

window.onload = function () {
    var divs = document.getElementsByName('handleonload');
    for (var i = 0; i < divs.length; i += 1) {
        divs[i].foo = 'bar';
    }
};

В качестве альтернативы, вы можете использовать селекторы , используя библиотеки (такие как jQuery и Prototype) и их соответствующие итераторы. Это также позволит вам выполнять поиск по другим атрибутам (например, class).


Хотя, будьте осторожны с вашей терминологией:

obj.property = value;

<tag attribute="value">
0 голосов
/ 08 января 2009

Как насчет этого?

<script>
    function LoadElement(myDiv)
    {
        alert(this.myCustomAttribute);
    }
</script>

<div onload="LoadElement(this)"></div>

не проверено кстати

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...