我正在使用HTML和JavaScript构建富文本/所见即所得编辑器组件。我有一个无序的工具栏项列表,其中包含颜色选择器的图像输入元素。颜色选择器是一个叠加层,显示在输入元素的click事件上。
问题:
我想在工具栏项输入元素丢失焦点时隐藏颜色选择器覆盖。因此,我处理输入元素的模糊事件并在颜色选择器覆盖上调用hide。我也使用了一个轻微的超时,因为输入元素的模糊事件将发生在颜色选择器覆盖内的单击事件处理程序之前。在IE中这一切都很好,但是,在FireFox中,超时需要比我希望的更加充实。
我尝试将输入元素更改为锚点并将叠加层放在里面(在一个相当热闹的尝试中,当单击叠加层时,工具栏项仍然具有焦点)。
人们如何通过正常的下拉菜单来处理这种情况?
谢谢, 本
非常简化的非OOP示例:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
<title>Test</title>
<style type="text/css">
.richTextEditor
{
}
.richTextEditor .toolbar
{
}
.richTextEditor iframe
{
border: 1px solid #000;
background: #FFF;
}
</style>
</head>
<body>
<div id="notes" class="richTextEditor">
<ul class="toolbar">
<li command="bold"><input type="button" value="Bold" /></li>
<li command="foreColor"><input type="button" value="Show Colour Picker" /></li>
</ul>
<iframe frameborder="0"></iframe>
</div>
<script type="text/javascript">
var notes = document.getElementById("notes");
var editorElement = notes.getElementsByTagName("IFRAME")[0];
var colourPicker = null;
function showColourPicker(toolbarItemElement) {
if (!colourPicker) {
colourPicker = document.createElement("DIV");
var red = document.createElement("A");
red.href = "javascript:void(0);";
red.style.backgroundColor = "red";
red.innerHTML = "red";
red.onclick = function() {
var toolbarItemCommand = toolbarItemElement.getAttribute("command");
editorElement.contentWindow.focus();
editorElement.contentWindow.document.execCommand(toolbarItemCommand, false, "rgb(255,0,0)");
editorElement.contentWindow.focus();
colourPicker.style.display = "none";
};
colourPicker.appendChild(red);
document.body.appendChild(colourPicker);
} else {
colourPicker.style.display = "block";
}
toolbarItemElement.getElementsByTagName("INPUT")[0].onblur = function() {
window.setTimeout(function() {
colourPicker.style.display = "none";
}, 100);
};
}
function toolbarItemInputElement_click(e) {
var e = e || window.event;
var target = e.target || e.srcElement;
while (target.tagName != "LI") {
target = target.parentNode;
}
var toolbarItemCommand = target.getAttribute("command");
if (toolbarItemCommand == "foreColor" || toolbarItemCommand == "backColor") {
showColourPicker(target);
} else {
editorElement.contentWindow.focus();
editorElement.contentWindow.document.execCommand(toolbarItemCommand, false, null);
editorElement.contentWindow.focus();
}
if (e.preventDefault) {
e.preventDefault();
} else {
e.cancelBubble = true;
}
return false;
}
window.onload = function() {
// turn on design mode
editorElement.contentWindow.document.designMode = "on";
// attach toolbar item event handlers
var toolbarItemElements = document.getElementsByTagName("LI");
for (var i = 0; i < toolbarItemElements.length; i++) {
var toolbarItemInputElement = toolbarItemElements[i].getElementsByTagName("INPUT")[0];
toolbarItemInputElement.onclick = toolbarItemInputElement_click;
}
};
</script>
</body>
</html>
这是相当随机的,所以如果没有发生,请尝试刷新页面几次。 在Firefox中,我执行以下操作:
100毫秒还不够吗?会是什么?
再次感谢。
答案 0 :(得分:0)
不是将输入元素更改为锚点,而是将输入和叠加层包装在锚点或其他元素中,以触发模糊事件并在其中附加事件处理程序。
我认为您还可以在位于所有工具栏和其他控件上方的元素上使用mousemove事件处理程序,并根据从叠加层或输入移动到除叠加和输入之外的任何内容来更改状态。
对于暂停,我似乎记得有一些理由不使用0ms而是使用1ms。
编辑:添加指向使用mousemove / event delegation更换onblur的讨论的链接。