vsy*_*ync 7 html javascript html-input contenteditable html-datalist
我想知道是否有任何非法侵入的方式可能有人知道这将允许HTML数据列表元件的作用,与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>
Run Code Online (Sandbox Code Playgroud)
似乎它只能与<input>元素绑定。在我的情况下,我有一个 javascript 插件,它隐藏了一个输入字段并将其替换为span,对于一些只能使用常规 DOM 元素完成的“特殊”事情,例如span. 这个跨度是contenteditable和行为是它替换的输入的模拟,而输入是隐藏的。
据我所知,没有标准将 a 应用于<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;
}
});
Run Code Online (Sandbox Code Playgroud)
以及一些入门款式(尽管您的里程可能会有所不同)
[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;
}
Run Code Online (Sandbox Code Playgroud)
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);Run Code Online (Sandbox Code Playgroud)
[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;
}Run Code Online (Sandbox Code Playgroud)
<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>Run Code Online (Sandbox Code Playgroud)