contenteditable(非输入标签)的html datalist

时间:2017-01-14 20:45:41

标签: javascript html html5 dom

我想知道是否有任何人可能知道哪种黑客方式允许HTML Iterating-over-arrays repo元素与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>

datalist

它似乎只与<input>元素绑定。 在我的情况下,我有一个javascript插件,它隐藏了一个输入字段并用span替换它,用于一些只能用常规DOM元素完成的“特殊”事件,例如span。此范围为contenteditable,并且act是对其替换的输入的模拟,而输入则保持隐藏。

1 个答案:

答案 0 :(得分:0)

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

显然,最好的方法是将其转换为语义正确的html,但只要有可能,只需添加该注释以供将来的访问者使用,因为这不是您的用例。

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

这是在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>