【问题标题】:jQuery convert DOM element to different typejQuery 将 DOM 元素转换为不同的类型
【发布时间】:2010-02-05 11:40:35
【问题描述】:

我需要将 DOM 元素转换为不同的类型(如在 HTML 标记名称中,a 在本例中为 p),但仍保留所有原始元素属性。在这种情况下,它们是否对新类型有效并不重要。

关于如何做到这一点的任何建议?

我已经研究过只是创建一个新元素并复制属性,但这并非没有它自己的复杂性。在 Firefox 中,DOMElement.attributes 仅包含具有值的属性,但在 IE 中,它会报告该元素的所有可能属性。 attributes 属性本身是只读的,因此无法复制。

【问题讨论】:

  • 创建一个新的副本,除了更改类型,然后删除旧的?
  • @thephpdeveloper 我不明白,那只是克隆元素并替换它,而不是更改 HTML 元素类型。
  • “元素类型”是指标签名称(例如“div”)吗?
  • @J-P 是(为什么是不是合法评论?!?)
  • 这可能是最糟糕的技术之一,但parent.innerHTML = parent.innerHTML.replace("<old", "<new") 怎么样?

标签: javascript jquery dom


【解决方案1】:

Sans-jQuery 解决方案:

function makeNewElementFromElement( tag, elem ) {

    var newElem = document.createElement(tag),
        i, prop,
        attr = elem.attributes,
        attrLen = attr.length;

    // Copy children 
    elem = elem.cloneNode(true);
    while (elem.firstChild) {
        newElem.appendChild(elem.firstChild);
    }

    // Copy DOM properties
    for (i in elem) {
        try {
            prop = elem[i];
            if (prop && i !== 'outerHTML' && (typeof prop === 'string' || typeof prop === 'number')) {
                newElem[i] = elem[i];
            }
        } catch(e) { /* some props throw getter errors */ }
    }

    // Copy attributes
    for (i = 0; i < attrLen; i++) {
        newElem.setAttribute(attr[i].nodeName, attr[i].nodeValue);
    }

    // Copy inline CSS
    newElem.style.cssText = elem.style.cssText;

    return newElem;
}

例如

makeNewElementFromElement('a', someDivElement); // Create anchor from div

【讨论】:

  • 这很好。这对附加到子元素的事件有什么作用?他们也被复制了吗? (我在想 IE 和attachEvent)。 newElem.innerHTML = elem.innerHTML 会更好地服务于第一个 while 循环吗?
  • 这不会复制由attachEventaddEventListener 绑定的事件。 AFAIK,无法访问通过其中任何一种方法注册的事件处理程序。此外,innerHTML 不捕获 DOM 属性,仅捕获属性和内容。
  • 无法获得足够的支持。好答案。没有 jQuery。复制属性。复制 DOM 属性。干得好,可爱!
【解决方案2】:

虽然不是一个完整的解决方案,但逻辑基本上是:

保存现有元素:

var oldElement = $(your selector here);

创建一个新元素并将其插入到您的 oldElement 之前或之后

复制属性

  oldElement.attr().each(function(){
    copy old
    });

更好的是,这里有一个插件示例,可以满足您的需求:

http://plugins.jquery.com/project/getAttributes

【讨论】:

  • 太棒了,就可以了!没有意识到 attr() 会返回所有属性,它通过只返回带有值的属性来修复 IE。
  • @J-P 出于某种原因,我第一次尝试它时它就起作用了,但你说得对,它不能被那个调用(我怪 Firebug ...)
  • 有一个插件可以复制所有属性,如果我找到参考我会添加。
【解决方案3】:

更现代(2020 年以上)的方法是:

function changeTag (element, tag) {
    // prepare the elements
    const newElem = document.createElement(tag)
    const clone = element.cloneNode(true)

    // move the children from the clone to the new element
    while (clone.firstChild) {
      newElem.appendChild(clone.firstChild)
    }

    // copy the attributes
    for (const attr of clone.attributes) {
      newElem.setAttribute(attr.name, attr.value)
    }
    return newElem
  }

与@James 的答案相比,您不需要复制cssText,因为它已经被浏览器处理了。您也不需要字符串/数字 dom 属性,因为它们也已正确迁移。最好只在克隆的节点上工作,而不是两者都(clone 和 elem)

【讨论】:

    猜你喜欢
    • 2010-10-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-13
    • 1970-01-01
    • 2021-12-06
    • 2011-10-30
    相关资源
    最近更新 更多