Disabled element hover triggers onmouseout

Status
Niet open voor verdere reacties.

Robin S

Gebruiker
Lid geworden
4 dec 2008
Berichten
246
Hallo :)

Ik ben wat aan het expirimenteren met custom dropdowns (zie online voorbeeld). Ik heb listeners toegevoegd ('mouseover' en 'mouseout', zie DropDown.js) die de inhoud uit- resp. inklapt.
Nu staan er in de tweede dropdown een aantal disabled radio inputs. Mij viel op dat ook wanneer je daar overheen komt met de cursor komt de mouseout-listener in actie. Dat is natuurlijk niet de bedoeling :p De content moet gewoon nog zichtbaar blijven ondanks de mouseover van een disabled child element...
Google leverde me helaas weinig nuttige info op. Hebben jullie ideeën voor een (elegante) oplossing?

Groetjes,
Robin


Voorbeeld:
- Firefox (/Chrome?)
- Laden duurt even: AJAX
http://robins.awardspace.com/test/movies/

Relevante source:
http://robins.awardspace.com/test/movies/index.js
http://robins.awardspace.com/test/vistaonline/DropDown.js
 
Great...

Ach, dan maar op de normale manier. Ik heb het probleem even uit de originele context gehaald:

[JS]<html>
<head>
<script type="text/javascript">

//DropDown.js

/**
* @require EventManager EventManager.js
* @require TypeManager TypeManager.js
*/
function DropDown (initialText) {

// EventManager.createEventDispatcher(this);

var value = initialText;
var jsObject = this;

var el = document.createElement("div");
el.addEventListener("mouseover", function () {
content.show();
}, false);
el.addEventListener("mouseout", function () {
content.hide();
}, false);
el.className = "DropDown";

if (initialText === undefined) {
initialText = "";
}

var display = document.createElement("div");
display.addEventListener("click", function () {
content.toggle();
}, false);
display.className = "display";
display.innerHTML = initialText;
el.appendChild(display);

var content = document.createElement("div");
content.addEventListener("click", function () {
display.innerHTML = displayFunction();
value = valueFunction();
// jsObject.dispatchEvent("change");
}, false);
content.className = "content";
el.appendChild(content);

function displayFunction () {
return display.innerHTML;
}
function valueFunction () {
return display.innerHTML;
}

this.__defineGetter__("el", function () {
return el;
});
this.__defineGetter__("value", function () {
return value;
});

this.__defineSetter__("displayFunction", function (f) {
//assert(typeof f == "function", "DropDown::set displayFunction | f is not a function");
displayFunction = f;
});
this.__defineSetter__("valueFunction", function (f) {
assert(typeof f == "function", "DropDown::set valueFunction | f is not a function");
valueFunction = f;
});
this.__defineSetter__("content", function (c) {
if (c instanceof Element) {
content.appendChild(c);
}
else {
assert(!is_undefined(c.length), "DropDown::set content | c is not iteratable");
for (var i = 0; i < c.length; i++) {
content.appendChild(c);
}
}
});

}

</script>
<script type="text/javascript">

//index.js

Element.prototype.show = function () {
switch (this.tagName) {
case "TD": this.style.display = "table-cell"; break;
case "TR": this.style.display = "table-row"; break;
default: this.style.display = "block"; break;
}
}
Element.prototype.hide = function () {
this.style.display = "none";
}
Element.prototype.toggle = function () {
this.style.display = this.style.display == "none" ? "block" : "none";
}
HTMLFormElement.prototype.getValue = function (name) {
var el = this[name];
if (el instanceof NodeList) {
var i = 0;
while (i < el.length && el.checked == false) {
i++;
}
return i == el.length ? null : el.value;
}
else {
//NYI
}
}

window.onload = function () {

var dropdown = new DropDown("Rate here...");
document.body.appendChild(dropdown.el);

//var genreXML = fileManager.get("genres.xml", true);
//var genreList = genreXML.documentElement.getElementsByTagName("genre");
var genreList = ["Action", "Adventure", "Comedy", "Drama", "Family", "Fantasy", "Horror", "Mystery", "Thriller", "Romance"];

var form = document.createElement("form");
dropdown.content = form;

for (var i = 0; i < genreList.length; i++) {
//var genre = new Genre(genreList);
var genre = {
name: genreList
};

var div = document.createElement("div");
form.appendChild(div);

var primary = document.createElement("input");
primary.name = "primary";
primary.type = "radio";
primary.value = genre.name;
div.appendChild(primary);

var secondary = document.createElement("input");
secondary.disabled = true;
secondary.name = "secondary";
secondary.type = "radio";
div.appendChild(secondary);

var span = document.createElement("span");
span.innerHTML = genre.name;
div.appendChild(span);
}

dropdown.displayFunction = function () {
var genre = form.getValue("primary");
return genre === null ? "Rate here..." : genre;
};

}

</script>
<style type="text/css">

/* DropDown.css */

.DropDown {
cursor: default;
font-family: "Segoe UI", "Tahoma", sans-serif;
font-size: 11pt;
width: 300px;
}

.DropDown * {
-moz-user-select: -moz-none;
}

.DropDown .display {
border: 1px solid #BBB;
}

.DropDown .display,
.DropDown .content {
background-color: #FFF;
padding: 5px 10px;
width: 278px;
}

.DropDown .display {
background-image: url("http://lab.aspektas.com/select/dropdown.png");
background-repeat: no-repeat;
background-position: right center;
}

.DropDown .content * {
margin: 3px;
margin-left: 0;
}

.DropDown .content {
border: 1px solid #CCC;
border-top: 0px;
display: none;
position: absolute;
}

</style>
</head>
<body></body>
</html>[/JS]
 
Okay, wauw, ik geloof dat je iets interessants hebt gevonden. Heb eventjes lopen klooien, maar nog geen resultaat...

Ik kan ook compleet geen reden verzinnen waarom een disabled radiobutton dit gedrag heeft. Sterker nog, ik kan er zelfs geen event aan binden! Dit geeft dus geen resultaat:
[JS]secondary.addEventListener('mouseover', function(e)
{
alert(e.currentTarget);
}, true);[/JS]
wat nogal... apart is. Misschien komt het omdat het element 'disabled' is, maar dat zou toch geen events tegen moeten houden?


Misschien is een (zucht, lastige) oplossing om zelf een 'disabled' property bij te houden. Je kan het element stijlen, en 2x een event toevoegen wat een interne property bijhoud.



:thumb:
 
Inderdaad, 't is net alsof er gewoon een gaatje in het omvattende element te zitten op de plaats van zo'n disabled input. Ik kom er trouwens net achter dat ook een enabled input dit gedrag vertoont, met als verschil dat het w�l ook de mouseover vuurt.
In het eerste voorbeeld klapt de dropdown dan zo snel in en uit (wanneer je over de primary-elements komt) dat je het niet door hebt.
Verder heb ik gelezen dat zo'n mouseover of -out event een relatedTarget eigenschap heeft. Hierin blijkt zo'n input (ook disabled) genoemd te worden. Gewoon even testen in de listenerfunctie dus gok ik :)
[JS]<html>
<head>
<script type="text/javascript">

function logEvent (e) {
var t = document.createTextNode(e.type + ": " + e.target + ", " + e.currentTarget + ", " + e.relatedTarget);
var br = document.createElement("br");
document.body.appendChild(t);
document.body.appendChild(br);
}

window.onload = function () {
var container = document.getElementById("container");
container.addEventListener("mouseout", logEvent, false);
container.addEventListener("mouseover", logEvent, false);
};

</script>
<style type="text/css">

#container {
background-color: #DBF6FF;
}

</style>
</head>
<body>
<div id="container">
<form>
<input name="radio" type="radio"/>
<input disabled="disabled" name="radio" type="radio"/>
</form>
</div>
</body>
</html>[/JS]
 
Status
Niet open voor verdere reacties.
Terug
Bovenaan Onderaan