简体   繁体   中英

Can someone explain how one can use preventDefault as an if expression?

While peer reviewing code to fix a parallax issue in IE, I see this odd little bit of code.

    if (window.navigator.userAgent.indexOf("Trident") >= 0) {
        $('body').mousewheel(function (event, delta) {
            // disable native scroll
            if (event.preventDefault) {
                event.preventDefault();
            } else { // IE fix
                event.returnValue = false;
            };
            $html.stop().animate({
                scrollTop: $html.scrollTop() + (-delta * 500)
            }, 'slow');
        });
    }

The code comes from this site but the author there does not mention how some one could drop the () off the end of a function call and cram it into an if statement. Javascript seems to be okay with this, as it is a very loose language, but I do not understand the concept of what is occuring here?

If this is an IE browser
  when some scrolling happens
    [*what is this?*]
    add jQuery scroll animation to replace it
  done
fi

This is called "feature detection" and is a common pattern used to determine if a client supports a certain API. It's much preferred to "browser detection" , which your first line of code does ( window.navigator.userAgent.indexOf("Trident") >= 0 ). Checking user agent strings is not only a full-time job that is always a moving target, but user agent strings can easily be spoofed and, even when they aren't, they aren't always accurate.

Your particular use case stems from the fact that Internet Explorer did not support preventDefault() prior to IE 9, so if your code needs to work in browsers that support this standard as well as IE 8 or less, you need to stop an event the proper way for the appropriate client.

In JavaScript, object properties are nothing more than keys and "methods" don't technically exist. Functions are first-class citizens (they are data) and can simply be stored in a property like any other data. You can access the function directly (as data) as you would any object property:

 var myObj = { foo:"something", bar:function(){ console.log("bar says hello"); } }; console.log(myObj.foo); // Just accessing the value of the foo property console.log(myObj.bar); // Just accessing the value of the bar property 

But, functions can be invoked and, in JavaScript, the invocation operator is () . So, if you look up something that can be invoked and want to invoke it, just add () on to the end of it:

 var myObj = { foo:"something", bar:function(){ console.log("bar says hello"); } }; myObj.bar(); // Accessing the value of the bar property and invoking the result 

So, if an object has a certain property (key) and you query for it, you will get its value. In the case of what we commonly call "methods", the value would be the function stored in the property. And, if the property (key) doesn't exist, you will get undefined returned to you.

With all that in mind, we can move on to a related topic...

When you retrieve a value, it can be thought of as "truthy" or "falsy", which simply means, if you converted the value to a Boolean, would it convert to true or false . false , empty ( "" ), null , undefined and 0 values are falsy and everything else is truthy.

The following attempts to get the preventDefault property value of the event object.:

// Notice we're not calling the function (no parenthesis)
// We're just retrieving the value of the property
if(event.preventDefault) 

In user-agents that support preventDefault() , the native function will be returned and, because it's in an if condition, it will be converted to a Boolean. It will convert to true here and then the true branch of the if statement is entered. If the property doesn't exist, undefined is returned, which converts to false and the false branch is entered.

Another way to find out if a property exists is the in operator:

if(preventDefault in event)

This checks inherited properties as well as "own" properties on the object.

Here's another example. You'll notice that no where in the following code will foo actually be invoked (you won't see "foo was invoked!" in the console). We're only looking up the value of the foo property:

 var myObj = { foo : function(){ console.log("foo was invoked!"); } }; // Notice were not calling foo (no parenthesis). We're just looking up its value: console.log(myObj.foo); // What about a property that doesn't exist? console.log(myObj.foo2); // undefined // And we can convert that value to a Boolean console.log(Boolean(myObj.foo)); // true console.log(Boolean(myObj.foo2)); // false if(myObj.foo){ console.log("foo exists"); } else { console.log("foo doesn't exist"); } 

It is a guard statement. function s in JavaScript are nothing more than objects, so this code is guarding that preventDefault exists.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM