You are on page 1of 77

Advantages of JavaScript

• Less server interaction − You can validate user input before


sending the page off to the server. This saves server traffic,
which means less load on your server.
• Immediate feedback to the visitors − They don't have to wait
for a page reload to see if they have forgotten to enter
something.
• Increased interactivity − You can create interfaces that react
when the user hovers over them with a mouse or activates
them via the keyboard.
• Richer interfaces − You can use JavaScript to include such items
as drag-and-drop components and sliders to give a Rich
Interface to your site visitors.
Limitations of JavaScript
• We cannot treat JavaScript as a full-fledged programming
language. It lacks the following important features −
• Client-side JavaScript does not allow the reading or writing of
files. This has been kept for security reason.
• JavaScript cannot be used for networking applications
because there is no such support available.
• JavaScript doesn't have any multithreading or multiprocessor
capabilities.
• Once again, JavaScript is a lightweight, interpreted
programming language that allows you to build interactivity
into otherwise static HTML pages.
JavaScript - Syntax
• JavaScript can be implemented using JavaScript
statements that are placed within the <script>...
</script> HTML tags in a web page.
• You can place the <script> tags, containing your
JavaScript, anywhere within your web page, but it is
normally recommended that you should keep it within
the <head> tags.
• The <script> tag alerts the browser program to start
interpreting all the text between these tags as a script. A
simple syntax of your JavaScript will appear as follows.
JavaScript - Syntax
• <script ...> JavaScript code </script>
Whitespace and Line Breaks
• JavaScript ignores spaces, tabs, and newlines that appear in
JavaScript programs. You can use spaces, tabs, and newlines
freely in your program and you are free to format and indent
your programs in a neat and consistent way that makes the code
easy to read and understand.
• Semicolons are Optional
• Simple statements in JavaScript are generally followed by a
semicolon character, just as they are in C, C++, and Java.
JavaScript, however, allows you to omit this semicolon if each of
your statements are placed on a separate line. For example, the
following code could be written without semicolons.
Comments in JavaScript
• JavaScript supports both C-style and C++-style comments,
Thus −
• Any text between a // and the end of a line is treated as a
comment and is ignored by JavaScript.
• Any text between the characters /* and */ is treated as a
comment. This may span multiple lines.
• JavaScript also recognizes the HTML comment opening
sequence <!--. JavaScript treats this as a single-line comment,
just as it does the // comment.
• The HTML comment closing sequence --> is not recognized by
JavaScript so it should be written as //-->
Comments in JavaScript
• The following example shows how to use
comments in JavaScript.
<script >
<!-- // This is a comment. It is similar to comments in C++
/*
* This is a multiline comment in JavaScript
* It is very similar to comments in C Programming
*/
//-->
</script>
Comments in JavaScript
• For hiding JavaScript codes from old browsers:
• Add "<!--" without the quotes in the code just
after the <script> tag.
• Add "//-->" without the quotes in the code just
before the <script> tag.
• Old browsers will now treat this JavaScript code
as a long HTML comment. While, a browser that
supports JavaScript, will take the "<!--" and "//--
>" as one-line comments.
Warning for Non-JavaScript Browsers

• If you have to do something important using


JavaScript, then you can display a warning
message to the user using <noscript> tags.
• You can add a noscript block immediately
after the script block as follows −
Warning for Non-JavaScript Browsers
<html>
<body>
<script>
<!–
document.write("Hello World!")
//-->
</script>
<noscript>
Sorry...JavaScript is needed to go ahead.
</noscript>
</body>
</html>

Now, if the user's browser does not support JavaScript or JavaScript is not enabled,
then the message from </noscript> will be displayed on the screen.
JavaScript - Placement in HTML File

• There is a flexibility given to include JavaScript


code anywhere in an HTML document.
However the most preferred ways to include
JavaScript in an HTML file are as follows −
Script in <head>...</head> section.
Script in <body>...</body> section.
Script in <body>...</body> and <head>...</head> sections.
Script in an external file and then include in
<head>...</head> section.
JavaScript in <head>...</head> section

• If you want to have a script run on some event, such as


when a user clicks somewhere, then you will place that
script in the head as follows:
<html>
<head>
<script>
<!--
function sayHello()
{
alert("Hello World")
}
//-->
</script>
</head>
<body>
<input type="button" onclick="sayHello()" value="Say Hello" />
</body>
</html>
JavaScript in <body>...</body> section

• If you need a script to run as the page loads so


that the script generates content in the page,
then the script goes in the <body> portion of
the document. In this case, you would not
have any function defined using JavaScript.
Take a look at the following code.
JavaScript in <body>...</body> section

<html
<head>
</head>
<body>
<script>
<!—
document.write("Hello World")
//-->
</script>
<p>This is web page body </p>
</body>
</html>
JavaScript in External File

• As you begin to work more extensively with JavaScript,


you will be likely to find that there are cases where you are
reusing identical JavaScript code on multiple pages of a
site.
• You are not restricted to be maintaining identical code in
multiple HTML files. The script tag provides a mechanism
to allow you to store JavaScript in an external file and then
include it into your HTML files.
• Here is an example to show how you can include an
external JavaScript file in your HTML code using script tag
and its src attribute.
JavaScript in External File
<html>
<head>
<script src="filename.js" >
</script>
</head>
<body> ....... </body>
</html>
• To use JavaScript from an external file source, you need to
write all your JavaScript source code in a simple text file with
the extension ".js" and then include that file as shown above.
• For example, you can keep the following content
in filename.js file and then you can use sayHello function in
your HTML file after including the filename.js file.
JavaScript in External File
For example, you can keep the following content
in filename.js file and then you can use sayHello
function in your HTML file after including the
filename.js file

function sayHello() { alert("Hello World") }


• Primitive data types
Data Types
– Number: integer & floating-point numbers
– Boolean: true or false
– String: a sequence of alphanumeric characters

• Composite data types (or Complex data types)


– Object: a named collection of data
– Array: a sequence of values (an array is actually a predefined object)

• Special data types


– Null: the only value is "null" – to represent nothing.
– Undefined: the only value is "undefined" – to represent the value of an
unintialized variable
Data Types
• Note − JavaScript does not make a distinction
between integer values and floating-point
values. All numbers in JavaScript are
represented as floating-point values. JavaScript
represents numbers using the 64-bit floating-
point format defined by the IEEE 754 standard.

Strings
A string variable can store a sequence of alphanumeric
characters, spaces and special characters.

• Each character is represented using 16 bit


– You can store Chinese characters in a string.

• A string can be enclosed by a pair of single quotes (') or double


quote (").

• Use escaped character sequence to represent special character


(e.g.: \", \n, \t)
Object
• An object is a collection of properties.

• Properties can be variables (Fields) or


Functions (Methods)

var x = {firstName:"John", lastName:"Doe"}; // Object

• There is no "Class" in JavaScript.


JavaScript Data Types
• JavaScript variables can hold many data types:
numbers, strings, objects and more:

var length = 16; // Number


var lastName = "Johnson"; // String
var x = {firstName:"John",
lastName:"Doe"}; // Object
Identifier
• Same as Java/C++ except that it allows an
additional character – '$'.

• Contains only 'A' – 'Z', 'a' – 'z', '0' – '9', '_', '$'
• First character cannot be a digit
• Case-sensitive
• Cannot be reserved words or keywords
JavaScript Variables
• Like many other programming languages,
JavaScript has variables.
• Variables can be thought of as named containers.
• You can place data into these containers and then
refer to the data simply by naming the container.
• Before you use a variable in a JavaScript program,
you must declare it.
• Variables are declared with the var keyword as
follows.
JavaScript Variables
<script>
<!–
var money;
var name;
//-->
</script>
• You can also declare multiple variables with the
same var keyword as follows:
<script>
<!–
var money, name;
//-->
</script
JavaScript Variables
• Storing a value in a variable is called variable initialization. You
can do variable initialization at the time of variable creation or
at a later point in time when you need that variable.
• For instance, you might create a variable named money and
assign the value 2000.50 to it later. For another variable, you
can assign a value at the time of initialization as follows
<script>
<!–
var money=2000.50;
var name=“Ali”;
//-->
</script>
JavaScript Variables
• JavaScript is untyped language.
• This means that a JavaScript variable can hold a
value of any data type.
• Unlike many other languages, you don't have to
tell JavaScript during variable declaration what
type of value the variable will hold.
• The value type of a variable can change during
the execution of a program and JavaScript takes
care of it automatically.
JavaScript Variable Scope
• The scope of a variable is the region of your
program in which it is defined. JavaScript variables
have only two scopes.
• Global Variables − A global variable has global
scope which means it can be defined anywhere in
your JavaScript code.
• Local Variables − A local variable will be visible only
within a function where it is defined. Function
parameters are always local to that function.
JavaScript Variable Scope

• Within the body of a function, a local variable takes


precedence over a global variable with the same name. If
you declare a local variable or function parameter with the
same name as a global variable, you effectively hide the
global variable. Take a look into the following example.
<html>
<body onload = checkscope();>
<script>
<!–
var myVar = "global"; // Declare a global variable
function checkscope( ) { var myVar = "local"; // Declare a local variable document.write(myVar); }
//--> </script>
</body> </html>
JavaScript Arrays
• JavaScript arrays are used to store multiple values in a
single variable.
• Using an array literal is the easiest way to create a
JavaScript Array.
• Syntax:
var array_name = [item1, item2, ...];
Ex:
var cars = ["Saab", "Volvo", "BMW"];

• Using the JavaScript Keyword new


Array
• An array is represented by the Array object. To
create an array of N elements, you can write
var myArray = new Array(N);

• Index of array runs from 0 to N-1.


• Can store values of different types
• Property "length" tells the # of elements in the
array.
• Consists of various methods to manipulate its
elements. e.g., reverse(), push(),
concat(), etc
Array Examples
var Car = new Array(3);
Car[0] = "Ford";
Car[1] = "Toyota";
Car[2] = "Honda";

// Create an array of three elements with initial


// values
var Car2 = new Array("Ford", "Toyota", "Honda");

// Create an array of three elements with initial


// values
var Car3 = ["Ford", "Toyota", "Honda"];
// An array of 3 elements, each element is undefined
var tmp1 = new Array(3);

// An array of 3 elements with initial values


var tmp2 = new Array(10, 100, -3);

// An array of 3 elements with initial values


// of different types
var tmp3 = new Array(1, "a", true);

// Makes tmp3 an array of 10 elements


tmp3.length = 10; // tmp[3] to tmp[9] are undefined.

// Makes tmp3 an array of 100 elements


tmp3[99] = "Something";
// tmp[3] to tmp[98] are undefined.
JavaScript Reserved Words
Operators
• Arithmetic operators
– +, -, *, /, %

• Post/pre increment/decrement
– ++, --

• Comparison operators
– ==, !=, >, >=, <, <=
– ===, !== (Strictly equals and strictly not equals)
• i.e., Type and value of operand must match / must not
match
Logical Operators
• ! – Logical NOT
• && – Logical AND
– OP1 && OP2
– If OP1 is true, expression evaluates to the value of OP2.
Otherwise the expression evaluates to the value of OP1.
– Results may not be a boolean value.

• || – Logical OR
– OP1 || OP2
– If OP1 is true, expression evaluates to the value of OP1.
Otherwise the expression evaluates to the value of OP2.
var tmp1 = null && 1000; // tmp1 is null

var tmp2 = 1000 && 500; // tmp2 is 500

var tmp3 = false || 500; // tmp3 is 500

var tmp4 = "" || null; // tmp4 is null

var tmp5 = 1000 || false; // tmp5 is 1000

// If foo is null, undefined, false, zero, NaN,


// or an empty string, then set foo to 100.
foo = foo || 100;
Operators (continue)

• String concatenation operator


–+
– If one of the operand is a string, the other operand is
automatically converted to its equivalent string value.

• Assignment operators
– =, +=, -=, *=, /=, %=

• Bitwise operators
– &, |, ^, >>, <<, >>>
Operators (continue)
• Miscellaneous Operator
• We will discuss two operators here that are quite useful in
JavaScript: the conditional operator (? :) and the typeof
operator.
• Conditional Operator (? :)
• The conditional operator first evaluates an expression for a
true or false value and then executes one of the two given
statements depending upon the result of the evaluation.
? : (Conditional )
• If Condition is true? Then value X : Otherwise value Y
== vs ===
// Type conversion is performed before comparison
var v1 = ("5" == 5); // true

// No implicit type conversion.


// True if only if both types and values are equal
var v2 = ("5" === 5); // false

var v3 = (5 === 5.0); // true

var v4 = (true == 1); // true (true is converted to 1)

var v5 = (true == 2); // false (true is converted to 1)

var v6 = (true == "1") // true


typeof operator
var x = "hello", y;
alert("Variable x value is " + typeof x );
alert("Variable y value is " + typeof y );
alert("Variable x value is " + typeof z );

• An unary operator that tells the type of its


operand.
– Returns a string which can be "number", "string",
"boolean", "object", "function", "undefined", and
"null"

– An array is internally represented as an object.


The Concept of Data Types
• In programming, data types is an important concept.
• To be able to operate on variables, it is important to
know something about the type.
• Without data types, a computer cannot safely solve this:
var x = 16 + "Volvo";
• JavaScript will treat the example above as:
var x = "16" + "Volvo";
The Concept of Data Types
• JavaScript evaluates expressions from left to right. Different
sequences can produce different results:
var x = 16 + 4 + "Volvo";
Result:
20Volvo

• JavaScript Types are Dynamic.


• JavaScript has dynamic types. This means that the same variable can
be used to hold different data types:

The Concept of Data Types
• JavaScript Types are Dynamic.
• JavaScript has dynamic types. This means that
the same variable can be used to hold different
data types:
var x; // Now x is undefined
x = 5; // Now x is a Number
x = "John"; // Now x is a String
Null & Undefined
• An undefined value is represented by the
keyword "undefined".
– It represents the value of an uninitialized variable

• The keyword "null" is used to represent


“nothing”
– Declare and define a variable as “null” if you want
the variable to hold nothing.
– Avoid leaving a variable undefined.
Type Conversion (To Boolean)
• The following values are treated as false
– null
– undefined
– +0, -0, NaN (numbers)
– "" (empty string)
Type Conversion
• Converting a value to a number
var numberVar = someVariable – 0;

• Converting a value to a string


var stringVar = someVariable + "";

• Converting a value to a boolean


var boolVar = !!someVariable;
JavaScript / JScript
• Different brands or/and different versions of
browsers may support different implementation
of JavaScript.
– They are not fully compatible

• JScript is the Microsoft version of JavaScript.


Using innerHTML
• To access an HTML element, JavaScript can use
the document.getElementById(id) method.
• The id attribute defines the HTML element.
The innerHTML property defines the HTML content:
• <!DOCTYPE html>
<html>
<body>
<h1>My First Web Page</h1>
<p>My First Paragraph</p>
<p id="demo"></p>

<script>
document.getElementById("demo").innerHTML = 5;
</script>

</body>
</html>
Using document.write()
• For testing purposes, it is convenient to use
document.write():

• <!DOCTYPE html>
<html>
<body>

<h1>My First Web Page</h1>


<p>My first paragraph.</p>

<script>
document.write(5 + 6);
</script>

</body>
</html>
alert() and confirm()
alert("Text to be displayed");
• Display a message in a dialog box.
• The dialog box will block the browser.

var answer = confirm("Are you sure?");


 Display a message in a dialog box with two buttons: "OK" or
"Cancel".
 confirm() returns true if the user click "OK". Otherwise it
returns false.
prompt()
prompt("What is your student id number?");
prompt("What is your name?”, "No name");

• Display a message and allow the user to enter a value


• The second argument is the "default value" to be displayed in
the input textfield.
• Without the default value, "undefined" is shown in the input
textfield.

• If the user click the "OK" button, prompt() returns the


value in the input textfield as a string.
• If the user click the "Cancel" button, prompt() returns null.
alert(), confirm(), and prompt()
<script type="text/javascript">
alert("This is an Alert method");
confirm("Are you OK?");
prompt("What is your name?");
prompt("How old are you?","20");
</script>
HTML (Document Object Model)
DOM
When a web page is loaded, the browser
creates a Document Object Model of the page.
The HTML DOM model is constructed as a tree
of Objects:
HTML (Document Object Model)
DOM

• When a web page is loaded, the browser creates


a Document Object Model of the page.
• The HTML DOM model is constructed as a tree of Objects:
What is the HTML DOM?
• The HTML DOM is a standard object model
and programming interface for HTML. It defines:
• The HTML elements as objects
• The properties of all HTML elements
• The methods to access all HTML elements
• The events for all HTML elements
• In other words: The HTML DOM is a standard for
how to get, change, add, or delete HTML
elements.
HTML DOM Methods

• HTML DOM methods are actions you can perform (on HTML Elements).
• HTML DOM properties are values (of HTML Elements) that you can set or
change.

The HTML DOM can be accessed with JavaScript (and with other
programming languages).
• In the DOM, all HTML elements are defined as objects.
• The programming interface is the properties and methods of each object.
• A property is a value that you can get or set (like changing the content of
an HTML element).
• A method is an action you can do (like add or deleting an HTML element).
Finding HTML Element by Id
• The easiest way to find an HTML element in the DOM, is by using the element id.
• The following example changes the content (the innerHTML) of
the <p> element with id="demo":

<html>
<body>

<p id="demo"></p>

<script>
document.getElementById("demo").innerHTML = "Hello World!";
</script>

</body>
</html>

• In the example above, getElementById is a method,


while innerHTML is a property.
HTML DOM Methods
The getElementById Method
• The most common way to access an HTML element is
to use the id of the element.
• In previous example the getElementById method
used id="demo" to find the element
• The innerHTML property can be used to get or
change any HTML element,
including <html> and <body>
The HTML DOM Document Object
• The document object represents your web page.
• If you want to access any element in an HTML
page, you always start with accessing the
document object.
• Below are some examples of how you can use the
document object to access and manipulate HTML.
Finding HTML Elements
• Method Description document.
• getElementById(id)
Find an element by element id
• document.getElementsByTagName(name)
Find elements by tag name
• document.getElementsByClassName(name)
Find elements by class name
Changing HTML Elements

• element.innerHTML = new html content Change


the inner HTML of an element
• element.attribute = new value
Change the attribute value of an HTML element .
• element.style.property = new style
Change the style of an HTML element
• element.setAttribute(attribute, value)
Change the attribute value of an HTML element
Adding and Deleting Elements
• document.createElement(element)
Create an HTML element.
• Document.removeChild(element)
Remove an HTML element.
document.appendChild(element)
Add an HTML element.
• document.replaceChild(new, old)
Replace an HTML element.
• document.write(text)
Write into the HTML output stream.
Adding Events Handlers
• document.getElementById(id).onclick =
function(){code}
Adding event handler code to an onclick event
Finding HTML Elements
When you want to access HTML elements with JavaScript, you have to
find the elements first.

There are a couple of ways to do this:

• Finding HTML elements by id


• Finding HTML elements by tag name
• Finding HTML elements by class name
• Finding HTML elements by CSS selectors
• Finding HTML elements by HTML object collections
Finding HTML Element by Id
•The easiest way to find an HTML element in the DOM, is by using the
element id.
This example finds the element with id="intro":
<!DOCTYPE html>
<html>
<body>

<h2>JavaScript HTML DOM</h2>

<p id="intro">Finding HTML Elements by Id</p>


<p>This example demonstrates the <b>getElementsById</b> method.</p>

<p id="demo"></p>

<script>
const element = document.getElementById("intro");

document.getElementById("demo").innerHTML =
"The text from the intro paragraph is: " + element.innerHTML;

</script>

</body>
</html>
Finding HTML Elements by Tag Name
<!DOCTYPE html>
<html>
<body>

<h2>JavaScript HTML DOM</h2>

<div id="main">
<p>Finding HTML Elements by Tag Name</p>
<p>This example demonstrates the <b>getElementsByTagName</b> method.</p>
</div>

<p id="demo"></p>

<script>
const x = document.getElementById("main");
const y = x.getElementsByTagName("p");

document.getElementById("demo").innerHTML =
'The first paragraph (index 0) inside "main" is: ' + y[0].innerHTML;

</script>

</body>
</html>
Finding HTML Elements by Class Name
<!DOCTYPE html>
<html>
<body>

<h2>JavaScript HTML DOM</h2>

<p>Finding HTML Elements by Class Name.</p>


<p class="intro">Hello World!</p>
<p class="intro">This example demonstrates the <b>getElementsByClassName</b> method.</p>

<p id="demo"></p>

<script>
const x = document.getElementsByClassName("intro");
document.getElementById("demo").innerHTML =
'The first paragraph (index 0) with class="intro" is: ' + x[0].innerHTML;
</script>

</body>
</html>
Finding HTML Elements by HTML Object
Collections
This example finds the form element with id="frm1", in the forms collection, and displays all element values:
<!DOCTYPE html>
<html>
<body>

<h2>JavaScript HTML DOM</h2>


<p>Finding HTML Elements Using <b>document.forms</b>.</p>

<form id="frm1" action="/action_page.php">


First name: <input type="text" name="fname" value="Donald"><br>
Last name: <input type="text" name="lname" value="Duck"><br><br>
<input type="submit" value="Submit">
</form>

<p>These are the values of each element in the form:</p>

<p id="demo"></p>

<script>
const x = document.forms["frm1"];
let text = "";
for (let i = 0; i < x.length ;i++) {
text += x.elements[i].value + "<br>";
}
document.getElementById("demo").innerHTML = text;
</script>

</body>
</html>
Changing HTML Content
• The easiest way to modify the content of an HTML element is by using the innerHTML property.

<!DOCTYPE html>
<html>
<body>

<h2>JavaScript can Change HTML</h2>

<p id="p1">Hello World!</p>

<script>
document.getElementById("p1").innerHTML = "New text!";
</script>

<p>The paragraph above was changed by a script.</p>

</body>
</html>
Changing the Value of an Attribute
This example changes the value of the src attribute
of an <img> element:

<!DOCTYPE html>
<html>
<body>

<img id="myImage" src="smiley.gif">

<script>
document.getElementById("myImage").src = "landscape.jpg";
</script>

</body>
</html>
Dynamic HTML content

JavaScript can create dynamic HTML content:


<!DOCTYPE html>
<html>
<body>

<p id="demo"></p>

<script>
document.getElementById("demo").innerHTML = "Date : " + Date();
</script>

</body>
</html>
document.write()
In JavaScript, document.write() can be used to write directly to
the HTML output stream:
<!DOCTYPE html>
<html>
<body>

<p>Bla bla bla</p>

<script>
document.write(Date());
</script>

<p>Bla bla bla</p>

</body>
</html>

Never use document.write() after the document is loaded. It will overwrite the document.
JavaScript HTML DOM Events
A JavaScript can be executed when an event occurs, like when a
user clicks on an HTML element.
Examples of HTML events:
• When a user clicks the mouse
• When a web page has loaded
• When an image has been loaded
• When the mouse moves over an element
• When an input field is changed
• When an HTML form is submitted
• When a user strokes a key
JavaScript HTML DOM Events
In this example, the content of the <h1> element is changed
when a user clicks on it:

<!DOCTYPE html>
<html>
<body>

<h2>JavaScript HTML Events</h2>


<h2 onclick="this.innerHTML='Ooops!'">Click on this text!</h2>

</body>
</html
HTML Event Attributes
To assign events to HTML elements you can use event attributes.

<!DOCTYPE html>
<html>
<body>

<h2>JavaScript HTML Events</h2>


<p>Click the button to display the date.</p>

<button onclick="displayDate()">The time is?</button>

<script>
function displayDate() {
document.getElementById("demo").innerHTML = Date();
}
</script>

<p id="demo"></p>

</body>
</html>
Assign Events Using the HTML DOM
The HTML DOM allows you to assign events to HTML elements
using JavaScript.
Example : Assign an onclick event to a button element:
<!DOCTYPE html>
<html>
<body>

<h2>JavaScript HTML Events</h2>


<p>Click "Try it" to execute the displayDate() function.</p>

<button id="myBtn">Try it</button>

<p id="demo"></p>

<script>
document.getElementById("myBtn").onclick = displayDate;

function displayDate() {
document.getElementById("demo").innerHTML = Date();
}
</script>

</body>
</html>
The onmouseover,onmouseout
onmousedown, onmouseup, and onclick
Events
The onmouseover and onmouseout events can be used to trigger a function when the user mouses over,
or out of, an HTML element:

<!DOCTYPE html>
<html>
<body>

<div onmousedown="mDown(this)" onmouseup="mUp(this)"


style="background-color:#D94A38;width:90px;height:20px;padding:40px;">
Click Me</div>

<script>
function mDown(obj) {
obj.style.backgroundColor = "#1ec5e5";
obj.innerHTML = "Release Me";
}

function mUp(obj) {
obj.style.backgroundColor="#D94A38";
obj.innerHTML="Thank You";
}
</script>

</body>
</html> uses over, or out of, an HTML element:

You might also like