繁体   English   中英

contenteditable 的 html 数据列表(非输入标签)

[英]html datalist for contenteditable (non-input tag)

我想知道是否有任何人可能知道的任何可破解的方式将允许 HTMLdatalist元素与contenteditable元素一起工作,而不是与<input>元素一起工作

示例代码:

<label>Choose a browser from this list:
  <span contenteditable list="browsers" name="myBrowser">choose</span> 
</label>
<datalist id="browsers">
  <option value="Chrome">
  <option value="Firefox">
  <option value="Internet Explorer">
  <option value="Opera">
  <option value="Safari">
  <option value="Microsoft Edge">
</datalist>

小提琴演示

看起来它只能与<input>元素绑定。 在我的情况下,我有一个 javascript 插件,它隐藏了一个输入字段并用span替换它,对于一些只能用常规 DOM 元素完成的“特殊”事情,例如span 这个跨度contenteditable ,其作用是它取代了输入的模拟,而输入保持隐藏。

据我所知,没有标准可以将<datalist>应用于具有[contenteditable]属性的随机元素,或者除了具有[list]属性的输入之外的任何元素。 充其量,您会受制于各个浏览器如何选择实现该规范。

显然,最好的方法是转换为语义正确的 html,但如果可能的话,只需为未来的访问者添加该注释,因为这不是您的用例。

一种可能的解决方法是在focusin事件期间启动input元素,匹配周围范围的样式,允许本地浏览器事件触发,并在输入失去焦点时应用更新的值。

这是在 JavaScript 中的样子:

document.addEventListener('focusin', function (event) {
    if (event.target.matches('[contenteditable]')) {
        var editable = event.target

        // get text
        var text = editable.innerText

        // create input
        var input = document.createElement("input");
        input.type = "text";
        input.className = "editable-mirror";
        input.setAttribute("list", "browsers");
        input.value = text;

        editable.appendChild(input);

        input.focus()
    }
});
document.addEventListener('focusout', function (event) {
    if (event.target.matches('.editable-mirror')) {
        var input = event.target
        var editable = input.closest("[contenteditable]")

        // get text
        var text = input.value;

        // destroy input
        input.parentNode.removeChild(input);

        // apply value
        editable.innerText = text;
    }
});

和一些入门款式(尽管您的里程可能会有所不同)

[contenteditable] {
  position: relative;
  border: 1px solid silver;
  padding: 2px 5px;
  display: inline-block;
}

.editable-mirror {
    position: absolute;
    left: -1px;
    top: -1px;
    height: calc(100% + 2px);
    width: calc(100% + 7px);
    padding: 2px 5px;
    margin: 0;
    border: 0;
}

这是 Stack Snippets & JSFiddle 中的一个工作演示

 document.addEventListener('focusin', function (event) { if (event.target.matches('[contenteditable]')) { console.log('focused') var editable = event.target // enter edit mode editable.classList.add("editing") // get text var text = editable.innerText // create input var input = document.createElement("input"); input.type = "text"; input.className = "editable-mirror"; input.setAttribute("list", "browsers"); input.value = text; editable.appendChild(input); input.focus() } }, false); document.addEventListener('focusout', function (event) { if (event.target.matches('.editable-mirror')) { console.log('blur') var input = event.target var editable = input.closest("[contenteditable]") // leave edit mode editable.classList.remove("editing") // get text var text = input.value; // destroy input input.parentNode.removeChild(input); // apply value editable.innerText = text; } }, false);
 [contenteditable] { position: relative; border: 1px solid silver; padding: 2px 5px; } .editable-mirror { position: absolute; left: -1px; top: -1px; height: calc(100% + 2px); width: calc(100% + 12px); padding: 2px 5px; margin: 0; border: 0; font: inherit; }
 <h2>Regular - Input + Datalist</h2> <label>Choose a browser from this list: <input type="text" list="browsers" placeholder="Edit Me" id="regular" /></label> <datalist id="browsers"> <option value="Chrome"/> <option value="Firefox"/> <option value="Internet Explorer"/> <option value="Opera"/> <option value="Safari"/> <option value="Microsoft Edge"/> </datalist> <h2>Workaround - ContentEditable + Datalist</h2> <label>Choose a browser from this list: <span contenteditable list="browsers" name="myBrowser">edit me</span></label>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM