Thumbnail
Category: Lập trình

Kinh nghiệm css, javascript - frontend

Date: November 17, 2020
82 views

1. CSS

1.1 Kinh nghiệm chung

  • transparent: thiết lập màu trong suốt
  • transform: translate(10px,10px); dịch chuyển 2D
  • transition: height 2s ease 3s; hiểu ứng chuyển đổi
  • [property] [duration] [timing-function] [delay]
  • flexbox: https://viblo.asia/p/huong-dan-su-dung
  • gradient: 
linear-gradient(direction, color-stop1, color-stop2, ...);  từ một phía
radial-gradient(shape-size-at position, start-color... last-color); từ tâm

1.2 Các công cụ Tú chia sẻ

File dấu trang google chrome: mục yêu thích_18_11_2020. html

1.3 Library Slider and Nav-mobile


 $(document).ready(function(){
   var bxslider = $('.slider').bxSlider({
     touchEnabled: false,
     oneToOneTouch: false
     });
​
   JumpToSlide = function (slideNumber) {
​
     var slide = slideNumber - 1;
​
     bxslider.goToSlide(slide);
​
   };
 });
​
​
//xu ly click href not working
<a onclick="handleClick(this)" href="{{route("vn.searchJobCategoryFriendly", ["dich-thuat"]) }}">
function handleClick(obj) {
     let href = obj.getAttribute("href");
     window.location.href = href;
}

1.4 Library OwlCarousel and ScrollUp

1.5 Kinh nghiệm thực tập

1.5.1 Reset css


* {
    box-sizing: inherit;
    margin: 0;
    padding: 0;
}
​
html {
    font-size: 62.5%;
    line-height: 1.6rem;
    box-sizing: border-box;
    font-family: "Roboto", sans-serif;
}

1.5.2 Center cả ngang và dọc

Tăng line-height và sử dụng text-align: center


.content-right__process-item-content {
    text-align: center;
    line-height: 4.7rem;
    font-size: 1.6rem;
}

1.5.3 Cdn Fontawesome


<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.1/css/all.min.css" />

Link font-awesome: https://fontawesome.com/

1.5.4 Xử lý mũi tên

Bạn làm mũi tên trỏ xuống từ thông báo, hoặc user để logout.

Hãy tạo thêm 1 lớp giả để ghi đè đường viền của box ngay tại điểm giao giữa mũi tên và box bên dưới.

1.5.4 box-shadow theo clip-path


<!-- html -->
<div class="content-right__header-item-notify-triagle-wrap">
  <div class="content-right__header-item-notify-triagle">
​
  </div>
</div>


/* css */
.content-right__header-item-notify-triagle-wrap {
    filter: drop-shadow( 0 0 5px rgba(50, 50, 0, 0.5));
    position: absolute;
    right: 25px;
    top: 23px;
    display: none;
}
​
.content-right__header-item-notify-triagle {
    position: absolute;
    /* top: 14px;
    right: 3px; */
    /* width: 2.2rem;
    height: 1.5rem; */
    /* background-color: orange;
    box-shadow: 0 0px 9px #ccc; */
    background-color: #6f64f8;
    color: #222;
    padding: 1rem 1rem 1rem 2rem;
    font: bold 32px system-ui;
    clip-path: polygon(50% 0%, 0% 100%, 100% 100%);
}

1.5.5 Tạo hình ảnh trắng đen


img {
  -webkit-filter: grayscale(100%); /* Safari 6.0 - 9.0 */
  filter: grayscale(100%);
}

1.6 Thư viện crop image

Link demo and doc: https://fengyuanchen.github.io/cropperjs/

1.7 Các khái niệm học thêm được

  1. Specificity: Đánh giá độ ưu tiên của các selector
  2. Biểu thức tính mức độ ưu tiên của selector


/*00110*/
#myDivId .myDivClass
{
    font-size: 20px;
}
​
/*00030*/
.a .b .c
{
    color: green;
}
​
/*00020*/
.a .b
{
    color: red;
}

Xem thêm bài viết: https://viblo.asia/p/css-specificity-Eb85ojpOl2G

2. css taking context: 

 + Stacking Order: Mọi element trong một trong HTML có thể ở phía trước hay phía sau các element khác trong document. Đây được gọi là thứ tự xếp lớp (stacking order).

 + Một nhóm các element có chung một element cha sẽ cùng di chuyển chung với nhau trong stacking order, tạo nên khái niệm gọi là stacking context.

Xem thêm bài viết: https://viblo.asia/p/dieu-khong-ai-noi-cho-ban-ve-z-index-gDVK2jOeKLj

1.8 breakline cho \n

Để \n trình duyệt có thể hiển thị xuống dòng thì cần thêm css với thuộc tính sau:


white-space: break-spaces;

1.9 Không cho trình duyệt autofill

Thêm code sau vào input có type là password


autocomplete='new-password'

1.10 Word-break

Sử dụng


word-break: break-word;

Thay vì


word-break: break-all;

Thì sẽ tránh được case dấu . này


1・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・

2. Javascript

2.1 Javascript ES6

  • Let vs Var vs Const
  • + Let: biến cục bộ
  • + Var: biến toàn cục
  • + Const: hằng – không thay đổi giá trị
  • Objects
  • The this Keyword
  • Binding this
  • Arrow Functions:  ()=> {} cách viết ngắn gọn của function và không có binding
  • Arrow Functions and this
  • Array.map Method: Như foreach
  • Object Destructuring: Lấy biến từ object dễ hơn


var person = {
    name: "Hao",
    age: 20,
}
​
let name = person.name;
let age = person.age;
​
//để ngắn gọn sử dụng Destructuring
let { name, age } = person;
​
//thay đổi tên biến
let { name: ten, age } = person
  • Spread Operator: dấu … => copy mảng, object
  • Classes
  • Inheritance : Kế thừa
  • Modules : chia class thành các file khác nhau
  • Named and Default Exports: xuất class thì file khác và import vào file sử dụng

Đây là video mình học ES6, dễ hiểu:

  • Closures: Function lồng function, function con được sử dụng biến của function cha

2.2 Tú chia sẻ javascript

Link file word: Javascript

2.3 Format date yyyy-mm-dd


formatDate(date) {
  var d = new Date(date),
  month = '' + (d.getMonth() + 1),
  day = '' + d.getDate(),
  year = d.getFullYear();
​
  if (month.length < 2) 
    month = '0' + month;
  if (day.length < 2) 
    day = '0' + day;
​
  return [year, month, day].join('-');
}

2.4 Format date yyyy-mm-ddThh:mm cho thẻ input type datetime


formatDate(dateInput) {
  let day = this.formatNumberAddZero( dateInput.getDate() );
  let month = this.formatNumberAddZero( (dateInput.getMonth()+1) );
  let date = dateInput.getFullYear() + '-' + month + '-' + day;
​
  let hours = this.formatNumberAddZero(dateInput.getHours());
  let minutes = this.formatNumberAddZero(dateInput.getMinutes());
  var time = hours + ":" + minutes;
  var dateTime = date+'T'+time;
  return dateTime;
},
/**
  * format 1..9 =>01...09
*/
formatNumberAddZero(number) {
  if (number >= 10)
    return number;
  else {
    switch (number) {
      case 1: return '01';
      case 2: return '02';
      case 3: return '03';
      case 4: return '04';
      case 5: return '05';
      case 6: return '06';
      case 7: return '07';
      case 8: return '08';
      case 9: return '09';
    }
  }
}

2.5 Count down


<script>
        function countdownTimer(strDate, index) {
            const difference = +new Date(strDate) - +new Date();
            let remaining = "Time's up!";
            if (difference > 0) {
                const parts = {
                hours: Math.floor((difference / (1000 * 60 * 60))),
                minutes: Math.floor((difference / 1000 / 60) % 60),
                seconds: Math.floor((difference / 1000) % 60),
                };
​
                
                remaining = Object.keys(parts).map(part => {
                return `${parts[part]} ${part}`;
                }).join(" ");
            }
            console.log(remaining);
​
            let hour = '';
            let minute = '';
            let second = '';
​
            let arraySplitHour = remaining.split(' hours ');
            hour = addZeroToNumber(arraySplitHour[0]);
​
            let arraySplitMinute = arraySplitHour[1].split(' minutes ');
            minute = addZeroToNumber(arraySplitMinute[0]);
​
            let arraySplitSecond = arraySplitMinute[1].split(' second');
            second = addZeroToNumber(arraySplitSecond[0]);
​
            document.getElementById("hour-" + index).innerHTML      = hour;
            document.getElementById("minute-" + index).innerHTML    = minute;
            document.getElementById("second-" + index).innerHTML    = second;
        }
​
        function addZeroToNumber( number ) {
            if ( number > 9 ) {
                return number
            } else {
                switch ( number ) {
                    case '0': return '00';
                    case '1': return '01';
                    case '2': return '02';
                    case '3': return '03';
                    case '4': return '04';
                    case '5': return '05';
                    case '6': return '06';
                    case '7': return '07';
                    case '8': return '08';
                    case '9': return '09';
                }
            }
        }
​
        $( document ).ready(function() {
            for(let i = 0; i < arrayTimeEventNotOver.length; i++) {
                countdownTimer(arrayTimeEventNotOver[i], i);
            }
            for(let i = 0; i < arrayTimeEventNotOver.length; i++) {
                setInterval(countdownTimer, 1000, arrayTimeEventNotOver[i], i);
            }
        });
</script>

Link bài viết: https://www.digitalocean.com/

2.6 set attribute css important


element.style.setProperty("padding-top", '10px', "important");

2.7 Check image exists by javascript


ImageExist(url) 
{
    url = window.location.origin + url;
​
    var http = new XMLHttpRequest();
    http.open('HEAD', url, false);
    http.send();
    return http.status!=404;
}

2.8 Upload File change image


<p><input type="file"  accept="image/*" name="image" id="file"  onchange="loadFile(event)" style="display: none;"></p>
<p><label for="file" style="cursor: pointer;">Upload Image</label></p>
<p><img id="output" width="200" /></p>
​
<script>
var loadFile = function(event) {
    var image = document.getElementById('output');
    image.src = URL.createObjectURL(event.target.files[0]);
};
</script>

2.9 Check phone number vietnam


function phonenumber(inputtxt) {
  var phoneno = /(84|0[3|5|7|8|9])+([0-9]{8})\b/;
  if(inputtxt.match(phoneno)) {
    return true;
  }
  else {
    return false;
  }
}

2.10 Replace url not reload page


window.history.pushState({ các biên cần lưu: giá trị }, '', url);


// bắt sự kiện ấn back trang về
window.onpopstate = function(event) {
  location.replace(document.location);
};

Tham khảo: https://developer.mozilla.org/en-US/docs/Web/API/History/pushState

https://developer.mozilla.org/en-US/docs/Web/API/Window/popstate_event

2.11 Convert 2 byte to 1 byte Japan


function toASCII(chars) {
    var ascii = '';
    for(var i=0, l=chars.length; i<l; i++) {
        var c = chars[i].charCodeAt(0);
​
        // make sure we only convert half-full width char
        if (c >= 0xFF00 && c <= 0xFFEF) {
           c = 0xFF & (c + 0x20);
        }
​
        ascii += String.fromCharCode(c);
    }
​
    return ascii;
}
​
// example
toASCII("ABC"); // returns 'ABC' 0x41

2.12 Check input file is image


<input type="file" name="background_image" id="background_image" accept="image/*" onchange="changeBackgroundImage(this)">
function changeBackgroundImage(inputFile) {
    var filePath = inputFile.value;
          
    // Allowing file type
    var allowedExtensions = 
            /(\.jpg|\.jpeg|\.png|\.gif)$/i;
        
    if (!allowedExtensions.exec(filePath)) {
        alert('File is not an image. Please choose another file!');
        inputFile.value = '';
    } 
}

2.13 Mask input javascript

Download thư viện: https://github.com/beholdr/maska/archive/master.zip

1. Add library vào web


<script src="/dist/maska.js"></script>

2. Định nghĩa data-masked và thêm class masked


<input data-mask="##/##/####" class="masked">

3. Khởi tạo mask


$(document).ready(function () {
​
  Maska.create('.masked');
});

Xem thêm tại: https://www.cssscript.com/input-mask-maska/

2.14 Các khái niệm học thêm được

2.14.1 Closure

Closure: Sử dụng biến ngoài function, mặc dù biến đó đã return.


function numberGenerator() {
  // Local free variable that ends up within the closure
  var num = 1;
  function checkNumber() { 
    console.log(num);
  }
  num++;
  return checkNumber;
}
​
var number = numberGenerator();
number(); // 2

2.14.2 Event loop

Event loop: Tự động đưa bất đồng bộ ở queue vào call stack khi call stack rỗng.


const foo = () => console.log("First");
const bar = () => setTimeout(() => console.log("Second"), 500);
const baz = () => console.log("Third");
​
bar();
foo();
baz();

Xem thêm bài viết: https://viblo.asia/p/hieu-ve-co-che-xu-ly-su-kien-event-loop-trong-javascript-07LKXjX2lV4

2.14.3 Microtask và macrotask:

+ Microtask: Liên quan đến promise, … có độ ưu tiên cao hơn macrotask.

+ Macrotask: Liên quan setTimeout, setIntervel,… có độ ưu tiên thấp hơn microtask.

Cả hai cùng nằm trong queue, 


function getUp() {
  console.log('I am waking up');
}
​
function makeCoffee() {
  setTimeout(() => {
    console.log('Making coffee in 5 minutes');
  }, 0);
}
​
function haveBreakfast() {
  Promise.resolve().then(() => {
      console.log('I have my breakfast');
  });
}
​
makeCoffee();
haveBreakfast();
getUp();

Xem thêm bài viết: https://viblo.asia/p/javascript-chay-bat-dong-bo-nhu-the-nao-gDVK2JW0KLj

2.14.4 Promise:

Tại mỗi thời điểm Promise sẽ có 1 trạng thái nhất đinh

  • pending
  • fulfilled
  • rejected

Static methods

  • Promise.resolve(value): Trả về một promise resolved (hoàn thành) với một giá trị cụ thể.
  • Promise.reject(reason): Trả về một promise rejected (lỗi) với một lỗi cụ thể.
  • Promise.all(iterable of multiple promises)
  • Nhận vào một mảng các promise hoặc cũng có thể là non-promise (number, boolean, .etc).
  • Trả về một promise mới.
  • Chờ tất cả các promise trong mảng resolved, kết quả của promise mới này là một mảng chứa kết quả của các promise theo đúng thứ tự.
  • 1 promise bất kì rejected, kết quả của promise mới này được trả về ngay lập tức lỗi của promise rejected đó, các promise khác vẫn tiếp tục thực thi nhưng kết quả bị bỏ qua.
  • Thực thi promise dạng parallel.
  • Promise.race(iterable of multiple promises):
  • Nhận vào một mảng các promise hoặc cũng có thể là non-promise (number, boolean, .etc).
  • Trả về một promise mới.
  • Kết quả của promise mới là kết quả của promise bất kì đầu tiên resolved hoặc rejected.
  • Promise.allSetted(iterable of multiple promises):
  • Nhận vào một mảng các promise hoặc cũng có thể là non-promise (number, boolean, .etc).
  • Trả về một promise mới.
  • Chờ cho tất cả các promise được xử lý, kết quả trả về là mảng chứa các object chứa trạng thái và giá trị của promise kể cả resolved hay rejected.
  • Một vài trình duyệt với phiên bản mới gần đây đã hỗ trợ
  • Promise.any(iterable of multiple promises)experimental

Xem thêm bài viết: https://viblo.asia/p/nhung-dieu-can-biet-ve-promise-javascript-bJzKmJwEZ9N

2.14.5 Async/Await

Cách làm cho gọn code hơn. Tuy nhiên nó vẫn là Promise.

  • Async – khai báo một hàm bất đồng bộ (async function someName(){…}).
  • Tự động biến đổi một hàm thông thường thành một Promise.
  • Khi gọi tới hàm async nó sẽ xử lý mọi thứ và được trả về kết quả trong hàm của nó.
  • Async cho phép sử dụng Await.
  • Await – tạm dừng việc thực hiện các hàm async. (Var result = await someAsyncCall ()?.
  • Khi được đặt trước một Promise, nó sẽ đợi cho đến khi Promise kết thúc và trả về kết quả.
  • Await chỉ làm việc với Promises, nó không hoạt động với callbacks.
  • Await chỉ có thể được sử dụng bên trong các function async.


async function getJSONAsync() {
​
  // The await keyword saves us from having to write a .then() block.
  let json = await axios.get('https://tutorialzine.com/misc/files/example.json');
​
  // The result of the GET request is available in the json variable.
  // We return it just like in a regular synchronous function.
  return json;
}
​
getJSONAsync().then( function(result) {
  // Do something with result.
});

Thay vì


function getJSON() {
​
  // To make the function blocking we manually create a Promise.
  return new Promise( function(resolve) {
    axios.get('https://tutorialzine.com/misc/files/example.json')
      .then( function(json) {
​
        // The data from the request is available in a .then block
        // We return the result using resolve.
        resolve(json);
      });
  });
}
​
getJSONAsync().then( function(result) {
  // Do something with result.
});

2.14.6 Generator javascript

Xen ngang quá trình xử lý.

Giống debug, có thể dừng chương trình ở 1 điểm break point nào đó.

Dùng biến đổi bất đồng bộ thành đồng bộ.

Điểm dừng sẽ là yield param

Xem thêm bài viết: https://viblo.asia/p/generator-trong-javasccript-WEMGBjjVGQK

2.14.7 Event Bubbling và Capturing

Bubbling xử lý sự kiện từ element đến element cha, ông, tổ tiên.

Capturing thì ngược lại từ tổ tiên, ông, cha, rồi mới tới element đó.

Vd: khi click vào thẻ td


//capturing
window → document → table → tbody → tr → td
​
// bubling
td → tr→ tbody → table → document → window

Việc đăng ký capturing mặc định là false => tức là luôn áp dụng bubling.

Bạn có thể thay đổi bằng cách thêm tham số thứ ba


addEventListener("click", handler, true)
/**
  * true => capturing
  * false => bubling (default)
*/

Không áp dụng cái nào chỉ thực hiện của element thôi thì sao?

=====> Sử dụng event.stopPropagation() nhé!


<body onclick="alert(`the bubbling doesn't reach here`)">
    <button onclick="event.stopPropagation()">Click me</button>
</body>

Khi chúng ta click và button Click me thì nó sẽ không bubbling đến event của <body>.

Xem thêm: https://viblo.asia/p/bubbling-va-capturing-event-trong-javascript-phan-1-m68Z0Nod5kG

https://viblo.asia/p/bubbling-va-capturing-event-trong-javascript-phan-2-bJzKmLnO59N

2.15 Tạo đối tượng mới

Với object và array muốn clone thành 1 object hoàn toàn mới, hãy luôn sử dụng cloneDeep. Vì sử dụng spread operator thì nó chỉ clone được 1 cấp thôi, những thằng con vẫn còn giữ tham chiếu cũ.


// sử dụng
let formData = cloneDeep(state2.form);
​
// thay vì
let formData = {...state2.form};

3. html

  • semantic tags: những thẻ có tên rõ ràng như header, footer, nav,..
  • SEO cơ bản thẻ meta: 
  • – Lúc trước google dựa vào thẻ meta title, description, keywork để sắp xếp thứ hạng, sau này đã bỏ không còn sử dụng.
  • – Các meta trên thì vẫn được TQ sử dụng.
  • Xem thêm: https://viblo.asia/p/ky-thuat-seo-co-ban-3wjAM7zLRmWe?fbclid=IwAR3vTmCEtoXxlTiZQ2NweZ1SyeTb2ILILnIKr09nNQ3StMv00Pr9OaQxrMo


Copyright © 2025 All Right Reserved