JavaScript、DOM模糊/焦点、下拉列表
我正在用HTML和JavaScript构建一个富文本/所见即所得编辑器组件。我有一个无序的工具栏项目列表,其中包含一个颜色选择器的图像输入元素。颜色选择器是一个叠加,显示在输入元素的单击事件上 问题是: 当焦点从工具栏项输入元素丢失时,我希望颜色选择器覆盖隐藏。因此,我处理输入元素的模糊事件,并调用颜色选择器覆盖上的隐藏。我还使用了一个轻微的超时,因为输入元素的模糊事件将在颜色选择器覆盖内的click事件处理程序之前发生。在IE中,这一切都很好,但是在FireFox中,超时需要比我希望的更大 我尝试将输入元素更改为锚点,并将覆盖层放在内部(这是一个相当有趣的尝试,试图说在覆盖层中单击时工具栏项仍然有焦点) 人们倾向于用正常的下拉列表来处理这种情况吗 谢谢, 本 一个极其简化的非OOP示例:JavaScript、DOM模糊/焦点、下拉列表,javascript,html,events,dom,Javascript,Html,Events,Dom,我正在用HTML和JavaScript构建一个富文本/所见即所得编辑器组件。我有一个无序的工具栏项目列表,其中包含一个颜色选择器的图像输入元素。颜色选择器是一个叠加,显示在输入元素的单击事件上 问题是: 当焦点从工具栏项输入元素丢失时,我希望颜色选择器覆盖隐藏。因此,我处理输入元素的模糊事件,并调用颜色选择器覆盖上的隐藏。我还使用了一个轻微的超时,因为输入元素的模糊事件将在颜色选择器覆盖内的click事件处理程序之前发生。在IE中,这一切都很好,但是在FireFox中,超时需要比我希望的更大 我
<!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>
试验
.richTextEditor
{
}
.richTextEditor.toolbar
{
}
.richTextEditor iframe
{
边框:1px实心#000;
背景:#FFF;
}
var notes=document.getElementById(“notes”);
var editorElement=notes.getElementsByTagName(“IFRAME”)[0];
var colorPicker=null;
函数ShowColorPicker(toolbarItemElement){
if(!颜色选择器){
colorPicker=document.createElement(“DIV”);
var red=document.createElement(“A”);
red.href=“javascript:void(0);”;
red.style.backgroundColor=“红色”;
red.innerHTML=“red”;
red.onclick=函数(){
var toolbarItemCommand=toolbarItemElement.getAttribute(“命令”);
editorElement.contentWindow.focus();
editorElement.contentWindow.document.execCommand(toolbarItemCommand,false,“rgb(255,0,0)”;
editorElement.contentWindow.focus();
colorPicker.style.display=“无”;
};
颜色选择器。儿童(红色);
文件.正文.附件(颜色选择器);
}否则{
colorPicker.style.display=“block”;
}
toolbarItemElement.getElementsByTagName(“输入”)[0].onblur=function(){
setTimeout(函数(){
colorPicker.style.display=“无”;
}, 100);
};
}
功能工具栏ItemInputElement\u单击(e){
var e=e | | window.event;
var target=e.target | | e.src元素;
while(target.tagName!=“LI”){
target=target.parentNode;
}
var toolbarItemCommand=target.getAttribute(“命令”);
如果(toolbarItemCommand==“前景色”| | toolbarItemCommand==“背景色”){
showcolowerpicker(目标);
}否则{
editorElement.contentWindow.focus();
editorElement.contentWindow.document.execCommand(toolbarItemCommand,false,null);
editorElement.contentWindow.focus();
}
如果(如默认){
e、 预防默认值();
}否则{
e、 取消气泡=真;
}
返回false;
}
window.onload=函数(){
//打开设计模式
editorElement.contentWindow.document.designMode=“on”;
//附加工具栏项事件处理程序
var toolbarItemElements=document.getElementsByTagName(“LI”);
对于(var i=0;i
这是相当随机的,所以如果不适合您,请尝试几次刷新页面。
在Firefox中,我执行以下操作:
再次感谢。不要将输入元素更改为锚点,而是将输入和覆盖都包装在锚点或其他元素中,以触发模糊事件并将事件处理程序附加到那里 我认为您还可以在工具栏和其他控件之上的元素上使用mousemove事件处理程序,并根据从覆盖或输入移动到覆盖和输入之外的任何内容来更改状态 对于超时,我似乎记得有一些理由不使用0ms,而是使用1ms 编辑:添加有关使用mousemove/event delegation替换onblur的讨论的链接
Fx中的超时延迟要大多少?通常,0毫秒的超时应该足够了,因为它将在线程空闲时执行(在所有事件完成触发和传播之后)。你能发布一些示例源代码吗?我的想法完全正确-我怀疑还有其他事情发生,但不能完全确定它。我会尽快发布一个精简版。谢谢。如果我没有弄错的话,焦点和模糊事件不会冒泡,因此将事件处理程序放在容器元素上而不是输入上会导致事件不会触发。mousemove的想法是正确的,但我是