动态改变元素的 TagName

Dynamically change element's TagName

根据 jQuery API's Documentation 我使用了正确的事件处理程序。

我也知道 IE 问题,我不在乎,因为这只是一个有趣的实验。

Note: Attempting to change the type property (or attribute) of an input element created via HTML or already in an HTML document will result in an error being thrown by Internet Explorer 6, 7, or 8.

所以我一直在努力让它发挥作用,但我有几个问题:

  1. 这可能吗?
  2. 如果是这样,我做错了什么?我该如何解决?

编辑

我打算将 .selected 的标签从 span 更改为用户指定的任何内容。我最初使用 button 作为示例,但我看到我的 post 是多么容易被误解。因为我的意图是将 span 标记更改为从 buttoninput[type=text] 元素的任何内容。一切都取决于用户在文本框中键入的内容。

我看不出 replaceWidth 在这种情况下对我有何帮助。我怎样才能对此有更多了解?

$(document).ready(function() {
  // Show active tag
  $(".activetag").html( $(".selected").prop("tagName").toLowerCase() );

  // Change selected element's tag
  $(".convert").on("keyup", function() {
    $(".selected").replaceWidth( $("div") ).html( $(".selected").html() );
  });

  // Show selected element's code
  // ex. <span class="selected">Hello world</span>
  $(".code").val( $(".selected").html() );
});
<!DOCTYPE html>
<html>
  <head>
    <title>new document</title>
    <meta charset='utf-8'>
    <meta name='viewport' content='initial-scale=1.0'>
    <meta http-equiv='X-UA-Compatible' content='IE=9' />
    <link type='text/css' rel='stylesheet' href='http://necolas.github.io/normalize.css/3.0.1/normalize.css'/>
    <script type='text/javascript' src='http://code.jquery.com/jquery-latest.min.js'></script>
  </head>
  <body>
    <div align="center">
      <span class="activetag">Hello world</span><br />
      <input type="text" class="convert"><br />
      <span class="selected">Hello world</span><br />
      <textarea class="code"></textarea>
    </div>
  </body>
</html>

所以在了解到您不能直接更改 tagName 本身之后。还有一些方法可以做到这一点。

下面的示例是通过使用隐藏的文本区域来保存 html 并使用文本框、按钮和 .replaceWith 更改我们的标签。这样我们就有了更多的控制权,而不仅仅是使用 keyup。同样,通过这种方式,我不必担心丢失我的元素,而且我还节省了处理能力,因为我没有让浏览器做比它需要做的更多的工作。

Here's fiddle 使用名为 .replaceTagName 的 JQuery 插件。 (这个插件对我的需要来说不是很方便。因为我也想调用 input[type=text] 并且这个插件不允许这样的事情,因为它处理 html 而不是值。但是这个插件可能仍然有帮助其他人)

Here's 下面是相同内容的演示,但我使用的是 conditional/ternary 运算符。

$(document).ready(function() {

  // Change selected element's tag function
  var changeTagName = function() {
    var $val = $(".newtag").val().trim().toLowerCase();

    // If no value is set return to default
    if ($.inArray($val, [""]) > -1) {
      $(".selected").replaceWith( "<span class=\"selected\" \>");
      $(".selected").html( $(".code").val() );
      // Check if it's a textbox
    } else if ($.inArray($val, ["input[type=text]", "input", "textbox"]) > -1) {
      $(".selected").replaceWith( "<input type=\"text\" class=\"selected\" \>");
      $(".selected").val( $(".code").val() );

      // Check if it's an input button
    } else if ( $val === "input[type=button]" ) {
      $(".selected").replaceWith( "<input type=\"button\" class=\"selected\" \>");
      $(".selected").val( $(".code").val() );

      // Check if it's a textarea
    } else if ( $val === "textarea" ) {
      $(".selected").replaceWith( "<" + $val + " class=\"selected\" \>");
      $(".selected").val( $(".code").val() );

      // Use text as a placeholder to make a span tag
    } else if ( $val === "text" ) {
      $(".selected").replaceWith( "<span class=\"selected\" \>");
      $(".selected").html( $(".code").val() );
    } else {

      // Make any others specified
      $(".selected").replaceWith( "<" + $val + " class=\"selected\" \>");
      $(".selected").html( $(".code").val() );
    }

    // Return tagName
    $(".newtag").val( $(".selected").prop("tagName").toLowerCase() );
  };

  // Change tagName from "Enter" Key
  $(document).keydown(function(e) {
    if ($(".newtag").is(":focus")) {
      if (e.which === 13) {
        changeTagName();
      }
    }
  });

  // Change selected element's tag
  $(".convert").on("click", function() {
    changeTagName();
  });

  // Show selected element's code
  // ex. <span class="selected">Hello world</span>
  $(".code").val( $(".selected").html() );
});
.hide {
  display: none;
}
<!DOCTYPE html>
<html>
  <head>
    <title>new document</title>
    <meta charset='utf-8'>
    <meta name='viewport' content='initial-scale=1.0'>
    <meta http-equiv='X-UA-Compatible' content='IE=9' />
    <link type='text/css' rel='stylesheet' href='http://necolas.github.io/normalize.css/3.0.1/normalize.css'/>
    <script type='text/javascript' src='http://code.jquery.com/jquery-latest.min.js'></script>
  </head>
  <body>
    <div align="center">
      <input type="text" class="newtag" placeholder="tagName here..."><br />
      <input type="button" class="convert" value="convert"><br />
      <span class="selected">Hello world</span><br />
      <textarea class="code hide"></textarea>
    </div>
  </body>
</html>

JS改标签名

/**
 * This function replaces the DOM elements's tag name with you desire
 * Example:
 *        replaceElem('header','ram');
 *        replaceElem('div.header-one','ram');
 */
function replaceElem(targetId, replaceWith){
  $(targetId).each(function(){
    var attributes = concatHashToString(this.attributes);
    var replacingStartTag = '<' + replaceWith + attributes +'>';
    var replacingEndTag = '</' + replaceWith + '>';
    $(this).replaceWith(replacingStartTag + $(this).html() + replacingEndTag);
  });
}
replaceElem('div','span');

/**
 * This function concats the attributes of old elements
 */
function concatHashToString(hash){
  var emptyStr = '';
  $.each(hash, function(index){
    emptyStr += ' ' + hash[index].name + '="' + hash[index].value + '"';
  });
  return emptyStr;
}

相关fiddle在这个link

下面是一段小曲:

var el = document.querySelector('.js-the-thing');
var outer = el.outerHTML;
el.parentElement.innerHTML = outer.replace(/(<)(\/)?strong\b/gi, 'em');

示例:将 strong 替换为 em

var outer = "<strong><stronger><strong yes></strong></stronger></strong>";
outer.replace(/(<)(\/)?strong\b/gi, 'em');

"<em><stronger><em yes></em></stronger></em>"

请记住,您会丢失任何附加到元素的事件处理程序,但如果您使用的是在组件级别附加侦听器的标准做法,或者 onclick= 的野蛮做法,你会没事的。

如果您不想替换 所有 类似标记的元素,您也可以使用 .innerHTML 保存它们,然后替换 .innerHTML新元素。