html datalist for contenteditable(非输入标签)

Posted

技术标签:

【中文标题】html datalist for contenteditable(非输入标签)【英文标题】:html datalist for contenteditable (non-input tag) 【发布时间】:2017-05-30 00:26:35 【问题描述】:

我想知道是否有任何人可能知道的可破解方式允许 html datalist 元素与 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>

fiddle demo

它似乎只与&lt;input&gt; 元素绑定。 在我的情况下,我有一个隐藏输入字段并将其替换为spanjavascript 插件,用于一些只能使用常规 DOM 元素完成的“特殊”事情,例如span。这个 span 是 contenteditable,acts 是对它替换的输入的模拟,而输入是隐藏的。

【问题讨论】:

【参考方案1】:

据我所知,没有标准可以将&lt;datalist&gt; 应用于具有[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>

【讨论】:

以上是关于html datalist for contenteditable(非输入标签)的主要内容,如果未能解决你的问题,请参考以下文章

<select>与<datalist>的区别

无法使用 jquery 获取 datalist 中的数组数据

html5中datalist标签怎么用

请问一下HTML中,datalist元素有啥特性?

html中select和datalist功能有啥区别?

datalist嵌套子datalist获取不到ID的值