CHƯƠNG 1. CƠ SỞ LÝ THUYẾT
1.2.1.3. Cách khai báo CSS
Có 3 cách để nhúng CSS vào trang HTML:
Cách 1: nhúng ngày trong thành phần: áp dụng trực tiếp trên một đối tƣợng nhất định bằng thuộc tính style:
Ví dụ:
<span style="font-weight:bold;color:#FF0000;"> Đoạn text cần in đậm, gạch chân, màu đỏ </span>
Cách 2: nhúng vào đầu mỗi trang: Đặt CSS ở đầu trang web để áp dụng kiểu dáng cho toàn bộ trang ấy, khi đó chỉ cần đặt đoạn CSS vào trong cặp thẻ <style> rồi đặt vào trong phần header của web (giữa <head> và </head>):
Ví dụ:
<style type="text/css">
body {font-family: verdana;color:#0000FF;} /* Kiểu chữ trong trang Web là "Verdana", màu chữ thông thường là màu xanh dương */
</style>
Cách 3: gọi 1 tệp từ ngoài vào: Đặt các thuộc tính CSS vào một tệp tin riêng biệt (*.css), khi đó có thể tham chiếu đến từ nhiều trang web khác nhau:
Ví dụ:
<link rel="stylesheet" type="text/css"
href="style.css">
Mức độ ƣu tiên của CSS: gọi tệp css từ ngoài vào < nhúng vào đầu mỗi trang <
nhúng ngay trong thành phần.
Giới thiệu về CSS3 1.2.2.
CSS3 là phiên bản thứ ba của CSS, cũng nhƣ HTML5, CSS3 vẫn đang trong giai đoạn phát triển.CSS3 cung cấp rất nhiều cách thức mới để tạo ra những hiệu ứng khác nhau cho thiết kế của bạn, với một vài thay đổi quan trọng.Sử dụng CSS3 chúng
SVTH: Trần Thị Hồng Ánh – Lớp 09CNTT2 13 ta có thể tạo ra những thiết kế phong phú, dễ tương tác, và đẹp.CSS3 dành cho những ai đang sử dụng những trình duyệt tiên tiến hoặc những ai chuẩn bị sử dụng nó.
CSS3 xuất hiện với nhiều thuộc tính mới, trình bày trang web đẹp hơn tương thích tốt với HTML5, một số thuộc tính mới nhƣ:
Text-shadown: làm đổ bóng chữ.
Box-shadow: làm đổ bóng.
Border và border-radius: bo viền và bo tròn góc.
Rgba(x, y, z, t): tạo màu.
Hướng đối tượng trong CSS (OOCSS) 1.2.3.
OOCSS: viết tắt của Object Oriented Cascading Style Sheet, cũng tương tự như những ngôn ngữ lập trình khác thì CSS cũng có tính chất hướng đối tượng, trước khi tìm hiểu hướng đối tượng trong CSS ta sẽ đi tìm hiểu khái niệm của lập trình hướng đối tƣợng.
Lập trình hướng đối tượng: là kĩ thuật lập trình hỗ trợ công nghệ đối tượng. Lập trình hướng đối tượng được xem là giúp tăng năng suất, đơn giản hóa độ phức tạp khi bảo trì cũng nhƣ mở rộng phần mềm bằng cách cho phép lập trình viên tập trung vào các đối tượng phần mềm ở bậc cao hơn. Ngoài ra, nhiều người còn cho rằng lập trình hướng đối tượng dễ tiếp thu hơn cho những người mới học về lập trình hơn là các phương pháp trước đó.
Hướng đối tượng trong CSS là một mô hình mã hóa phong cách "đối tượng"
hoặc các khối của HTML xác định một phần của một trang web với phong cách cố định, có thể tái sử dụng lại.
CSS tập hợp các tính chất của hướng đối tượng như: kế thừa, và ghi đ . 1.3. JAVASCRIPT
Khái niệm 1.3.1.
JavaScript là 1 ngôn ngữ dạng script thường được sử dụng cho việc lập trình web ở phía client. Nó tuân theo chuẩn ECMAScript. Nó là 1 ngôn ngữ linh động, cú pháp dễ sử dụng nhƣ các ngôn ngữ khác và dễ dàng lập trình.JavaScript không hề liên quan tới ngôn ngữ lập trình Java, đƣợc hầu hết các trình duyệt ngày nay hỗ trợ. Với JavaScript, ứng dụng web của bạn sẽ trở nên vô cùng sinh động, mang tính trực quan và tương tác cao.
SVTH: Trần Thị Hồng Ánh – Lớp 09CNTT2 14 Cú pháp
1.3.2.
1.3.2.1. Khoảng trắng
Dấu cách, tab và ký tự dòng mới sử dụng bên ngoài một chuỗi ký tự đƣợc gọi là khoảng trắng.Khác với C, khoảng trắng trong JavaScript có thể ảnh hưởng trực tiếp tới ý nghĩa của câu lệnh.Sử dụng phương pháp "tự động thêm dấu chấm phẩy", bất cứ một dòng JavaScript nào thích hợp sẽ đƣợc coi là một câu lệnh hợp lệ (giống nhƣ có dấu chấm phẩy trước ký tự dòng mới).
Tuy trong phần lớn trường hợp, dấu chấm phẩy trước khi kết thúc một dòng JavaScript là không cần thiết để đoạn mã nguồn hoạt động chính xác, lập trình viên nên sử dụng dấu chấm phẩy sau mỗi câu lệnh để đoạn mã nguồn dễ nhìn hơn. Ngoài ra, do đặc thù của JavaScript - chuyên dùng trên trang web, kích cỡ của đoạn mã nguồn là quan trọng, có một số phần mềm có thể làm giảm kích cỡ của đoạn mã nguồn JavaScript bằng cách bỏ đi những khoảng trắng không cần thiết, để những phần mềm này hoạt động chính xác, lập trình viên cần thêm dấu chấm phẩy vào cuối mỗi câu lệnh.
1.3.2.2. Chú thích
Cú pháp chú thích của JavaScript giống với C++. Lập trình viên có thể chú giải trên nhiều dòng bằng cách bao bọc chú thích với /* và */ hoặc sử dụng // để chú thích từ vị trí // đến hết dòng.
1.3.2.3. Biến
Trước khi sử dụng biến trong JavaScript, lập trình viên không nhất thiết phải khai báo biến. Có hai cách để định nghĩa biến trong JavaScript, một là sử dụng cú pháp var để khai báo biến:
<script type=”text/javascript”>
var tên_biến;
</script>
Ngoài ra, lập trình viên có thể chỉ việc gán cho biến một giá trị để sử dụng biến đó.Biến đƣợc định nghĩa ngoài tất cả các hàm hoặc đƣợc sử dụng mà không khai báo với cú pháp var sẽ đƣợc coi là biến toàn cục, những biến này có thể sử dụng trên toàn trang web.Biến đƣợc khai báo với var bên trong một hàm là biến cục bộ của hàm đó và chỉ có thể sử dụng đƣợc bên trong hàm đó.
SVTH: Trần Thị Hồng Ánh – Lớp 09CNTT2 15 1.3.2.4. Đối tượng
Kiểu của JavaScript đƣợc chia ra làm hai loại: kiểu cơ bản và đối tƣợng. Đối tƣợng trong JavaScript là một thực thể có tên xác định và có thuộc tính trỏ đến giá trị, hàm hoặc cũng có thể là một đối tƣợng khác.Có nghĩa là, đối tƣợng trong JavaScript là một mảng kết hợp (associative array).
JavaScript có một số đối tƣợng định nghĩa sẵn, bao gồm mảng (Array), đối tƣợng đại số bool (Boolean), đối tƣợng ngày tháng (Date), đối tƣợng hàm (Function), đối tƣợng toán học (Math), đối tƣợng số (Number), đối tƣợng đối tƣợng (Object), đối tƣợng biểu thức tìm kiếm (RegExp) và đối tƣợng chuỗi ký tự (String). Các đối tƣợng khác là đối tượng thuộc phần mềm chủ (phần mềm áp dụng JavaScript - thường là trình duyệt).
Bằng cách định nghĩa hàm khởi tạo, lập trình viên có thể tạo đối tƣợng.
JavaScript là một ngôn ngữ lập trình dựa trên nguyên mẫu do đó thừa kế diễn ra giữa các đối tƣợng, không phải giữa các lớp (JavaScript không hề có lớp). Đối tƣợng thừa kế thuộc tính từ các nguyên mẫu của chúng.
Ta có thể thêm hoặc xóa thuộc tính hoặc hàm trong đối tƣợng sau khi đối tƣợng đã đƣợc tạo. Để làm việc này cho tất cả các đối tƣợng đƣợc tạo từ cùng một hàm khởi tạo, có thể sử dụng thuộc tính prototype của hàm khởi tạo để truy cập đối tƣợng nguyên mẫu.Lập trình viên không nhất thiết phải tự xóa các đối tƣợng đã tạo, JavaScript tự động gom rác tất cả những biến không còn đƣợc dùng nữa.
1.3.2.5. Cấu trúc dữ liệu
Một cấu trúc dữ liệu tiêu điểm là mảng (Array), mảng trong JavaScript là một bảng liên kết chỉ mục đến giá trị. Trong JavaScript, tất cả các đối tƣợng đều có thể liên kết chỉ mục đến giá trị, nhƣng mảng là một đối tƣợng đặc biệt có thêm nhiều tính năng xử lý chỉ mục và dữ liệu đặc biệt (ví dụ: push, join, v.v.).
Mảng trong JavaScript có thuộc tính length. Thuộc tính length của JavaScript luôn luôn lớn hơn số chỉ mục lớn nhất trong mảng một đơn vị. Trong phần lớn ngôn ngữ lập trình, những thuộc tính có tính năng như length thường là thuộc tính chỉ đọc, tuy nhiên, với JavaScript, lập trình viên có thể thay đổi thuộc tính length.Bằng cách thay đổi thuộc tính length, lập trình viên có thể làm mảng lớn hơn hoặc nhỏ hơn (và xóa đi những chỉ mục lớn hơn hoặc bằng thuộc tính length mới).
Cách nhúng JavaScript vào trang HTML 1.3.3.
Có 3 cách để nhúng JavaScript vào trang HTML.
SVTH: Trần Thị Hồng Ánh – Lớp 09CNTT2 16 Cách 1: Nhúng trực tiếp trong trang HTML hoặc khai báo trong thành phần
<Head></Head>-Heading Embed
<html>
<head>
….
</head>
<body >
<script language="javascript" type=
"text/javascript">
document.write("Xin chào!!!");
</script>
</body>
</html>
Cách 2: Gọi một tệp từ bên ngoài
Giả sử bạn có một tập tin JavaScript dài và phức tạp và tệp này cần đặt trong tất cả các trang HTML.Nếu như trang nào bạn cũng phải ch n đoạn mã như phương pháp 1 thì mất nhiều thời gian và phải kiểm tra đoạn mã. Để giảm kích thước của trang web và đỡ tốn thời gian, JavaScript cho chúng ta 1 phương pháp ch n đoạn mã JavaScript bằng cách gọi từ ngoài vào. Muốn gọi tập tin JavaScript, trước hết tập tin đó phải có phần mở rộng là .js. Và trong tập tin này không đƣợc chứa thẻ mở và đóng
<script></script>.
Cách 3: Nhúng trong câu
Ngoài hai phương pháp trên dành cho các đoạn mã JavaScript dài và phức tạp, JavaScript cung cấp 1 phương pháp đơn giản dành cho việc xử lý sự kiện hoặc gọi các đối tƣợng nhƣ JavaScript: window.location...
1.4. NODEJS
NodeJs là gì?
1.4.1.
Javascript trước đây chỉ chạy được trên trình duyệt web.Nhưng gần đây nó được dùng ở phía server.Có những môi trường Javascript ở phía server như là Jaxer và
SVTH: Trần Thị Hồng Ánh – Lớp 09CNTT2 17 Narwhal, tuy nhiên Nodejs có một chút khác biệt so với những cái trên. Bởi vì nó dựa trên sự kiện hơn là dựa theo luồng (thread). Các máy chủ Web như Apache thường xử lý PHP và các script CGI (Common Gateway Interface) khác dựa theo luồng bởi chúng sinh ra một hệ thống luồng cho mỗi request đến. Trong khi cách đó là ổn cho rất nhiều ứng dụng thì các mô hình dựa theo 3luồng không thể mở rộng một cách có hiệu quả với nhiều kết nối tồn tại lâu. Ví dụ nhƣ bạn muốn dùng các dịch vụ thời gian thực nhƣ Friendfeed hay Google Wave.
Nodejs, sử dụng một sự kiện lặp thay cho các luồng, và nó có thể mở rộng lên hàng triệu kết nối một lúc. Điều này rất có lợi vì thực tế các máy chủ sử dụng phần lớn thời gian vào việc đợi các xử lý vào ra (ví dụ nhƣ đọc một file từ ổ cứng, truy vấn đến một dịch vụ web bên ngoài hoặc là đợi file đƣợc tải lên hoàn tất) bởi vì các xử lý đó chậm hơn rất nhiều so với xử lý bộ nhớ. Với kiến trúc hướng sự kiện thì lượng bộ nhớ dùng ít hơn, lưu lượng tăng cao và mô hình lập trình thì đơn giản hơn.
Mỗi một xử lý vào ra trong Nodejs là không đồng bộ, nghĩa là máy chủ có thể tiếp tục xử lý các request đến trong khi các xử lý vào ra đang diễn ra.Javascript mà một ngôn ngữ phù hợp cho việc lập trình hướng sự kiện bởi vì nó có các hàm không đồng bộ và sự bao đống cái mà tạo ra một hàm callbacks đảm bảo.Mô hình hướng sự kiện khiến cho Nodejs chạy rất nhanh và có thể triển khai và mở rộng cho các ứng dụng thời gian thực một cách dễ dàng. Một lợi ích lớn lao của NodeJS đó là nó đƣợc viết bằng javascript. Nó cũng hỗ trợ các hệ NoSQL dùng javascript để truy vấn.Từ đây ta chỉ cần học một ngôn ngữ là javascript để thực thi từ phía trình duyệt, phía webserver và cả cho database server.
Khác nhau giữa Blocking và Non-Blocking 1.4.2.
1.4.2.1. Blocking
Theo cách truyền thống (thread-based) thì hãy tưởng tượng một ngân hàng đang áp dụng mô hình phục vụ: Phục vụ hoàn toàn một yêu cầu rồi mới chuyển sang yêu cầu khác. Trong đó nhân viên trong ngân hàng.Tương ứng mỗi nhân viên là một thread.Và mỗi một yêu cầu tương ứng là 1 request đến server.Bạn yêu cầu là muốn gửi tiền vào ngân hàng. Bạn sẽ phải điền 1 số form như tên người gửi, số tài khoản của họ, số tiền cần gửi. v.v... Trong thời gian bạn điền thông tin cần rút tiền vào tờ khai.Cô nhân viên phải chờ bạn.Bạn đã "khóa" cô ấy không cho cô ấy phục vụ các khách hàng khác vì lúc đó cô ấy đang rảnh vì phải đợi bạn.Hành động đợi ở đây phần lớn là hành động vào/ra, truy xuất file, hoặc đợi kết quả truy vấn SQL trong Webservice.Đó là cơ chế Blocking.
SVTH: Trần Thị Hồng Ánh – Lớp 09CNTT2 18 Theo cách này.Nếu ngân hàng đang quá tải vì có quá nhiều người chờ được phục vụ.Thì ngân hàng chỉ còn một cách duy nhất là. Tăng thêm số nhân viên phục vụ lên. Ở trường hợp này trong ví dụ chúng ta là tăng số server phục vụ lên.
Vấn đề xảy ra ở đây ra.Khi tăng số lƣợng nhân viên lên để đáp ứng nhu cầu phục vụ khách hàng thì ngân hàng phải tăng chi phí (tiền để trả lương, mặt bằng văn phòng...) (tương ứng với việc tăng phần cứng máy chủ lên để đáp ứng).Như thế sẽ gây ra các vấn đề về lãng phí.Và không tận dụng đƣợc nguồn lực và tiết kiệm đƣợc chi phí.
1.4.2.2. Non-Blocking
Ở một ngân hàng khác, họ lại áp dụng theo một phương thức mới (event- driven): Tận dụng mọi khả năng của tất cả các nhân viên khi họ rảnh và nhân viên khi có yêu cầu mới phục vụ. Tức là khi bạn có một yêu cầu muốn gửi tiền nhƣ ở trên.Cô nhân viên chỉ cần đƣa bạn bút và giấy để bạn điền vào và bảo bạn hãy ngồi ở ghế chờ để điền xong thông tin gửi tiền. Trong khi đó cô ấy có thể phục vụ những vị khách tiếp theo. Ở đây bạn đã không "khóa" cô ấy lại.Và cô nhân viên tranh thủ lúc đợi bạn điền các thông tin.Cô ấy có thể làm việc khác.Thành ra ở đây không có hành động đợi vô nghĩa ở đây.Khi bạn điền xong thông tin, bạn có thể trở lại gặp cô ấy báo là đã hoàn thành.Cô ấy sẽ tiếp tục phục vụ bạn để bạn hoàn thành việc của mình.Đây là cơ chế Non-Blocking. Bạn có thể thấy, theo mô hình áp dụng của ngân hàng này (event- driven), họ sẽ tận dụng đƣợc khoảng thời gian rỗi của nhân viên. Khiến cho việc một nhân viên có thể phục vụ nhiều khách hàng hơn so với ngân hàng dùng mô hình theo cách cũ ở trên. Nếu có quá tải.Bạn chắc chắn vẫn phải thêm nhân viên để đáp ứng kịp thời.Nhƣng chắc chắn sẽ thêm ít nhân viên hơn.Tiết kiệm đƣợc rất nhiều tài nguyên.(Đây cũng là mô hình đƣợc áp dụng phổ biến ở các ngân hàng).
1.4.2.3. Lợi ích event-driven so với thread-driven Sẽ có 2 câu hỏi đƣợc đặt ra ở đây đó là:
Một là: Mặc định, NodeJs chỉ có một luồng đƣợc thực thi. Nó không cần đợi các tác vụ vào ra hoặc là chuyển nội dung.Thay vào đó, các tác vụ vào/ra sẽ tự động tạo ra một hàm điều khiển gửi tới các sự kiện khi mà mọi thứ đã xong.Các sự kiện lặp và mô hình điều hướng lặp cũng giống như cách mà JavaScript ở phía trình duyệt thực hiện.Chương trình sẽ xử lý các hành động và nhanh chóng quay về vòng lặp để gửi các tác vụ khác đến.Khi load 1 trang và đang chờ nó truy xuất cơ sở dữ liệu, thì NodeJs sẽ tranh thủ phục vụ request khác.Trong khi việc chờ truy xuất cơ sở dữ liệu vẫn tiếp tục.Vậy cũng thể coi đó là 2 tiến trình hoàn tòan khác nhau.
SVTH: Trần Thị Hồng Ánh – Lớp 09CNTT2 19 Hai là: Ngay trong hệ điều hành đã áp dụng mô hình dựa theo sự kiện (event- based) rồi. Nó sẽ không chỉ có 1 thread mà sẽ có rất nhiều thread. Và khi 1 thread tiến trình đang bị blocking I/O. Thì hệ điều hành sẽ cho các thread khác đƣợc chạy thay thế.
Và nhƣ thế sẽ không có thời gian trễ.Nhƣ vậy sẽ không có lợi ích gì đáng kể của mô hình hướng sự kiện so với không hướng sự kiện.
Có thể trả lời 2 câu hỏi trên bằng 1 ví dụ nhƣ sau : (Ở đây ta sẽ so sánh NodeJs với Apache)
Cho 1 đoạn code:
result = query(“select A from B”);
do_something(result);
Theo cách thông thường như trên. Nếu một request được gửi đến yêu cầu xử lý đoạn code trên. Webservice sẽ phải tạo ra 1 thread để xử lý. Vấn đề là thread đƣợc tạo ra đó sẽ không làm gì cả trong khi hàm query() vẫn đang chạy. Cho đến khi kết quả của câu lệnh truy vấn SQL trên xử lý thành công, lâu hay nhanh thì tùy thuộc vào độ phức tạp của câu truy vấn. Sau đó thread sẽ gọi hàm do_something. Đó thực sự không tốt bởi vì trong khi toàn bộ các tiến trình đang trong trạng thái đợi (trừ tiến trình SQL) thì các yêu cầu mới vẫn tiếp tục đƣợc gửi đến. Lúc này sẽ sinh ra rất nhiều các tiến trình đang đợi thực thi câu lệnh, theo đúng cơ chế blocking, vẫn ngốn tài nguyên máy chủ nhƣng không làm gì cả. Và nếu tất cả các tiến trình nhiều đến mức ngốn hết tài nguyên trong khi các tác vụ vẫn chƣa xong vì phải đợi thì lúc đó hệ thống sẽ sụp đổ.Quả thực là rất lãng phí. Mà việc chuyển trạng thái giữa các tiến trình là luôn có một khoảng thời gian trễ nào đó, mà càng nhiều tiến trình thì CPU càng mất nhiều thời gian để lưu trữ và khởi động lại các trạng thái, kéo theo tổng thời gian trễ đợi chuyển giữa các tiến trình là tăng lên. Đơn giản bằng cách không đồng bộ, NodeJs sẽ tận dụng triệt để tài nguyên do không có tài nguyên nào phải đợi lãng phí nữa. Một điểm yếu của lập trình hướng luồng là việc đồng bộ và tính đồng nhất của nó. Độ phức tạp của nó đến từ việc trao đổi giữa các biến và các hàm để tránh việc deadlock và xung đột giữa các luồng với nhau.
NodeJs khiến cho chúng ta phải hiểu theo một nghĩa khác thế nào là đồng nhất.
Các hàm callback đƣợc gọi một cách không đồng bộ trong các sự kiện lặp xử lý khá tốt trong việc đồng nhất, khiến cho mô hình đồng nhất trở nên đơn giản hơn, dễ hiễu hơn và dễ thực hiện hơn.Nhất là khi với việc trễ trong truy xuất các đối tƣợng.Nếu truy suất trong bộ nhớ thì ta chỉ mất với thời gian là nano giây, truy xuất đĩa cứng hoặc qua