简体   繁体   English

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

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

I would like to know if there's any hackable way anyone might know of which will allow an HTMLdatalist element to work with a contenteditable element and not with an <input> element .我想知道是否有任何人可能知道的任何可破解的方式将允许 HTMLdatalist元素与contenteditable元素一起工作,而不是与<input>元素一起工作

Example code:示例代码:

<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>

fiddle demo小提琴演示

It would seem like it is bound to only with with <input> element.看起来它只能与<input>元素绑定。 In my situation I have javascript plugin which hides an input field and replaces it with a span , for some "special" things that can only be done with a regular DOM element, such as span .在我的情况下,我有一个 javascript 插件,它隐藏了一个输入字段并用span替换它,对于一些只能用常规 DOM 元素完成的“特殊”事情,例如span This span is contenteditable and acts is a simulation for the input it replaces, while the input is kept hidden.这个跨度contenteditable ,其作用是它取代了输入的模拟,而输入保持隐藏。

As far as I'm aware, there is no standard to apply a <datalist> to random elements with the [contenteditable] attribute, or anything other than a input with the [list] attribute.据我所知,没有标准可以将<datalist>应用于具有[contenteditable]属性的随机元素,或者除了具有[list]属性的输入之外的任何元素。 At best, you'd be beholden to how individual browsers choose to implement that spec.充其量,您会受制于各个浏览器如何选择实现该规范。

Obviously, the best medicine is to convert to semantically correct html, but just adding that note for future visitors to do if possible, since that's not your use case.显然,最好的方法是转换为语义正确的 html,但如果可能的话,只需为未来的访问者添加该注释,因为这不是您的用例。

A possible workaround is to spin up an input element during the focusin event, match the styling of the surrounding span, allow the native browser events to fire, and apply the updated value when the input loses focus.一种可能的解决方法是在focusin事件期间启动input元素,匹配周围范围的样式,允许本地浏览器事件触发,并在输入失去焦点时应用更新的值。

Here's how that would look in JavaScript:这是在 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;
    }
});

And some starter styles (although Your Mileage May Vary)和一些入门款式(尽管您的里程可能会有所不同)

[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;
}

Here's a working demo in Stack Snippets & JSFiddle这是 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