开发者

visibility property not working as expected in javascript function

开发者 https://www.devze.com 2023-01-19 20:42 出处:网络
I have a table: <table> <tr> <td colspan=\"2\"><h2>Order Awards here:</h2></td>

I have a table:

<table>
<tr>
  <td colspan="2"><h2>Order Awards here:</h2></td>
</tr>

<tr>
  <td class="aocBlack">Delivery:</td>
  <td>
    <select style="width: 200px;" id="deliveryMethod" name="deliveryMethod" size="1" onchange="showMailing()">
       <option value="print">I will print it myself.</option>
       <option value="mail">Please mail it to me.</option></select>
  </td>
</tr>

<tr id="messageText" style="">
  <td class="aocBlack" colspan="2">Message to appear on card:</td>
</tr>
<tr id="messageText2" style="">
  <td colspan="2"><textarea id="certMessage" name="certMessage" rows="5" cols="10" style="width: 284px;"></textarea></td>
</tr>
</table>

When the select box called deliveryMethod is set to "print", the following two table rows (id messageText and messageText2) should be visible. When it's set to "mail", they should be hidden. I have some javascript that's worked before with no problem, but the id's I was targeting before were always divs. I don't know if table rows behave differently, but I'm getting some strange results. Here's the JS:

function showMailing(){
    e = document.getElementById("deliveryMethod");
    eVal = e.options[e.selectedIndex].value;

    if (eVal == "mail"){
        document.getElementById("messageText").style.display="none";
        document.getElementById("messageText2").style.display="none";
    }else{
        document.getElementById("messageText").style.display="inline";
        document.getElementById("messageText2").style.display="inline";
    }
}

The results are somewhat strange, to my (admittedly javascript/css-rusty) eyes. For example, when the page initially loads, everything displays as it's supposed to: the开发者_如何转开发 dropdown's default value is "print", and so the two table rows in question display. When you change the dropdown to "mail", they both disappear. But when you change it back, the fields are all pushed over out of where they're supposed to be. These results are consistent across FF and Chrome (strangely it works correctly in IE) so I have to assume I'm doing something wrong, but I don't know what.

Here are some screenshots (note there are a few fields displayed in the screenshot that I've stripped out of the code shown here just for clarity.) Can anyone help me out here?

On initial load:

visibility property not working as expected in javascript function

After changing from print to mail:

visibility property not working as expected in javascript function

After changing back from mail to print:

visibility property not working as expected in javascript function


The default display value for a table row is table-row(*). If you set it to inline instead you'll be asking the browser to draw table cells inside inline text instead of a row, which will confuse it and give unspecified results.

(*: except on IE<8, which don't support the table-related display values, instead setting them all to block and giving the elements themselves magic layout powers.)

The better way do show/hide, where you don't have to worry about what the default display value might be, is to define a class:

.hidden { display: none; }

and then toggle that class on and off the element.

document.getElementById('deliveryMethod').onchange= function() {
    var cls= this.value==='mail'? 'hidden' : '';
    document.getElementById('messageText').className= cls;
    document.getElementById('messageText2').className= cls;
};

Assigning the handler from script allows you to drop the onchange inline attribute. You also don't need size="1" (that goes without saying for a single-select), or the style="".

The business with reading the select's value using this.options[this.selectedIndex].value you probably don't need any more, unless you're dealing with ancient browsers.


function showMailing(){ 
    e = document.getElementById("deliveryMethod"); 
    eVal = e.options[e.selectedIndex].value; 

    if (eVal == "mail"){ 
        document.getElementById("messageText").style.display="none"; 
        document.getElementById("messageText2").style.display="none"; 
    }else{ 
        document.getElementById("messageText").style.display="table-row"; 
        document.getElementById("messageText2").style.display="table-row"; 
    } 
} 


I'd recommend avoiding "eVal" as a variable name, because there's a native JS method called eval(). The capitalization you used is different ("eVal" not "eval"), so it probably won't break things. But it could easily be confusing to a human reader. Also, if you accidentally forget to capitalize the "V" and then need to use the eval() method, it could break your script.

So just in general, avoid using variable names that are similar to the names of existing methods. May I suggest "selectedOption" or "sel" or something?

0

精彩评论

暂无评论...
验证码 换一张
取 消