整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

每个JavaScript开发人员都应该了解的编程概念

每个JavaScript开发人员都应该了解的编程概念

avaScript是构建在标准Web浏览器上工作的Web应用程序前端的唯一本地编程语言。每个流行的Web浏览器都遵循众所周知的ECMAScript标准,并允许Web开发人员运行可移植、兼容的JavaScript代码。作为另一种流行的编程语言,JavaScript生态系统提供了几个独特的编程概念,帮助开发人员编写自解释的、性能优先的源代码。大多数现代Web开发项目在其代码库中使用这些JavaScript概念。在某些开发需求中,使用其中一些概念是不可避免的。

因此,有一些必须了解的JavaScript概念,每个Web开发人员在他们的职业生涯中都应该知道。开发人员不需要深入理解这些概念来编写简单的实验性Web应用程序。但是,理解这些JavaScript概念可以让您充分发挥JavaScript的潜力,通过理解JavaScript内部机制,以高效地编写生产级Web代码库。理解JavaScript的核心概念有助于更快地发现错误,并支持您提升职业水平。

在本文中,我将解释几个作为经验丰富的Web开发人员应该了解的核心JavaScript概念。

闭包和Hoisting

在JavaScript源代码中,我们通常不使用全局变量和一个主要函数,而是通过作用域将代码执行模型分解为多个堆叠段。例如,一个函数可以调用另一个函数,该函数使用私有变量来计算特定的值。闭包是一种位于另一个函数内部的函数,它允许程序员创建内部作用域。在函数调用后,内部函数(闭包)可以访问主函数作用域。

让我们通过一个简单的例子来理解这个概念:

function createUnitAdder(unit) {
  return (val)=> `${val} ${unit}` 
}
const cm=createUnitAdder('cm');
const kg=createUnitAdder('m');

console.log(cm(120));   
console.log(kg(7.5));   

在这里,createUnitAdder函数返回一个内部函数,该内部函数使用主作用域中的unit变量。当我们调用内部函数时,它使用了在调用createUnitAdder函数时初始化的主作用域中的unit变量。即使cm和kg函数来自同一个主要函数,它们使用不同的词法环境。

在C/C++语言中,我们无法在声明之前调用函数,因此通常在头文件中预定义它们。JavaScript允许您在声明之前访问函数和变量,因为JavaScript通过提升概念将声明移到作用域的顶部:

sayHello();
function sayHello() {
  console.log(`Hello JavaScript!`);
}

回调, 匿名方法, 和IIFE

现代JavaScript使用Promise和async/await关键字支持异步编程。但是,过去的JavaScript实现只能通过回调函数进行异步编程。回调通常是您传递给另一个函数的函数,该函数根据特定事件稍后调用它。尽管回调概念不再推荐用于异步编程,但基于事件的浏览器API通常会使用它。例如,您应该将回调函数传递给计时器和DOM API。

看下面的例子:

function sayHello() {
  console.log(`Hello JavaScript!`);
}
setInterval(sayHello, 1000);

在这里,我们使用sayHello函数作为回调函数。在这里,我们也可以使用匿名函数:

setInterval(()=> console.log(`Hello JavaScript!`), 1000);

如果您需要在创建匿名函数后立即运行它,那该怎么办?立即调用函数表达式(IIFE,Immediately Invoked Function Expression)的概念允许您这样做,如下面的示例所示:

((param)=> {
  let name='JS';
  console.log('IIFE', param, name); 
})(2023);

如上所示,它通过不允许我们向全局命名空间添加新变量来隔离代码段。

防抖动和节流

标准的浏览器API为各种目的提供了基于事件的API,用于创建用户友好的现代Web应用程序前端。这些基于事件的API(特别是DOM API)在短时间内可能会生成大量事件。因此,如果您通过这么多传入事件触发了一个昂贵的操作(例如调用RESTful API、解析等),它可能会影响您的整个应用程序的性能。如何减少调用昂贵操作的事件数量?

JavaScript开发人员通常使用防抖动(debounce)和节流(throttling)的概念作为性能增强策略。防抖动会等待频繁事件,并在超时后没有新的频繁事件发生时执行昂贵的操作。例如,以下代码片段在用户在半秒钟内不再主动输入文本时触发模拟的RESTful API请求:

async function searchTags() {
  return new Promise((resolve)=> setTimeout(()=> {
    console.log('API called.');
    resolve();
  }, 500));
}
function debounce(cb, delay) {
  let timer;
  return (...args)=> {
     clearInterval(timer);
     timer=setTimeout(()=> {
        cb(...args);
     }, delay);
  }
}

document
  .getElementById('text')
  .addEventListener('input', debounce(searchTags, 500));

另一方面,节流的概念根据预定义的时间间隔触发一个昂贵的函数。换句话说,在特定的时间间隔内只调用一次昂贵的操作。

看下面的节流实现:

function throttle(cb, delay) {
  let wait=false;
  return (...args)=> {
     if(wait)
        return;
     cb(...args);
     wait=true;
     setTimeout(()=> {
        wait=false;
     }, delay);
  }
}
document
  .getElementById('text')
  .addEventListener('input', throttle(searchTags, 500));

上面的代码片段在半秒的时间内只触发了一次昂贵的函数调用,即使有很多传入事件发生。

异步编程

在过去,每个JavaScript开发人员都使用回调函数进行异步编程,并面临着回调地狱的问题。ES6引入了Promise的概念,并提供了一种方便的方式来进行异步编程。尽管Promise通过Promise链式调用解决了回调地狱的问题,但在异步操作调用过程中仍使用了回调函数。后来,ES8引入了async/await关键字,以比Promise更好的异步编程技术,但它们在内部仍然使用了Promise(带有async标记的函数只是返回一个Promise)。

在开发现代应用程序时使用async/await关键字是一个好主意,因为它们提高了代码的可读性,优于Promise和回调函数:

async function getTodos() {
  let r=await fetch('https://jsonplaceholder.typicode.com/todos');
  let todos=await r.json();
  return todos;
}
(async function (){
  let todos=await getTodos();
  console.log(todos);
})();

在这里,我们使用了带有await关键字的Fetch API。在JavaScript中,我们只能在异步函数内部使用await关键字,因此我们编写了一个IIFE。或者,您可以使用Promises API调用RESTful API,因为异步函数通常返回一个Promise:

getTodos().then((todos)=> console.log(todos));

由于async/await关键字概念中的这种向后兼容特性,您甚至可以使用现代的await关键字调用旧的基于Promise的API:

function getItems() {
   return Promise.resolve([1, 2, 4]);
}
(async function (){
  let items=await getItems();
  console.log(items);    
})();

在JavaScript的事件系统中,使用回调是不可避免的,但有时我们可以使用async/await改进某些基于事件的API:

async function sleep(timeout) {
  return new Promise((r)=> setTimeout(r, timeout));
}
(async function (){
  console.log('Please wait...');
  await sleep(1000);
  console.log('Done.');
})();

在这里,我们部分地(没有检索返回值)将setTimeout函数转换为Promise。您可以使用Node.js内置的util.promisify函数或es6-promisify包来将任何老式的基于回调的代码转换为Promise。

事件系统

每个标准浏览器的JavaScript执行环境都是单线程的,但浏览器的功能通常是多线程的。例如,浏览器不会一次性排队和发送所有网络请求,而是可以并发发送网络请求。但是,浏览器使用事件循环的概念将多线程事件转换为单线程的JavaScript环境事件。从标准的Web API到高级库,事件无处不在。因此,掌握事件系统对于所有Web开发人员来说是必不可少的。

研究所有标准浏览器提供的有用事件。然后,您可以使用它们来构建用户友好且高效的Web应用程序。例如,您可以如下所示检测鼠标滚轮事件:

document.addEventListener('wheel', (e)=> console.log(e.deltaY));

Web API标准积极实现新的浏览器事件,关注开发者的生产力和Web应用的可用性。浏览器甚至支持触发自定义事件以进行基于事件的编程。

函数式编程

在Web应用程序中的常规数据处理过程中,数组操作是一种经常使用的技术。过去的JavaScript实现提供了几种基本的数组方法,但由于缺乏便捷的数组处理方法,我们在许多场景中不得不使用循环结构。现代JavaScript现在提供了许多数组方法,以函数式的方式处理数据,避免了老式的循环结构。链式调用这些方法的可能性提高了开发者的生产力和源代码的简洁性。

看下面的例子,它显示了一个未排序整数数组中的最大的三个数字:

let marks=[50, 75, 80, 22, 81, 92];
let topThree=marks
                  .sort((a, b)=> b - a)
                  .slice(0, 3);
console.log(topThree);   

这是另一个例子,它获取了两个单独数组中值的总和:

let costs1=[20, 15, 5];
let costs2=[10, 200];
let total=costs1.concat(costs2).reduce((acc, n)=> acc + n);

console.log(total);   

现代JavaScript拥有许多内置函数,以函数式的方式处理数组,因此在使用循环编写自己的算法之前,浏览MDN上现有的数组方法是一个明智的决策。

函数式的数据处理提高了代码的可读性,并激励您编写干净的代码。

结论

Web开发领域每天都在不断发展。许多协作者致力于与数百个W3C标准化草案合作,以改进基于JavaScript的Web API。与此同时,贡献者们致力于ECMAScript标准化草案,以改进标准JavaScript语言。这些新功能可以在Web开发领域引发新的概念。例如,WebAssembly和Workers引发了使用客户端计算能力来减少服务器工作负载的新概念,通过实现厚客户端。

家好,在上一篇文章里 CSS小知识,分享14个你可能还未用上但又实用的CSS属性(上)我们一起学习了上半部分,这篇文章我们我们继续学习下半部分。

八、CSS Shake Effect 晃动效果

CSS Shake Effect 是一种使用 CSS 制作的晃动效果。这种效果通常用于错误提类似的场景。

如下段代码所示,当用户输入无效输入时,此“摇动”动画效果会摇动输入字段。它简单而优雅。例如,如果用户在文本字段中输入数字而不是字母,输入字段将会抖动。


HTML部分

<input id="name" type="text" placeholder="Enter your name" pattern="[A-Za-z]*"/>

CSS部分

input:invalid{
      animation: shake 0.2s ease-in-out 0s 2;
      box-shadow: 0 0 0.4em red;
}
  @keyframes shake {
      0% { margin-left: 0rem; }
      25% { margin-left: 0.5rem; }
      75% { margin-left: -0.5rem; }
      100% { margin-left: 0rem; }
}

九、Text Overflow 文字溢出

您可以使用此属性截断溢出的文本。指在文本超出元素宽度时,自动隐藏超出部分的文本。在 CSS 中,可以使用 text-overflow 属性来实现这种效果。可以使用省略号 (...) 或自定义字符串对其进行截取缩略显示。

下面是一个简单的代码示例:

.overflow-ellipsis {
  width: 100px; /* 定义元素的宽度 */
  white-space: nowrap; /* 防止文本换行 */
  overflow: hidden; /* 隐藏超出部分 */
  text-overflow: ellipsis; /* 添加省略号来指示隐藏的文本 */
}

HTML:

<div class="overflow-ellipsis">文本如果超出容器会被截断并添加省略号</div>

上面的代码定义了一个名为 "overflow-ellipsis" 的类,并将其应用于一个元素。这个类使用了 white-space: nowrap; 来防止文本换行,使用了 overflow: hidden; 来隐藏超出部分,并使用了 text-overflow: ellipsis; 来添加省略号(...)来指示隐藏的文本。

十、column-count 内容多列属性

CSS 的 column-count 属性可以用来将一个元素的内容分成多列,以实现报纸或杂志的页面布局效果。

下面是一个简单的代码示例:

.multi-column {
  column-count: 2; /* 将内容分成两列 */
  column-gap: 20px; /* 设置列之间的间隔 */
}

HTML:

<div class="multi-column">
  <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed auctor, augue non tincidunt eleifend, magna massa varius lorem, at luctus augue tellus in nibh.</p>
  <p>Proin velit orci, pellentesque vel malesuada at, varius vel nibh. Nam eget mauris euismod, feugiat ipsum a, convallis enim. Aenean euismod malesuada orci eget euismod.</p>
  <p>Nunc vitae augue eget nulla tempus aliquet. Integer euismod quam nunc, id rhoncus magna convallis at. Nullam euismod, sem a bibendum malesuada, erat ligula molestie magna.</p>
</div>

上面的代码定义了一个名为 "multi-column" 的类,并将其应用于一个元素。这个类使用了 column-count: 2; 来将内容分成两列,并使用了 column-gap: 20px; 来设置列之间的间隔。

还有 column-width 属性可以用来设置每一列的宽度,若同时设置 column-width 和 column-count 属性,则优先使用 column-width,column-count 会自动调整。

在实际使用中,需要结合其他属性,如 column-gap, column-rule, column-rule-color, column-rule-style, column-rule-width等等来实现多列布局的效果。


十一、CSS Animations 动画

动画逐渐改变元素的样式。只有先指定关键帧才能使用它。关键帧描述动画元素如何出现在动画序列中的等相关特性。

示例代码:

div{
  width: 200px;
  height: 200px;
  background-color: blue;
  animation-name: square;
  animation-duration: 8s;
}
@keyframes square{
  from {background-color: blue;}
  to {background-color: black;}
}

十二、Shadow Effects 阴影效果

text-shadow 属性可以在文本上添加阴影效果,可以使用它来增强文本的可读性和吸引力。

box-shadow 属性可以在元素上添加阴影效果,可以使用它来增强元素的立体感和吸引力。

下面是 text-shadow 和 box-shadow 的一个简单的代码示例:


.text-shadow {
  text-shadow: 2px 2px 4px #000000; /* x-offset, y-offset, blur-radius, color */
}

.box-shadow {
  box-shadow: 2px 2px 4px #000000; /* x-offset, y-offset, blur-radius, color */
}

HTML代码

<p class="text-shadow">This is text with shadow</p>
<div class="box-shadow">This is a box with shadow</div>

上面的代码定义了一个名为 "text-shadow" 的类和一个名为 "box-shadow" 的类,分别将其应用于一个文本元素和一个盒子元素。这两个类都使用了 x-offset: 2px; y-offset: 2px; blur-radius: 4px; color: #000000; 来定义阴影的样式。

阴影的偏移值(x-offset y-offset)可以正值或负值,正值为阴影在元素的下方右方,负值为阴影在元素的上方左方。阴影的模糊半径和阴影的颜色也可以根据需要调整。

在实际使用中,还可以使用 box-shadow: inset; 属性来改变阴影为内阴影。

十三、CSS Clipping

clip-path 属性可以用来剪切元素的形状。它可以使用一个图形或路径来定义剪切区域。

如下段代码示例:

.bg{
  height: 100%;
  width: 100%;
  background-color: rgba(199, 62, 133, 0.9);
  clip-path: polygon(100% 0, 100% 0, 100% 51%, 0 100%, 0 90%, 0 52%, 0 51%);
  position: absolute;
}

https://bennettfeely.com/clippy/ 这个工具网站,是一种通过将元素剪辑为基本形状(圆形、椭圆形、多边形或插图)的可视化在线代码生成工具,大大节省的你的时间。

十四、CSS background-blend-mode 属性

background-blend-mode 属性可以用来控制背景图像与背景颜色的混合模式。它可以使用一系列的混合模式来定义背景的外观,如添加颜色、阴影、高光等。

您可以使用 background-blend-mode 属性制作令人惊叹的背景。

如下段代码所示:

div{
   width: 600px;
   height: 400px;
   background-repeat: no-repeat, repeat;
   background-position: center;
   background-image: url("flower.png"), url("background-image.png");
   background-blend-mode: color;
}

完成后的效果:

background-blend-mode 属性有很多可用的值,如:normal, multiply, screen, overlay, darken, lighten, color-dodge, color-burn, hard-light, soft-light, difference, exclusion, hue, saturation, color, luminosity。

在实际使用中,需要注意浏览器的兼容性问题,需要使用前请查询浏览器对 background-blend-mode 的支持情况。更多相关的用法建议查询 https://www.w3schools.com/cssref/pr_background-blend-mode.php 这个网站。

结束

今天的分享就到这里,14 个关于CSS的属性就分享到这里,希望对你有所帮助,感谢你的关注。

参考文章:

https://ishratumar.medium.com/14-awesome-css-properties-you-need-to-know-9cee5b364990

作者:Ishrat Umar

注:非直译,有整理部分

图的时候遇到的这么一个问题,qq浏览器数字文本框 鼠标滚轮滑动,数字会自动加减,这个虽然也有一定的作用,但是并不是所有人都喜欢,所以必要的时候还是要禁用掉,目前在chrome,360为发现该问题,qq浏览器存在,禁用的方法也很简单。



核心代码就这一句话

<input type=”number” id=”inp1″ onmousewheel=”return false;”>


以下是扩展资料
<style type=”text/css”>
/*盒子大小从边框开始计算*/
html * {
box-sizing: border-box;
}
/*解决模态框抖动*/
html {
overflow-y: scroll;
-ms-overflow-style: none;
}
/* 隐藏滚动条 */
html::-webkit-scrollbar {
display: none;
}
body {
font-family: “Helvetica Neue”, Helvetica, Arial, sans-serif;
font-size: 14px;
}
/* 去除webkit中input的type=”number”时出现的上下图标 */
input::-webkit-outer-spin-button,
input::-webkit-inner-spin-button {
-webkit-appearance: none;
}
input[type=”number”] {
-moz-appearance: textfield;
}
</style>
<!DOCTYPE html>
<html lang=”en”>

<head>
<meta charset=”UTF-8″>
<title>禁止input输入框的鼠标滚轮事件</title>
<script src=”jquery.js”></script>
</head>
<body>
<!– 禁止谷歌浏览器、Opera浏览器以及360浏览器等采用谷歌内核的浏览器 –>
<input type=”number” id=”inp1″ onmousewheel=”return false;”>
<!– 禁止Firefox浏览器 –>
<input type=”number” id=”inp2″>
<script>
$(“#inp2”)[0].addEventListener(‘DOMMouseScroll’, MouseWheel, false);
function MouseWheel(event) {
event=event || window.event;
event.preventDefault();
}
</script>
</body>

</html>