Jquery 不会正确更新带有变量 (html) 的文本框

Jquery will not update text box with variable (html) Correctly

本文关键字:html 文本 变量 更新 Jquery      更新时间:2023-09-26

我正在尝试构建一个页面构建器,您可以在其中输入html,它会呈现为div进行预览,您可以编辑div(不是html),它将相应地更新文本区域。我遇到的问题是当我尝试将文本从div 移回文本区域时,某些文本落在包含标签之外。

我制作了一个JSFiddle来向您展示问题所在:

http://jsfiddle.net/7crysb0L/4/

Jquery :-

$('#dohtml').click(function () {
var textAreaVal = $('#myTextArea').val();
$('#myDiv').html(textAreaVal);
});
$('#dotext').click(function () {
var $div = $('#myDiv'),
    isEditable = $div.is('.editable');
$('#myDiv').prop('contenteditable', !isEditable).toggleClass('editable')
});
$('#dosave').click(function () {
var test = $('#myDiv').html();
alert(test);
$('#myTextArea').val(test);
});

.HTML:-

<div id="container">
<textarea id="textinput" placeholder="HTML here"></textarea>
<br/>
<button class="btn btn-primary" id="convert">View</button>
<button class="btn btn-primary" id="edit">Edit Div</button>
<button class="btn btn-primary" id="save">Save Changes</button>
<div id="htmloutput">
</div>
</div>

例如,如果您复制并粘贴此处找到的引导手风琴:

http://www.tutorialspark.com/twitterBootstrap/TwitterBootstrap_Collapsible_Accordion.php

并编辑div 以更改 ahref,如果您在末尾键入,或在开头键入或删除太多,整个div 就会消失。有解决方法吗?

我很确定我知道为什么会发生这种情况:-

当div 的最后一个字符被删除时,div 会自动被删除,这会破坏div 中的 html。

这个小提琴为您的问题提供了另一种答案。它不会使加载的 HTML 可编辑,但允许用户从中选择元素并更改该元素的属性。您可以通过允许插入新属性、删除属性、重写 innerHTML 等来大大扩展它。当您将树遍历到 a 元素时,您可以在不破坏元素结构的情况下调整 href。

http://jsfiddle.net/sm1Lz1jd/

法典:

Javascript:

function recursiveHTMLTraverser(html, el, trace)
{
    var ulNode = document.createElement("ul");
    var html = html.children;
    var elementArray = [];
    for( var i = 0; i < html.length; ++i)
    {
        if (!elementArray[html[i].nodeName])
        {
            elementArray[html[i].nodeName] = [0];
        }
        else
        {
            elementArray[html[i].nodeName].push(elementArray[html[i].nodeName].length);
        }
        var liNode = document.createElement("li");
        var name = "";
        if (html[i].getAttribute("class") || html[i].getAttribute("id") || html[i].getAttribute("name"))
        {    
            name = " (<span>";
            if (html[i].getAttribute("id"))
            {
                name += html[i].getAttribute("id") + "</span>)";
            }
            else if (html[i].getAttribute("class"))
            {
                name += html[i].getAttribute("class") + "</span>)";
            }
            else
            {
                name += html[i].getAttribute("name") + "</span>)";
            }
        }
        var expander = "";
        if (html[i].children.length  > 0)
        {
            expander = "<span class='expander'>+</span>";
        }
        liNode.setAttribute("data-node", html[i].nodeName);
        liNode.setAttribute("data-trace", trace + html[i].nodeName);
        liNode.setAttribute("data-index", elementArray[html[i].nodeName].length-1);
        liNode.innerHTML = "<div>" + expander + html[i].nodeName + name + "</div>";
        ulNode.appendChild(liNode);
        if (html[i].children.length > 0)
        {
            recursiveHTMLTraverser(html[i], liNode, trace + html[i].nodeName + " | ");
        }
    }
    if (ulNode.children.length > 0)
    {
        el.appendChild(ulNode);
    }
}
function loadHTMLNode(e)
{
    if (e.target && e.target.tagName)
    {
        if (e.target.tagName.toLowerCase == "li")
        {
            var source = e.target;
        }
        else if (e.target.className && e.target.className == "expander")
        {
            if (e.target.textContent == "+")
            {
                e.target.textContent = "-";
                e.target.parentElement.parentElement.querySelector("ul").style.display = "block";
            }
            else
            {
                e.target.textContent = "+";
                e.target.parentElement.parentElement.querySelector("ul").style.display = "none";
            }
            return true;
        }
        else
        {
            var source = e.target;
            while(source = source.parentElement)
            {
                if (source.tagName.toLowerCase() == "li")
                {
                    break;
                }
            }
        }
        var selector = source.getAttribute("data-trace").replace(/'|/g, ">");
        document.getElementById("attributeEditor").removeAttribute("data-selector");
        document.getElementById("attributeEditor").removeAttribute("data-index-element");
        document.getElementById("attributeEditor").removeAttribute("data-index-attribute");
        document.getElementById("innerHTMLEditor").value = documentIframe.querySelectorAll(selector)[source.getAttribute("data-index")].innerHTML;
        loadHTMLNodeAttributes(selector, source.getAttribute("data-index"));
    }
}
function loadHTMLNodeAttributes(selector, index)
{
    var element = documentIframe.querySelectorAll(selector)[index];
    var selectElement = document.getElementById("attributeSelector").cloneNode();
    document.getElementById("attributeSelector").removeEventListener("change", changeAttribute(selector, index), false);
    for (var i = 0; i < element.attributes.length; ++i)
    {
        var optionNode = document.createElement("option");
        optionNode.value = i;
        optionNode.textContent = element.attributes[i].name;
        selectElement.appendChild(optionNode);
    }
    document.getElementById("attributeEditor").value = "";
    if (element.attributes.length > 0)
    {
        selectElement.addEventListener("change", changeAttribute(selector, index), false);
        var starter = changeAttribute(selector, index); //mimic call to change function;
        starter.call({value : 0}); //insert object with value 0, to select the first element.
    }
    document.getElementById("attributeSelector").parentElement.replaceChild(selectElement, document.getElementById("attributeSelector"));
}
function changeAttribute(selector, index)
{
    return function(){
        document.getElementById("attributeEditor").value = documentIframe.querySelectorAll(selector)[index].attributes[this.value].value;
        document.getElementById("attributeEditor").setAttribute("data-selector", selector);
        document.getElementById("attributeEditor").setAttribute("data-index-element", index);
        document.getElementById("attributeEditor").setAttribute("data-index-attribute", this.value);
    }
}
function changeAttributeValue(e)
{
    //change the attribute real life.
    if (e.target.hasAttribute("data-selector") && e.target.hasAttribute("data-index-element") && e.target.hasAttribute("data-index-attribute"))
    {
        documentIframe.querySelectorAll(e.target.getAttribute("data-selector"))[e.target.getAttribute("data-index-element")].attributes[e.target.getAttribute("data-index-attribute")].value = document.getElementById("attributeEditor").value;
    }
}
function startHTMLPreview()
{
    documentIframe.write(document.getElementById("myTextArea").value);
    recursiveHTMLTraverser(documentIframe.querySelector("html"), document.getElementById("domTreeDiv"), "");
}
document.getElementById("dohtml").addEventListener("click", startHTMLPreview, false);
document.getElementById("domTreeDiv").addEventListener("click", loadHTMLNode, false);
document.getElementById("attributeEditor").addEventListener("keyup", changeAttributeValue, false);
documentIframe = document.getElementById("myDiv").contentDocument.document || document.getElementById("myDiv").contentDocument;

.HTML:

<textarea id="myTextArea" placeholder="Type here, then click the button to update the div">
</textarea>
<br />
<button id="dohtml">Render HTML</button>
<br /><br />
Element tree:
<div id="domTreeDiv"></div>
<div id="domTreeEditor">
    Attributes:
    <select id="attributeSelector"></select> = <input id="attributeEditor"><br />
    innerHTML: <textarea id="innerHTMLEditor" ></textarea>
</div>
Preview: <br />
<iframe id="myDiv" seamless sandbox="allow-same-origin"></iframe>

.CSS:

    body{
      font-size: 11px;
      font-family: verdana;
    }
    #myDiv {
        border:solid 1px #999;
        border-radius:4px;
        min-height:300px;
        min-width:600px;
        margin-top:1em;
        padding:0.5em;
    }
    #myTextArea {
        min-width:600px;
        height: 200px;
    }
    #domTreeDiv {
        border: 1px solid #e2e2e2;
        border-radius: 3px 3px 3px 3px;
        min-height: 50px;
        max-height: 450px;
    }

    #domTreeDiv ul {
        list-style-type: none;
        padding: 0px 0px 0px 20px;
    }
    #domTreeDiv li > ul {
        display: none;
    }
    #domTreeDiv ul li > div {
        padding: 8px 8px 8px 8px;
        cursor: pointer;
        border: 1px solid transparent;
    }
    #domTreeDiv ul li > div:before {
        content:"";
    }       
    #domTreeDiv li > div:hover {
        padding: 8px 8px 8px 8px;
        cursor: pointer;
        border: 1px solid #BFDFFF;
        background-color: #99CCFF;
    }
    #domTreeDiv li > div > span {
        color: #8C0000;
    }           
    #domTreeDiv li > div > span.expander {
        color: #000000;
        display: inline-block;
        width: 24px;
        height: 100%;
        font-weight: bold;
    }   
    #domTreeDiv li > div > span.expander:hover {
        color: #EEEEEE;
    }   
    #attributeEditor{
      width: 400px;
      padding: 8px 8px 8px 8px;
      margin: 10px 0px 10px 0px;
    }
    #attributeSelector{
      width: 100px;
      padding: 8px 8px 8px 8px;
    }