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
File dấu trang google chrome: mục yêu thích_18_11_2020. html
$(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; }
* { 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; }
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; }
<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/
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.
<!-- 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%); }
img { -webkit-filter: grayscale(100%); /* Safari 6.0 - 9.0 */ filter: grayscale(100%); }
Link demo and doc: https://fengyuanchen.github.io/cropperjs/
/*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
Để \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;
Thêm code sau vào input có type là password
autocomplete='new-password'
Sử dụng
word-break: break-word;
Thay vì
word-break: break-all;
Thì sẽ tránh được case dấu . này
1・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・
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
Đây là video mình học ES6, dễ hiểu:
Link file word: Javascript
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('-'); }
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'; } } }
<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/
element.style.setProperty("padding-top", '10px', "important");
ImageExist(url) { url = window.location.origin + url; var http = new XMLHttpRequest(); http.open('HEAD', url, false); http.send(); return http.status!=404; }
<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>
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; } }
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
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
<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 = ''; } }
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/
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
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
+ 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
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)
Promise.race(iterable of multiple promises)
:Promise.allSetted(iterable of multiple promises)
: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
Cách làm cho gọn code hơn. Tuy nhiên nó vẫn là Promise.
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. });
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
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
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};