我想知道是否有任何人可能知道哪种黑客方式允许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>
它似乎只与<input>
元素绑定。
在我的情况下,我有一个javascript插件,它隐藏了一个输入字段并用span
替换它,用于一些只能用常规DOM元素完成的“特殊”事件,例如span
。此范围为contenteditable
,并且act是对其替换的输入的模拟,而输入则保持隐藏。
答案 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;
}
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>