Avatar billede bearhugx Nybegynder
10. februar 2003 - 01:25 Der er 16 kommentarer og
2 løsninger

sætte eventhandler via programmering driller!

Hejsa eksperter

Jeg har et problem angående en form, som jeg leger lidt med :

Meningen med formen er, at det element, som har fokus har en anden farve end resten, sådan at folk, som måske ikke kan se en blinkende cursor alligevel ved, hvor man er henne:-)

Jeg kunne så gå igang med at putte
  onFocus="changeClass(this,'highlighted');" onBlur="changeClass(this,'normal');"
på alle elementer i formen
(som jeg har gjort på http://www.the-source.dk/accessibleForm/accForm-everyTag.html )

Men jeg tænker at det må kunne gøres lettere ...
F.eks. ville jeg gerne have det sådan at det evt kan programmeres via JavaScript ved hjælp af en funktion
  makeAccessibleForm( formObjekt, highlightClassName, normalClassName );

Så jeg er begyndt at programmere det lidt --- Jeg finder alle elementer i formen (alle input pt) via
  formObjekt.getElementsByTagName("input");
og sætter derefter deres onFocus og onBlur Event Handler ved at tildele en annonym funktion således
  c.onfocus = function fOnFocus() {c.className=clsHighlighted;}

(c = input-elementet i forløkken...)

Nu er der bare sådan, at forløkken åbenbart går fint igennem - den tager alle inputfelter og sætter onFocus og onBlur event-handleren - men når jeg så klikker på et af formens input-felter, så er det altid den sidste i forløkken, som hele tiden modtager den onFocus---

underligt ...
Jeg har lagt kode op på www.the-source.dk

versionen, hvor der er eventhandler på alle tags (men som virker efter hensigten...)
www.the-source.dk/accessibleForm/accForm-everyTag.html

versionen, hvor jeg forsøger at programmerere, men hvor det driller
www.the-source.dk/accessibleForm/accForm-programmed.html

Hvad jeg ønsker er
1) at man forklarer, hvorfor accForm_programmed.html ikke virker efter hensigten
2) evt. giver et hint om, hvordan jeg nemt og effektivt kan sætte eventhandlerne for alle form-elementer som har onFocus/onBlur event -- (i øjeblikket hardcoded til "input-tags only!")


/Søren Munk Skrøder

til sidst et lille sidespørgsmål, som evt. gerne må besvares (men som ikke er nødvendigt) - hvorfor sættes border ikke på et select-element ?
Avatar billede cms Nybegynder
10. februar 2003 - 02:14 #1
Sådan:

    <script type="text/javascript">
    function elementFocus(){
      var element = event.srcElement;
      element.className = element.clsHighlighted;
    }

    function elementBlur(){
      var element = event.srcElement;
      element.className = element.clsNormal;
    }

    function makeAccessibleForm (form, clsHighlighted, clsNormal){
      var elements = form.elements;
      for (var i=0; i<elements.length; i++){
        var element = elements[i];
        element.clsHighlighted = clsHighlighted;
        element.clsNormal = clsNormal;
        element.attachEvent("onfocus", elementFocus);
        element.attachEvent("onblur", elementBlur);
      }
    }

        function initializeDocument() {
            var form = document.getElementById("theForm");
            makeAccessibleForm (form, "highlighted", "normal");
        }
    </script>
Avatar billede olebole Juniormester
10. februar 2003 - 02:21 #2
<ole>

1. Du kan ikke sætte border på et select-element.
2. Hold dig fra at sætte ny klasse, dynamisk. Det er meget resourcekrævende, da hele dokumentet skal reberegnes hvergang
3. Du kan gøre det på denne måde:

<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<script type="text/JavaScript">
var d=document;
function initForm() {
    var prohib, f = document.forms[0];
    prohib = "radio checkbox select";
    for ( i=0; i<f.length; i++ ) {
        if ( prohib.indexOf(f.elements[i].type)==-1 ) {
            f.elements[i].onfocus = function() {
                this.style.border = "1px dashed #000000";
            }
            f.elements[i].onblur = function() {
                this.style.border = "1px solid #000000";
            }
        }
    }
}
window.onload = initForm;
</script>
</head>
<body>

<form name="osvald">
    <input type="text"><br>
    <textarea style="width:300;height:250px"></textarea><br>
    <input type="text"><br>
    <select>
        <option>bla 1</option>
        <option>bla 2</option>
        <option>bla 3</option>
    </select><br>
    <input type="text">
</form>

</body>
</html>

/mvh
</bole>
Avatar billede olebole Juniormester
10. februar 2003 - 02:23 #3
Så bør du naturligvis sætte border i init-funktionens for-løkke:

    for ( i=0; i<f.length; i++ ) {
        if ( prohib.indexOf(f.elements[i].type)==-1 ) {
            f.elements[i].onfocus = function() {
                this.style.border = "1px dashed #000000";
            }
            f.elements[i].onblur = function() {
                this.style.border = "1px solid #000000";
            }
            f.elements[i].style.border = "1px solid #000000";
        }
    }

/mvh
Avatar billede olebole Juniormester
10. februar 2003 - 02:27 #4
Select-elementet modtager ikke border - sådan er det bare  :)
Det er dog ikke det store problem, da det jo er highlighted, når det har fokus.

Jeg undlader også at sætte border på radio-buttons og check-box'e, da det ikke er videre kønt. Det kan du naturligvis rette i strengen her:
  prohib = "radio checkbox select";
/mvh
Avatar billede bearhugx Nybegynder
10. februar 2003 - 04:03 #5
I øjeblikket kan jeg bedst lide cms løsning - men har dog mine reservationer (se nedenfor) - så indtil de er løst holder jeg lige igen med pointsne :-)

olebole >> du siger at skifte class er ressource-krævende - jeg går ud fra, at det så også gælder for cms' version (hvor han også skifter class via className attributten...) [JA/NEJ] ?

Men i din kode er stylen jo hardcoded -- Er der nogen måder, hvormed jeg kan få "det bedste fra begge verdener" - dvs. hvor jeg ikke sætter class dynamisk - men samtidig, hvor jeg kan hente min style i mit stylesheet - og ikke være nødsaget til at skifte script-dynamik ud -bare fordi der bliver valgt andre farver (nyt stylesheet)....

Hvis man går ind og dynamisk ændre [objekt].style attributten (som du jo gør) - tvinger man så ikke browseren til at genberegne dokumentet alligevel -- sæt nu jeg havde følgende kode i stedet (ekstrem kode- men for at sætte eksempel)

      if ( prohib.indexOf(f.elements[i].type)==-1 ) {
            f.elements[i].onfocus = function() {
                this.style.border = "100px dashed #000000"; // MEGA BORDER
            }
            f.elements[i].onblur = function() {
                this.style.border = "1px solid #000000";
            }
        }

Så ville dokumentet da skulle reberegnes igen (mht. visning , positionering osv...) --- Eller er der noget, jeg misforstår ?

/Søren
Avatar billede bearhugx Nybegynder
10. februar 2003 - 04:05 #6
PS : ændring af border understøttes af Opera7
Avatar billede bearhugx Nybegynder
10. februar 2003 - 04:07 #7
sorry - havde lige glemt det vigtigste  - vi prøver igen :

PS : ændring af border <<på select-bokse>> understøttes af Opera7
Avatar billede olebole Juniormester
10. februar 2003 - 04:33 #8
Jaja ... der er til gengæld så meget andet Opera ikke kan. Opera er noget _helt_ for sig selv  :D
7'eren er nogenlunde - men versioner før den, har jeg vanskeligt ved at tage alvorlig.

Ja, du har misforstået det med at hele dokumentet reberegnes. Problemet er, at browseren skal ud og evaluere hele CSS-name-space'et - i modsætning til, når elementet, der skal have skiftet properties på style-objektet er kendt.
Derfor bruges kasse-skift næsten aldrig i professionelle løsninger. IE fraråder det selv kraftigt ... og det er jo i sig selv et særsyn  :o)

Ja, det gælder i højeste grad også cms's eksempel.

Ligesom du inkluderer et stylesheet, kan du jo inkludere en JS-fil, hvor du sætter nogle variabler, du skifter imellem:

---------- include start ---------
var foc, defoc;
foc = "1px dashed #000000";
defoc = "1px solid #000000";
---------- include slut ----------
og så:
    for ( i=0; i<f.length; i++ ) {
        if ( prohib.indexOf(f.elements[i].type)==-1 ) {
            f.elements[i].onfocus = function() {
                this.style.border = foc;
            }
            f.elements[i].onblur = function() {
                this.style.border = defoc;
            }
            f.elements[i].style.border = defoc;
        }
    }

Eller endda:
---------- include start ---------
foc = "this.style.border = '1px dashed #000000'";
defoc = "this.style.border = '1px solid #000000'";
start = "f.elements[i].style.border = '1px solid #000000'";
---------- include slut ----------
og så:
function initForm() {
    var prohib, f = document.forms[0];
    prohib = "radio checkbox select";
    for ( i=0; i<f.length; i++ ) {
        if ( prohib.indexOf(f.elements[i].type)==-1 ) {
            f.elements[i].onfocus = function() {
                eval( foc );
            }
            f.elements[i].onblur = function() {
                eval( defoc );
            }
            eval( start );
        }
    }
}

Så kan du blot fylde på i din include.
/mvh
Avatar billede olebole Juniormester
10. februar 2003 - 04:38 #9
Selvom du måske også har set mig fraråde ukritisk brug af eval() (den er nemlig heller ikke blandt de hurtigste), er denne løsning dog langt at foretrække i dette tilfælde  :)
/mvh
Avatar billede cms Nybegynder
10. februar 2003 - 11:21 #10
Kombinationen:

    <script type="text/javascript">
    function setElementStyle(element, style){
      var element = event.srcElement, es = element.style, s = style;//, estyle = element.elementHighlighted;
      es.backgroundColor = s.backgroundColor;
      es.border = s.border;
      es.color = s.color;
      es.margin = s.margin;
      es.padding = s.padding;
    }

    function elementFocus(){
      var element = event.srcElement;
      setElementStyle(element, element.styleHighlighted);
    }

    function elementBlur(){
      var element = event.srcElement;
      setElementStyle(element, element.styleNormal);
    }
   
    function findRule (ruleName){
      var s = document.styleSheets(0), r = s.rules, l = r.length;
      for (var i=0; i<l; i++){
        if (r(i).selectorText == ("."+ruleName))
          return r(i);
      }
      return null;
    }

    function makeAccessibleForm (form, clsHighlighted, clsNormal){
      var styleHighlighted = findRule(clsHighlighted).style;
      var styleNormal = findRule(clsNormal).style;

      var elements = form.elements;
      for (var i=0; i<elements.length; i++){
        var element = elements[i];
        element.styleHighlighted = styleHighlighted;
        element.styleNormal = styleNormal;
        element.attachEvent("onfocus", elementFocus);
        element.attachEvent("onblur", elementBlur);
      }
    }

        function initializeDocument() {
            var form = document.getElementById("theForm");
            makeAccessibleForm (form, "highlighted", "normal");
        }
    </script>
Avatar billede bearhugx Nybegynder
10. februar 2003 - 12:42 #11
cms >> he he... Sjovt nok var det det samme, som jeg arbejdede med i nat -- Jeg kan ikke henvise til the-source.dk (hvor den ligger) da den er nede pt (min kærste har slukket maskinen :-)

Men efter 4-5 så kan du jo se, at jeg også har tænkt hen i de baner --- Jeg opgav så bare idéen, dajeg konkluderede, at den ikke virker særligt godt i Opera 7

/Søren
Avatar billede bearhugx Nybegynder
10. februar 2003 - 16:21 #12
den omtalte version er her :
  http://www.the-source.dk/accessibleForm/accForm-docCSS.html
Men som sagt virker den ikke i Opera... ;-/

Nuvel ... Der skal vel også snart uddeles points :-))

Jeg går dog lige her og tænker på :
tror/synes i at det ville "hjælpe" på brugervenligheden, hvis teksten "...har bil" blev highlighted, når checkboksen harBil fik fokus --- dvs. at istedet for at selve control-elementet blev highlighted, at det så skete for dens Label --- altså kun ved checkbokse og radioknapper....

Jeg synes nemlig ikke at der er så meget "hjælp", når det fokuserede element er iblandt checkbokse/radioknapper --- for det er jo rigtigt nok hvad du siger OleBole - at control-elementet bliver highlighted ser ikke synderligt godt ud...

/Søren

Hvad synes i ????
Avatar billede cms Nybegynder
10. februar 2003 - 16:50 #13
det kunne man godt. Så kan du bare give label'en en id der minder om dens 'ejer's id
Avatar billede bearhugx Nybegynder
10. februar 2003 - 16:59 #14
Det ikke så meget om man kan gøre det (det ved jeg man kan) - men synes i det vil højne brugervenligheden (hvis det ikke gavner brugervenligheden - eller sikrer et konsistent look, så gider jeg ikke at bruge 'oceaner' af tid på at implementere det....)
Avatar billede cms Nybegynder
10. februar 2003 - 17:04 #15
lige med hensyn til checkboxe og radioknapper vil folk sandsynligvis oftest benytte musen eller en genvej/accesskey, og ikke tabulator. i sidstnævnte tilfælde vil det selvfølgelig være smart nok, men samtidigt vil det også forstyrre det billede man har af hvordan windows-elementer fungerer - nogle vil måske synes det er lidt påklistret og overflødigt. men det kan jo også fungere fint, hvis det passer ind i det overordnede design og sidens måde at kommunikere på (lød det ikke flot? ;o))
Avatar billede bearhugx Nybegynder
10. februar 2003 - 17:11 #16
Min mistanke er velbegrundet så - jeg frygtede nemlig også at det ville blive lidt 'påklistret' -

Nuvel ... point-uddeling!

Fordi i begge er kommet med super input (ikke mindst når man tager tidspunktet i betragtning) så får i begge to, hvad der oprindeligt var udlovet...

dvs. 30 p til jer hver  (og brug dem nu ikke alle på snoller på én gang ;-)

/Søren
Avatar billede cms Nybegynder
10. februar 2003 - 17:42 #17
Super tusind tak :o)
ps: Jeg har fødselsdag i dag, så må jeg ikke godt snolle dem op, hvis jeg nu spørger pænt..? :)
Avatar billede olebole Juniormester
10. februar 2003 - 18:25 #18
Tak for points ... og tak for indvielsen i dine mange, fine overvejelser  ;o)

Til slut skal lige bemærkes, at cms's løsninger kun fungerer i IE - så går du efter noget X-browser (hvad jeg da går ud fra) skal de skrives en del om.
/mvh
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Vi tilbyder markedets bedste kurser inden for webudvikling

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester