Thread: Help with some website design...

  1. #16
    Registered User Alpo's Avatar
    Join Date
    Apr 2014
    Posts
    877
    Quote Originally Posted by Nominal Animal View Post
    I'd personally put a fixed search bar at the bottom, with a hotkey assigned to it, and the tabindex of the search entry box would always be 1. There'd be no "search" button, as searching would be re-done every time you modify the search string, and it'd just reassign the tabindex values for each input entry, best matches first, followed by no matches.
    I had thought about suggesting the fixed search bar as part of whatever is containing the form that is being filled out (if I understand correctly, there is only one form). Modifying the tabindex seems like a great idea combined with that. You could have all the inputs in one place, and an easy way to navigate to other places on top of it.
    WndProc = (2[b] || !(2[b])) ? SufferNobly : TakeArms;

  2. #17
    Registered User MutantJohn's Avatar
    Join Date
    Feb 2013
    Posts
    2,665
    Quote Originally Posted by Alpo View Post
    I had thought about suggesting the fixed search bar as part of whatever is containing the form that is being filled out (if I understand correctly, there is only one form). Modifying the tabindex seems like a great idea combined with that. You could have all the inputs in one place, and an easy way to navigate to other places on top of it.
    I agree, I like the idea too.

    And Nominal, I agree. I love/hate jQuery at this stage. JavaScript on its own I was iffy about. I think I like back-end development. PHP is more akin to what I'm used to. JavaScript feels kind of esoteric in my hands right now.

    Alpo, I also wanted to ask, is this really a valid selector in jQuery?
    Code:
    select = $("<select></select>");
    I tried googling it at and I looked at the api's and none of them seem to say that's how you write it. Or am I just misinterpreting the jQuery selector syntax? Like, is this how you declare a variable with jQuery? I thought jQuery was just a JavaScript lib. Why not just use
    Code:
    var select_html = "<select></select>";
    ?

  3. #18
    Registered User Alpo's Avatar
    Join Date
    Apr 2014
    Posts
    877
    Quote Originally Posted by MutantJohn View Post
    Alpo, I also wanted to ask, is this really a valid selector in jQuery?
    Code:
    select = $("<select></select>");
    I tried googling it at and I looked at the api's and none of them seem to say that's how you write it. Or am I just misinterpreting the jQuery selector syntax? Like, is this how you declare a variable with jQuery? I thought jQuery was just a JavaScript lib. Why not just use
    Code:
    var select_html = "<select></select>";
    ?
    Oh no, it's not a selector, it's actually just an easy way that jQuery has of creating a new HTML element. It's similar to the vanilla document.createElement("tag_name") except it returns a wrapped JQuery object. Here is the relevant part from the website:

    If a string is passed as the parameter to $(), jQuery examines the string to see if it looks like HTML (i.e., it starts with <tag ... >). If not, the string is interpreted as a selector expression, as explained above. But if the string appears to be an HTML snippet, jQuery attempts to create new DOM elements as described by the HTML. Then a jQuery object is created and returned that refers to these elements. You can perform any of the usual jQuery methods on this object:
    jQuery() | jQuery API Documentation

    Just from memory, there are 3 things you will usually see passed to the $() function (which is alias for jQuery()):

    1. The listener for $(document).ready(), which fires when the html document has been parsed. Passing this listener to the $() function is just a shorthand for the longer $(document).ready().

    Edit: To explain a bit about why this is necessary, if you ever try running a script straight in the <head> section of a document, you may get confusing exceptions or ReferenceError's telling you that certain elements do not exist. This will happen even if you triple check that the element is actually part of the HTML. What happens is that the browser evaluates your script before the referenced elements have been created. One way to guard against this in vanilla JS, is to wrap your code in the onload listener for the <body> or Window or whatever. However doing this means that your code won't execute until literally everything has been loaded, including large pictures and whatnot. The $(document).ready() listener will execute once the DOM has been parsed, but pictures and whatnot might not be fully loaded, making it faster than the vanilla way (that is the reasoning anyway).

    2. Selectors, there are just your usual tag, class, id selectors. You can do this in vanilla JavaScript with document.getElementsByTagName(), document.querySelector(), document.getElementById(), document.getElementsByClassName(), ect. The return from most of those will either be a NodeList or the element specified. To me this is the main power of jQuery, as you get a consistent interface with the return.

    3. New HTML elements to be created. The return from these are wrapped and ready to be operated on, and since most jQuery can be cascaded, you can bind listener functions, or manipulate CSS properties or regular attributes (the .attr() method) before assigning the new element to its destination.


    There could be more...? Those are the ones I use the most though .

    Edit2: If you have any more syntax questions feel free to ask, it's doing me a service as well to try and explain things.
    Last edited by Alpo; 04-22-2015 at 11:29 AM.
    WndProc = (2[b] || !(2[b])) ? SufferNobly : TakeArms;

  4. #19
    Registered User MutantJohn's Avatar
    Join Date
    Feb 2013
    Posts
    2,665
    Thanks! That was bugging me for so long lol.

  5. #20
    Ticked and off
    Join Date
    Oct 2011
    Location
    La-la land
    Posts
    1,728
    Quote Originally Posted by Alpo View Post
    Edit: To explain a bit about why this is necessary, if you ever try running a script straight in the <head> section of a document, you may get confusing exceptions or ReferenceError's telling you that certain elements do not exist.
    Yup. My preferred solution is the following pattern in the HEAD section:
    Code:
    <script type="text/javascript">
    
     var somefeature = new(function() {
       var internalstatevariable = "some internal state here";
       this.init = function() {
        /* ... */
       };
      });
    
     var isready = false;
     function checkready() {
      if (isready) return;
      isready = true;
      /* Feature init calls here */
      somefeature.init();
     }
     document.onreadystatechange = function() { if (document.readyState == "interactive") checkready(); };
     document.addEventListener("DOMContentLoaded", checkready);
    
    </script>
    This not only encapsulates the features, but also initializes them when the DOM is ready (and not after page load).

    In particular, I like to use variables to hold references to often used unique elements, and use the document.getElementById() at init only. The above encapsulation avoids namespace pollution.

    For a page-internal search machinery, you can scan through the fixed content strings at that point, too, because fixed content (basically DOM element .textContent fields) has been parsed at that point. I think. For future-proofing, I personally might postpone that after the page load, however, using <body onload="mysearchengine.init();"> or document.body.addEventListener("onload", mysearchengine.init); instead to trigger its initialization.

    For elements that are dynamically positioned, I like to add style="display:none;" into the HTML for it, then have the init method find that element and then set the appropriate style, typically element.style.display="block"; or element.style.display="inline";

    It should be obvious that jQuery hides all the browser difference nastiness and lets you avoid having to write all that red tape, but I really do prefer my pages to work when they load, regardless of whether there browser can load some ancillary files or not. Then again, I'm old: I remember the times when I spent hours and hours hand-tuning web pages, so that important parts would be available immediately, and the nonessential niceties like tiled images would not stop the page from being immediately usable.

    To me, SQL error pages and wonky-looking pages because an important CSS or Javascript file failed to load, are an Absolute Affront. Inlining the critical points (layout basics, but not the fine-tuning stuff or old browser workarounds) would not grow the HTML pages themselves by more than a kilobyte or two even for the most complex pages, and that's a tradeoff I'd be always willing to pay for never seeing garbled pages.

    (For me, js.cprogramming.com often delays page loads, especially Preview loads. I hate that.)

  6. #21
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    Code:
    document.onreadystatechange = function() { if (document.readyState == "interactive") checkready(); };
    O_o

    You are really only adding support for "Internet Explorer 8" with the extra line.

    You need a lot more than one shim to really support "Internet Explorer 8".

    I realize that a lot of code is missing because example, but I'd say drop the line for any new source.

    To me, SQL error pages and wonky-looking pages because an important CSS or Javascript file failed to load, are an Absolute Affront. Inlining the critical points (layout basics, but not the fine-tuning stuff or old browser workarounds) would not grow the HTML pages themselves by more than a kilobyte or two even for the most complex pages, and that's a tradeoff I'd be always willing to pay for never seeing garbled pages.
    Preach!

    The overhead of another request is likely to be more expensive than a simple, a CSS foundation, reset.

    You'd probably find that a dumb shunt, a few lines of Javascript to suppress certain problems without providing an actual solution, is similarly less expensive than another request.

    I'm not even talking about getting the actual file data; I'm just talking about the overhead of the HTTP protocol.

    I don't know if you were working in the web at the time, but I remember those dread days when developers started splitting every resource into separate files. You'd see a really ugly page get slightly less ugly as more CSS loaded or slowly become more responsive as the missing Javascript interfaces was slowly shimmed...

    and then something would start blinking...

    Soma
    “Salem Was Wrong!” -- Pedant Necromancer
    “Four isn't random!” -- Gibbering Mouther

  7. #22
    Ticked and off
    Join Date
    Oct 2011
    Location
    La-la land
    Posts
    1,728
    Quote Originally Posted by phantomotap View Post
    You are really only adding support for "Internet Explorer 8" with the extra line.
    Yah, I pulled the example out of my backside, as I haven't made any real JS in a couple of years, and I'm woefully out of date.

    Quote Originally Posted by phantomotap View Post
    I'm not even talking about getting the actual file data; I'm just talking about the overhead of the HTTP protocol.
    Not just HTTP, either.

    When the resources are hosted somewhere else, typically on a content delivery network, the client has to find out the IP address of the host. For the very first contact to a server, the name resolution takes significant time (on the order of a second, depending on the depth of the name, and the locality to authoritative servers). And that has to complete before the request for the CSS/Javascript can even be sent.

    It's the latencies that bite us in the butt.

    Quote Originally Posted by phantomotap View Post
    I don't know if you were working in the web at the time, but I remember those dread days when developers started splitting every resource into separate files. You'd see a really ugly page get slightly less ugly as more CSS loaded or slowly become more responsive as the missing Javascript interfaces was slowly shimmed...
    I was. I worked on various web stuff (not just pages, but also backends and interactive stuff) from 1997 to 2005 or so, plus occasional sites and site engines after that. None in the last two or three years, however.

    One of the adaptive layouts I constructed for an university department included an SVG logo, with a MathML fallback version for IE in a separate HTML file, and a PNG image fallback for that. W̶o̶r̶k̶e̶d̶ Still works like a charm. The background colors etc. are chosen to minimise the perception of glitches, if they occur. (Of course, the pages and CSS also validate correctly, and have mobile stylesheets, although I dunno when those were last tested. Websites ought not be fire-and-forget, in my opinion.) I take huge pride in making my creations robust.

    The advent of Flash ads was worse, as most developers didn't bother creating the layout at the DOM level; as each Flash thingy managed to load, it'd cause a page relayout, and often also play some obnoxious music or sounds... The commercial sites (newspapers, TV channels, channel guides, social sites) were the worst offenders in this part of the world in that respect. Horrible, horrible user experience, unless you had the very latest hardware with a really good internet connection. Then it was just horrible.

    I've mentioned before that I have to browse with NoScript and AdBlock+, because without them I'd get too frustrated/disappointed/angry/aggravated/infuriated to browse at all. Unfortunately, there are lots and lots of pages that will show nothing in that case. I don't mind too much doing the experimentation to find out the visual aggravations I can accept (or drop the site if I cannot), but it's like having a car that is completely unable to unlock its doors unless it has both fuel in the tank and a well-charged battery. In other words, it's just poor design, in my mind.

    It is surprising how poor products people are willing to use and pay for, nowadays. As long as it's polished, it does not matter if it really is just a stinky turd.

    Quote Originally Posted by phantomotap View Post
    and then something would start blinking...
    AAAAaaaargh! No! No! NO! NO! NO!

    The memories, they make my head ache. From the inside.

    I don't know if that is a contributing factor, but nowadays, if I walk towards someone with a blinky bike light at night, I get nauseous, and pretty angry, too. More than once I've thought about building my own pen-flashlight -sized Dazzler..

  8. #23
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    The advent of Flash ads was worse, as most developers didn't bother creating the layout at the DOM level; as each Flash thingy managed to load, it'd cause a page relayout, and often also play some obnoxious music or sounds...
    O_o

    The advertisement frames remain worse.

    I can tolerate a page looking a little out of sorts because the layout expects alignment from missing content, but I can't think of any nonsense on the web that bugs me more than visiting a page with 1KiB of actual content hosting a 2MiB autoplaying advertisement hidden behind some Javascript protecting an unclickable `div' container.

    It is surprising how poor products people are willing to use and pay for, nowadays. As long as it's polished, it does not matter if it really is just a stinky turd.
    The more surprising part, at least to me, is that the polished turd approach is common enough to be part of an actual marketing strategy.

    I'll try to be brief in my example of complaint. I usually whitelist sites I visit a lot. I have no problem with people making money from content. However, one website I used to love played the polished turd game. (I'm not going to name the website because I'd hate to send lookieloo revenue their way.) The site used to have all the content for a relevant article included in a single page fed by a single advertisement. The owners have changed to breaking up the page more and more over the last few years with each page having an advertisement. My last visit found a gorgeous remodeled site; the owners found a lovely new font, the colors popped while remaining soft and pleasing over time, and a new CSS layout responded to the view so the site looked great on a lot of different devices without having crappy "mobile site" nonsense. Every single paragraph was a new advertisement s******g page.

    *shrug*

    Don't even get me started on free-to-play...

    Soma
    “Salem Was Wrong!” -- Pedant Necromancer
    “Four isn't random!” -- Gibbering Mouther

  9. #24
    Registered User MutantJohn's Avatar
    Join Date
    Feb 2013
    Posts
    2,665
    Quote Originally Posted by Nominal Animal View Post
    I'd personally put a fixed search bar at the bottom, with a hotkey assigned to it, and the tabindex of the search entry box would always be 1. There'd be no "search" button, as searching would be re-done every time you modify the search string, and it'd just reassign the tabindex values for each input entry, best matches first, followed by no matches. I'd also show the number of matches on the search bar, and have a "reset" button to clear the input entry, and reset the tab order.

    This way, you start searching by pressing that hotkey, then typing in the search text, then pressing tab (and/or shift+tab) to roll through the entries.

    If the searching is based on fixed contents, I'd definitely just use a specific CSS class for them, and on onload read them all by looping over the entries document.getElementsByClassName() returns, and saving each elements textContent as a string into an array, and the corresponding reference to its target element (select or input element related to it) in another array.
    Otherwise, you'll have to do the search based on the current page contents -- a loop over document.getElementsByClassName() works, although you might need to handle form input elements (containing searched for text) separately.

    If the machines are so slow that the automatic search feels annoying, use a timeout on each search field modification, cancelling the previous one whenever the search field changes. This way you can set the automatic search to start, say, three-quarters of a second after the last change to the search field. You could even use longer timeouts for when the search field is short.

    If you want an example, I could cobble one together. Be warned: I do raw Javascript; I don't like any of the available toolkits, as I prefer my JS on top of a raw browser. No reason, I'm just wonky that way.
    Actually, would you hate me if I did ask you for that small sample?

    I got jQuery's autocomplete widget to work but it's ugly (without CSS) and it adds a butt ton of extra HTML to the document (why?) so I'm curious what other implementations would look like.

  10. #25
    Registered User Alpo's Avatar
    Join Date
    Apr 2014
    Posts
    877
    Quote Originally Posted by phantomotap View Post
    O_o

    The advertisement frames remain worse.

    I can tolerate a page looking a little out of sorts because the layout expects alignment from missing content, but I can't think of any nonsense on the web that bugs me more than visiting a page with 1KiB of actual content hosting a 2MiB autoplaying advertisement hidden behind some Javascript protecting an unclickable `div' container.


    Soma
    The ones I hate the most are the popups that cover an entire page. For instance the other day I had a page loaded with a Raspbian configuration stuff lists on my main computer to help me configure my Raspberry Pi. I had unplugged my keyboard and mouse to use them on the device, then a little ways into it the entire page I was looking at was covered by an add. I ended up just printing it out. (Now I just ssh into the thing so I don't have to unplug anything).
    WndProc = (2[b] || !(2[b])) ? SufferNobly : TakeArms;

  11. #26
    Ticked and off
    Join Date
    Oct 2011
    Location
    La-la land
    Posts
    1,728
    Quote Originally Posted by phantomotap View Post
    visiting a page with 1KiB of actual content hosting a 2MiB autoplaying advertisement hidden behind some Javascript protecting an unclickable `div' container.
    I'm outta those pages faster than my browser can load. I can seriously be without that content, if it means I don't need to suffer through that.

    Quote Originally Posted by MutantJohn View Post
    that small sample?
    Sure.

    On my Firefox (37.0.1) I cannot stop tab from enumerating all user interface elements, so I think we'll just use normal keys instead. Maybe Shift+Up and Shift+Down to skip between matches, Shift+Left to start a new search, and Shift+Right to refine current search? Ideas, opinions?

  12. #27
    Ticked and off
    Join Date
    Oct 2011
    Location
    La-la land
    Posts
    1,728
    Nah, the cursor keys always change the selection; tabIndex is better.

    Here is a really raw example. My Javascript is rusty, so be gentle; however, all comments and especially fixes and enhancement suggestions are highly appreciated.

    Save the page, load it in a browser, and type e.g. per and press Enter, then start tabbing through the results. Use cursor keys to change the option. (On my system, I need to press Alt+Down to expand the list.) To clear the highlights, just search for nothing.
    Code:
    <!DOCTYPE html>
    <html>
     <head>
      <title> Example search widget thingy </title>
      <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
      <style type="text/css">
    
       html {
        padding: 0 0 0 0;
        border: 0 none;
        margin: 0 0 0 0;
        background: #efefef;
        color: #000000;
        font-size: 100%;
        height: 100%;
       }
    
       body {
        padding: 0.5em 1.0em 0.5em 1.0em;
        border: 1px solid #cccccc;
        margin: 0 auto auto auto;
        background: #ffffff;
        color: #000000;
       }
    
       #find_area {
        position: fixed;
        left: 0;
        bottom: 0;
        padding: 0.2em 0.5em 0.2em 0.5em;
        border: 1px solid #000000;
        margin: 0.2em 0.2em 1.2em 0.2em;
       }
    
      </style>
      <script type="text/javascript">
    
       var search_functionality = new (function() {
        var container_element = null;
        var button_element = null;
        var input_element = null;
        var form_element = null;
        var data = null;
        var self = this;
    
        /* This function enumerates all "name" class element contents as lowercase text.
         * The focus target is the child of the next sibling.
        */
        self.do_index = function() {
            data = [];
            var all = document.getElementsByClassName("name");
            for (i = 0; i < all.length; i++)
                data[i] = { text: String(all[i].textContent.toLowerCase()),
                            element: all[i],
                            target: all[i].nextSibling.firstChild };
        };
    
        /* This function highlights and enumerates all matching data objects.
        */
        self.do_find = function(evt) {
            var ev = evt ||..window.event;
            var text = String(input_element.value).toLowerCase();
            var found = 0;
            for (i = 0; i < data.length; i++)
                if (text.length > 0 && data[i].text.contains(text)) {
                    data[i].element.style.background = "#ffcc99";
                    data[i].target.tabIndex = 1 + found;
                    if (++found == 1)
                        data[i].target.focus();
                } else {
                    data[i].element.style.background = "";
                    data[i].target.tabIndex = 0;
                }
            if (found < 1) {
                var len = (input_element.value).length;
                input_element.tabIndex = 1;
                input_element.focus();
                input_element.setSelectionRange(0, len + 1);
            }..else
                input_element.tabIndex = found;
            ev.preventDefault();
            return false;
        };
    
        /* Show and activate search area when typing without focus.
        */
        self.keydown = function(evt) {
            var ev = evt || window.event;
            if (ev.target != document.body) return;
            var len = (input_element.value).length;
            input_element.focus();
            input_element.setSelectionRange(0, len + 1);
        };
    
        self.init = function() {
            form_element = document.getElementById("find_form");
            input_element = document.getElementById("find_text");
            button_element = document.getElementById("find_butt");
            container_element = document.getElementById("find_area");
            self.do_index();
            input_element.tabIndex = 1;
            form_element.onsubmit = self.do_find;
            document.body.addEventListener("keydown", self.keydown, true);
        };
    
       });
    
       document.addEventListener("DOMContentLoaded", search_functionality.init);
      </script>
     </head>
     <body>
    
      <form method="POST" action="#" accept-charset="UTF-8">
       <table>
        <tr><td class="name"> First Person </td><td class="select"><select name="select00001"><option value="" selected="selected"><i>Select...</i></option><option value="Exists">Exists</option><option value="Imaginary">Imaginary</option><option value="Penguin">Penguin</option><option value="Purple">Purple</option><option value="Wet">Wet</option><option value="Owes me Money">Owes me Money</option></td></tr>
        <tr><td class="name"> Second Person </td><td class="select"><select name="select00002"><option value="" selected="selected"><i>Select...</i></option><option value="Exists">Exists</option><option value="Imaginary">Imaginary</option><option value="Penguin">Penguin</option><option value="Purple">Purple</option><option value="Wet">Wet</option><option value="Owes me Money">Owes me Money</option></td></tr>
        <tr><td class="name"> Third Person </td><td class="select"><select name="select00003"><option value="" selected="selected"><i>Select...</i></option><option value="Exists">Exists</option><option value="Imaginary">Imaginary</option><option value="Penguin">Penguin</option><option value="Purple">Purple</option><option value="Wet">Wet</option><option value="Owes me Money">Owes me Money</option></td></tr>
        <tr><td class="name"> Outta Ideas </td><td class="select"><select name="select00004"><option value="" selected="selected"><i>Select...</i></option><option value="Exists">Exists</option><option value="Imaginary">Imaginary</option><option value="Penguin">Penguin</option><option value="Purple">Purple</option><option value="Wet">Wet</option><option value="Owes me Money">Owes me Money</option></td></tr>
        <tr><td class="name"> Late Night </td><td class="select"><select name="select00005"><option value="" selected="selected"><i>Select...</i></option><option value="Exists">Exists</option><option value="Imaginary">Imaginary</option><option value="Penguin">Penguin</option><option value="Purple">Purple</option><option value="Wet">Wet</option><option value="Owes me Money">Owes me Money</option></td></tr>
        <tr><td class="name"> Poor Imagination </td><td class="select"><select name="select00006"><option value="" selected="selected"><i>Select...</i></option><option value="Exists">Exists</option><option value="Imaginary">Imaginary</option><option value="Penguin">Penguin</option><option value="Purple">Purple</option><option value="Wet">Wet</option><option value="Owes me Money">Owes me Money</option></td></tr>
        <tr><td class="name"> Don't Be Cruel </td><td class="select"><select name="select00007"><option value="" selected="selected"><i>Select...</i></option><option value="Exists">Exists</option><option value="Imaginary">Imaginary</option><option value="Penguin">Penguin</option><option value="Purple">Purple</option><option value="Wet">Wet</option><option value="Owes me Money">Owes me Money</option></td></tr>
        <tr><td class="name"> I'm Trying </td><td class="select"><select name="select00008"><option value="" selected="selected"><i>Select...</i></option><option value="Exists">Exists</option><option value="Imaginary">Imaginary</option><option value="Penguin">Penguin</option><option value="Purple">Purple</option><option value="Wet">Wet</option><option value="Owes me Money">Owes me Money</option></td></tr>   </table>
      </form>
    
      <div id="find_area">
       <form id="find_form" method="POST" action="" accept-charset="UTF-8">
        <input id="find_text" type="text" name="q" value="">
        <input id="find_butt" type="submit" name="" value="≫">
       </form>
      </div>
     </body>
    </html>
    Improvement suggestions:
    • Using two hidden elements with tabIndex=1 and tabIndex=N to act as border guards, both refocusing to the search input field when they get the focus event. This might help avoid the annoying case where you start tabbing through the user interface elements.
    • Auto-hide the search area when not needed?
    • Search matches are currently shown using orangey background. Any custom styling of the entire elements will work fine (either the name element, or the dropdown select element).


    Comments? Ideas?

    I think someone less crusty with Javascript than I am might be able to make something workable out of this..

  13. #28
    Registered User MutantJohn's Avatar
    Join Date
    Feb 2013
    Posts
    2,665
    Okay, JavaScript is officially too confusing for me *throws desk over*

    Why does passing the word "event" work? How am I supposed to know the name? And then how am I supposed to know about stuff like keyCode and whatnot?
    Code:
    <!DOCTYPE html>
    <html>
    <head>
        <style>
    #searchBar
    {
        bottom : 2%;
        width : 15%;
        position : fixed;
    }
    
        </style>
        <script>
    function keyboardHandler(e)
    {
        var keynum = 0;
    
        keynum = e.which;
        document.getElementById("searchBar").focus();
    }
        </script>
    </head>
    <body onkeydown="keyboardHandler(event)">
        <table>
            <tr>
                <td>MutantJohn</td>
                <td>
                    <select id="MutantJohn">
                        <option>Yea</option>
                        <option>Nea</option>
                        <option>Not Voting</option>
                        <option>Absent</option>
                        <option>Excused</option>
                    </select>
                </td>
            </tr>
            <tr>
                <td>phantomotap</td>
                <td>
                    <select id="phantomotap">
                        <option>Yea</option>
                        <option>Nea</option>
                        <option>Not Voting</option>
                        <option>Absent</option>
                        <option>Excused</option>
                    </select>
                </td>
            </tr>
            <tr>
                <td>Mario F.</td>
                <td>
                    <select id="Mario F.">
                        <option>Yea</option>
                        <option>Nea</option>
                        <option>Not Voting</option>
                        <option>Absent</option>
                        <option>Excused</option>
                    </select>
                </td>
            </tr>
            <tr>
                <td>Nominal Animal</td>
                <td>
                    <select id="Nominal Animal">
                        <option>Yea</option>
                        <option>Nea</option>
                        <option>Not Voting</option>
                        <option>Absent</option>
                        <option>Excused</option>
                    </select>
                </td>
            </tr>
            <tr>
                <td>Alpo</td>
                <td>
                    <select id="Alpo">
                        <option>Yea</option>
                        <option>Nea</option>
                        <option>Not Voting</option>
                        <option>Absent</option>
                        <option>Excused</option>
                    </select>
                </td>
            </tr>
            <div id="searchDiv">
                <input tabindex="1" id="searchBar"></input>
            </div>
        </table>
    </body>
    </html>

  14. #29
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,612
    Quote Originally Posted by MutantJohn View Post
    Okay, JavaScript is officially too confusing for me *throws desk over*

    Why does passing the word "event" work?
    That's window.event; the window is implied, so you don't even need to type it. All browsers recognize event used in this fashion.

    This works in IE FWIW:
    Code:
    <body onkeydown="keyboardHandler(window.event);">
    So it is just the implied window property.

    How am I supposed to know the name?
    Of the event? Well, you kinda don't need to... all of the onSomething attributes are events and when you write the attribute you are registering the event with a handler function, so you will only have arguments of that kind of event.

    There are actually a few ways to register handlers, and frankly I prefer the way that Nominal showed (DOM Level 2 Events), but even that is not perfect across browsers. This is what makes JS libraries nice. You don't have to deal with cross-browser support.

    And then how am I supposed to know about stuff like keyCode and whatnot?
    A reference? https://developer.mozilla.org/en-US/docs/Web/API/Event

  15. #30
    Registered User Alpo's Avatar
    Join Date
    Apr 2014
    Posts
    877
    Quote Originally Posted by MutantJohn View Post
    Okay, JavaScript is officially too confusing for me *throws desk over*

    Why does passing the word "event" work? How am I supposed to know the name? And then how am I supposed to know about stuff like keyCode and whatnot?
    The handler functions for event are 'callbacks', I mean there is other code that actually calls them. Imagine you had to implement this in C++, you would have a class with a data member that looked something like this:

    Code:
    std::map<std::string, std::function<bool(Event)>> m_listeners
    You could then add a listener anytime during the code, and then while receiving events you would check if any events of that type were registered and then invoke the callback (though now that I think about it, my std::map only holds one listener per event :P). The native code that calls your callback function will construct the event object and call your handler with it. JQuery goes even farther and puts a layer of abstraction between you and the browser callback, constructing it's own event object with cross browser friendliness. The event object will either be referenced by 'event' or in old IE 'window.event'.

    The reason you can include the function as an inline string (onkeydown="keyboardHandler(event)") is because the browser will call 'eval' on it. This invokes the JavaScript compiler directly. You can do this yourself on strings you wish to convert to code, but there are only a few instances where it's not a dangerous idea, and even then it's probably a dangerous idea lol. This is how the modular patterns are made (Common Modules and Asynchronous Module Definitions - AMD). They evaluate a script file and pass the result into either a variable or a callback function.

    There are actually a few ways to find out what members an object has in JavaScript. You can examine them in the debugger (I actually prefer IE's debugger to the FireFox one because it allows highlighting expressions for evaluation). Another simple way is to print it out with a call to JSON.stringify(object), which turns the object into a JSON string (very useful when passing application/json mime type). This won't work for objects that contain circular references though.
    Edit: Also (duh on me), you can use a for in loop to loop through the properties by name and get their values. It's pretty easy to construct a function that recursively prints subobjects as well.

    Code:
    for (var name in object) {
        if (object.hasOwnProperty(name)) {
            //...
        }
    }
    // Use 'hasOwnProperty' to prevent members of the object's prototype from shining through.
    There are quite a few members in the KeyboardEvent object for telling which key has been pressed. The problem I've had with it is that they are almost all labeled as deprecated, and none of them feel very portable to me. I've been preferring the 'key' member, as it's not labeled as deprecated (on an aside, I use MDN for a lot of info):

    https://developer.mozilla.org/en-US/.../KeyboardEvent

    Edit: Holy crap, Whiteflags you ninja'ed me by 30 minutes. It's a good thing I was never in an old western shootout or I would still be sitting around looking at my toes by the time they buried me .
    Last edited by Alpo; 04-22-2015 at 11:54 PM.
    WndProc = (2[b] || !(2[b])) ? SufferNobly : TakeArms;

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 2
    Last Post: 12-11-2012, 12:25 AM
  2. Website Design....again
    By Sentral in forum A Brief History of Cprogramming.com
    Replies: 14
    Last Post: 10-29-2006, 05:47 AM
  3. Website design!
    By Sentral in forum A Brief History of Cprogramming.com
    Replies: 28
    Last Post: 10-07-2006, 12:38 AM
  4. website
    By the Wookie in forum Windows Programming
    Replies: 1
    Last Post: 11-07-2002, 02:25 PM