创建与框架无关的JavaScript插件


Posted in Javascript onDecember 01, 2020

JavaScript 中的插件使我们能够扩展语言,以实现所需的某些强大(或不够强大)的功能。插件/库本质上是打包的代码,可以使我们免于一遍又一遍地编写相同的东西(功能)。

在 JavaScript 生态系统中,有数百个框架,这些框架中的每一个都为我们提供了一个创建插件的系统,以便为框架添加新的东西。

如果你看一下 NPM 注册表,几乎所有的 JavaScript 插件都是在那里发布的,你会看到有超过一百万个插件以简单库和框架的形式发布。

为每个框架创建插件的方式可能会有很大不同。例如,Vue.js 有自己的插件系统,这与你为 React.js 创建插件的方式不同。然而,这一切都归结为相同的 JavaScript 代码。

因此,使用普通 JavaScript 创建插件,让你有能力创建一个无论在哪个框架下都能使用。

“与框架无关的 JavaScript 插件是无需框架上下文即可工作的插件,您可以在任何框架(甚至没有框架)中使用插件”

构建库时要记住的事项

  • 您应该对插件有一个目标——这是插件要实现的关键
  • 您的插件应易于使用以达到预期用途
  • 您的插件应在很大程度上可定制
  • 您的插件应该有一个文档,指导将要使用该插件的开发人员

现在,让我们着眼于上述几点。

我们将创造什么

在本文中,我将向您展示如何创建与框架无关的插件。在本教程中,我们将创建一个旋转木马/幻灯片插件——该插件的目标。

这个插件会暴露一些方法,可以被插件的用户调用 .next() 和 .prev()

起步

让我们创建一个新的文件夹来存放我们的插件代码和任何其他必要的文件,我将把我的文件夹称为 TooSlidePlugin。

在这个文件夹中,在你喜欢的编辑器中创建一个新的 JavaScript 文件。这个文件将包含插件的代码,我把我的文件叫做 tooSlide.js。

有时,我什至想像在开始创建插件之前(从最终开发人员的角度)如何使用插件。

var slider = new ToolSidePlugin({
 slideClass: ".singleSlide",
 container: ".slideContainer",
 nextButton: ".next",
 previousButton: ".prev",
});

上面的代码假定有一个名为 TooSlides 的构造函数,该构造函数接收具有某些属性的对象作为参数。对象的属性是 slidesClass、container、nextButton 和 previousButton,这些是我们希望用户能够自定义的属性。

我们将从将插件创建为单个构造函数开始,以便其本身具有名称空间。

function ToolSidePlugin() {}

Options

由于我们的插件,TooSlides 需要一个选项参数,所以我们会定义一些默认的属性,这样如果我们的用户没有指定自己的属性,就会使用默认的属性。

function ToolSidePlugin(options) {
 let defaultOptions = {
  slideClass: ".singleSlide",
  container: ".slideContainer",
  nextButton: ".nextSlide",
  previousButton: ".previousSlide",
 };

 options = { ...defaultOptions, ...options };

 let _this = this;
 let slides = [];
 let currentSlideIdex = 0;
}

我们创建了一个 defaultOptions 对象来保存一些属性,我们还使用 JavaScript 扩展操作符将传入的选项与默认选项合并。我们将 this 分配给另一个变量,因此我们仍然可以在内部函数中对其进行访问。

我们还创建了两个变量 slides,它将保存所有我们想要用作幻灯片的图片,以及 currentSlideIndex,它保存当前正在显示的幻灯片的索引。

接下来,由于我们的幻灯片需要有一些控制,可以用来向前和向后移动幻灯片,我们将在构造函数中添加下面的方法。

this.prepareControls = function() {
 const nextButton = document.createElement("button");
 const previousButton = document.createElement("button");

 nextButton.setAttribute("class", "next");
 nextButton.InnerHTML = "Next";

 previousButton.setAttribute("class", "prev");
 nextButton.InnerHTML = "Prev";

 let controleContainer = document.createElement("div");

 controleContainer.setAttribute(
  "class",
  "too-slide-control-container"
 );

 controleContainer.appendChild(previousButton);
 controleContainer.appendChild(nextButton);

 document
  .querySelector(options.container)
  .appendChild(controleContainer);

 nextButton.addEventListener("click", function() {
  _this.next();
 });
 previousButton.addEventListener("click", function() {
  _this.previous();
 });
};

在 .prepareControls() 方法中,我们创建了一个容器 DOM 元素来保存控件按钮,我们自己创建了下一个和上一个按钮,并将它们附加到 controlContainer。

然后我们给两个按钮附加事件监听器,分别调用 .next() 和 .previous() 方法。别担心,我们很快就会创建这些方法。

接下来,我们将添加两个方法:.goToSlide() 和 .hideOtherSlides()。

this.goToSlide = function(index) {
 this.hideOtherSlides();
 if (index > slides.length - 1) {
  index = 0;
 }
 if (index < 0) {
  index = slides.length - 1;
 }
 slides[index].style = "display:block";
 currentSlideIndex = index;
};

this.hideOtherSlides = function() {
 document
  .querySelectorAll(options.slidesClass)
  .forEach((slide, index) => {
   slides[index].style = "display: none";
  });
};

.goToSlide() 方法采用参数 index,这是我们要显示的幻灯片的索引,此方法首先隐藏当前正在显示的任何幻灯片,然后仅显示我们要显示的幻灯片。

接下来,我们将添加 .next() 和 .previous() 辅助方法,分别帮助我们向前一步,或者向后一步(还记得我们之前附加的事件监听器吗?

this.next = function() {
 this.goToSlide(currentSlideIndex + 1);
};
this.previous = function() {
 this.goToSlide(currentSlideIndex - 1);
};

这两个方法基本上调用 .goToSlide() 方法,并将 currentSlideIndex 移动 1。

现在,我们还将创建一个 .init() 方法,该方法将在实例化构造函数时帮助我们进行设置。

this.init = function() {
 document.querySelectorAll(options.container).className +=
  " too-slide-slider-container";
 document
  .querySelectorAll(options.slidesClass)
  .forEach((slide, index) => {
   slides[index] = index;
   slides[index].style = "display:none";
   slides[index].className =
    " too-slide-single-slide too-slide-fade";
  });

 this.goToSlide(0);
 this.prepareControls();
};

如您所见,.init() 方法获取所有幻灯片图像并将其存储在我们之前声明的 slides 数组中,并默认隐藏所有图像。

然后,它通过调用 .goToSlide(0) 方法显示幻灯片中的第一张图像,并且还通过调用 .prepareControls() 设置我们的控制按钮。

为了收尾我们的构造函数代码,我们将在构造函数中调用 .init() 方法,这样每当构造函数被初始化时,.init() 方法总是被调用。

最终代码如下所示:

function ToolSidePlugin(options) {
 let defaultOptions = {
  slidesClass: ".singleSlide",
  container: ".slideContainer",
  nextButton: ".nextSlide",
  previousButton: ".previousSlide",
 };

 options = { ...defaultOptions, ...options };

 let _this = this;
 let slides = [];
 let currentSlideIdex = 0;

 this.init = function() {
  document.querySelectorAll(
   options.container
  ).className += " too-slide-slider-container";
  document
   .querySelectorAll(options.slidesClass)
   .forEach((slide, index) => {
    slides[index] = index;
    slides[index].style = "display:none";
    slides[index].className =
     " too-slide-single-slide too-slide-fade";
   });

  this.goToSlide(0);
  this.prepareControls();
 };

 this.prepareControls = function() {
  const nextButton = document.createElement("button");
  const previousButton = document.createElement("button");

  nextButton.setAttribute("class", "next");
  nextButton.InnerHTML = "Next";

  previousButton.setAttribute("class", "prev");
  nextButton.InnerHTML = "Prev";

  let controleContainer = document.createElement("div");

  controleContainer.setAttribute(
   "class",
   "too-slide-control-container"
  );

  controleContainer.appendChild(previousButton);
  controleContainer.appendChild(nextButton);

  document
   .querySelector(options.container)
   .appendChild(controleContainer);

  nextButton.addEventListener("click", function() {
   _this.next();
  });
  previousButton.addEventListener("click", function() {
   _this.previous();
  });
 };

 this.goToSlide = function(index) {
  this.hideOtherSlides();
  if (index > slides.length - 1) {
   index = 0;
  }
  if (index < 0) {
   index = slides.length - 1;
  }
  slides[index].style = "display:block";
  currentSlideIndex = index;
 };

 this.hideOtherSlides = function() {
  document
   .querySelectorAll(options.slidesClass)
   .forEach((slide, index) => {
    slides[index].style = "display: none";
   });
 };

 this.next = function() {
  this.goToSlide(currentSlideIndex + 1);
 };
 this.previous = function() {
  this.goToSlide(currentSlideIndex - 1);
 };

 this.init();
}

添加 CSS

在存放我们的插件项目的文件夹中,我们将添加一个 CSS 文件,其中包含我们的滑块的基本样式。我将把这个文件称为 tooSlide.css。

* {
 box-sizing: border-box;
}

body {
 font-family: Verdana, sans-serif;
 margin: 0;
 padding: 30px;
}

.too-slide-single-slide {
 display: none;
 max-height: 100%;
 width: 100%;
}

.too-slide-single-slide img {
 height: 100%;
 width: 100%;
}
img {
 vertical-align: middle;
}

/* Slideshow container */
.too-slide-slider-container {
 width: 100%;
 max-width: 100%;
 position: relative;
 margin: auto;
 height: 400px;
}

.prev,
.next {
 cursor: pointer;
 position: absolute;
 top: 50%;
 width: auto;
 padding: 10px;
 margin-right: 15px;
 margin-left: 15px;
 margin-top: -22px;
 color: white;
 font-weight: bold;
 font-size: 18px;
 transition: 0.6s ease;
 border-radius: 0 3px 3px 0;
 user-select: none;
 border-style: unset;
 background-color: blue;
}

.next {
 right: 0;
 border-radius: 3px 0 0 3px;
}

.prev:hover,
.next:hover {
 background-color: rgba(0, 0, 0, 0.8);
}

.too-slide-fade {
 -webkit-animation-name: too-slide-fade;
 -webkit-animation-duration: 1.5s;
 animation-name: too-slide-fade;
 animation-duration: 1.5s;
}

@-webkit-keyframes too-slide-fade {
 from {
  opacity: 0.4;
 }
 to {
  opacity: 1;
 }
}

@keyframes too-slide-fade {
 from {
  opacity: 0.4;
 }
 to {
  opacity: 1;
 }
}

/* On smaller screens, decrease text size */
@media only screen and (max-width: 300px) {
 .prev,
 .next,
 .text {
  font-size: 11px;
 }
}

测试我们的插件

为了测试我们的插件,我们将创建一个 HTML 文件,我将其命名为 index.html。我们还将添加 4 张图片用作幻灯片,所有图片都与我们的插件 JavaScript 代码位于同一目录中。

我的 HTML 文件如下所示:

<!DOCTYPE html>
<html lang="en">
 <head>
  <meta charset="UTF-8" />
  <meta
   name="viewport"
   content="width=device-width, initial-scale=1.0"
  />
  <title>测试幻灯片</title>
  <link rel="stylesheet" href="tooSlide.css" rel="external nofollow" />
 </head>
 <body>
  <div class="contaoner">
   <div class="slideContainer">
    <div class="singleSlide">
     <img
      src="slide1.png"
      alt="slide1"
      class="slideImage"
     />
    </div>
    <div class="singleSlide">
     <img
      src="slide2.png"
      alt="slide2"
      class="slideImage"
     />
    </div>
    <div class="singleSlide">
     <img
      src="slide3.png"
      alt="slide3"
      class="slideImage"
     />
    </div>
    <div class="singleSlide">
     <img
      src="slide4.png"
      alt="slide4"
      class="slideImage"
     />
    </div>
   </div>
  </div>

  <script src="tooSlide.js"></script>
  <script>
   var slider = new ToolSidePlugin({
    slideClass: ".singleSlide",
    container: ".slideContainer",
    nextButton: ".next",
    previousButton: ".prev",
   });
  </script>
 </body>
</html>

在 HTML 文件的头部分,我调用了 tooSlide.css 文件,而在文件的末尾,我调用了 tooSlide.js 文件。

完成此操作后,我们将能够实例化我们的插件构造函数:

var slider = new ToolSidePlugin({
 slideClass: ".singleSlide",
 container: ".slideContainer",
 nextButton: ".next",
 previousButton: ".prev",
});

最后的效果:

创建与框架无关的JavaScript插件

为您的 JavaScript 项目编写文档

文档是你教人们如何使用你的插件。因此,它需要你花一些心思。

对于我们新创建的插件,我将从在项目目录中创建 README.md 文件开始。

创建与框架无关的JavaScript插件

发布你的插件

在编写了您的插件之后,您很可能希望其他开发人员从您的新创建中受益,因此我将向您展示如何做到这一点。

你可以通过两种方式让你的插件对其他人可用:

在 Github 上托管它,当您这样做时,任何人都可以下载仓库,包括文件(.js 和.css),并立即使用您的插件。
发布在 npm 上,请查看官方的 npm 文档来指导您。
就是这样。

结束

在本文中,我们构建了一个插件来完成一件事:幻灯片图像。

它也是零依赖的,现在我们可以开始用我们的代码来帮助别人,就像我们也得到了帮助一样。

该插件教程的代码可在我的 github 上找到:https://github.com/dunizb/CodeTest/tree/master/JavaScript/TooSlidePlugin

以上就是创建与框架无关的JavaScript插件的详细内容,更多关于创建 JavaScript插件的资料请关注三水点靠木其它相关文章!

Javascript 相关文章推荐
什么是JavaScript
Aug 13 Javascript
jquery validator 插件增加日期比较方法
Feb 21 Javascript
不使用中间变量,交换int型的 a, b两个变量的值。
Oct 29 Javascript
Javascript递归打印Document层次关系实例分析
May 15 Javascript
JavaScript判断undefined类型的正确方法
Jun 30 Javascript
微信小程序 PHP后端form表单提交实例详解
Jan 12 Javascript
微信小程序图片自适应支持多图实例详解
Jun 21 Javascript
jQuery 循环遍历改变a标签的href(实例讲解)
Jul 12 jQuery
create-react-app使用antd按需加载的样式无效问题的解决
Feb 26 Javascript
JavaScript判断对象和数组的两种方法
May 31 Javascript
微信小程序绘制图片发送朋友圈
Jul 25 Javascript
webpack+vue-cil 中proxyTable配置接口地址代理操作
Jul 18 Javascript
jQuery实现可以扩展的日历
Dec 01 #jQuery
如何使用gpu.js改善JavaScript的性能
Dec 01 #Javascript
jQuery实现容器间的元素拖拽功能
Dec 01 #jQuery
jQuery实现查看图片功能
Dec 01 #jQuery
vue实现表格合并功能
Dec 01 #Vue.js
vue element实现表格合并行数据
Nov 30 #Vue.js
Vue Elenent实现表格相同数据列合并
Nov 30 #Vue.js
You might like
PHP实现超简单的SSL加密解密、验证及签名的方法示例
2017/08/28 PHP
总结一些js自定义的函数
2006/08/05 Javascript
由JavaScript技术实现的web小游戏(不含网游)
2010/06/12 Javascript
读jQuery之十二 删除事件核心方法
2011/07/31 Javascript
简单实现限制uploadify上传个数
2015/11/16 Javascript
基于jQuery倒计时插件实现团购秒杀效果
2016/05/13 Javascript
Bootstrap编写一个在当前网页弹出可关闭的对话框 非弹窗
2016/06/30 Javascript
jQuery实现的多张图无缝滚动效果【测试可用】
2016/09/12 Javascript
angular实现表单验证及提交功能
2017/02/01 Javascript
详解Vue 开发模式下跨域问题
2017/06/06 Javascript
nodejs动态创建二维码的方法
2017/08/12 NodeJs
JS判断字符串是否为整数的方法--简单的正则判断
2018/07/23 Javascript
mpvue+vant app搭建微信小程序的方法步骤
2019/02/11 Javascript
vue如何搭建多页面多系统应用
2020/06/17 Javascript
vue中使用echarts的示例
2021/01/03 Vue.js
vue二选一tab栏切换新做法实现
2021/01/19 Vue.js
Python字符串的encode与decode研究心得乱码问题解决方法
2009/03/23 Python
跟老齐学Python之坑爹的字符编码
2014/09/28 Python
Python基础语法(Python基础知识点)
2016/02/28 Python
python切片及sys.argv[]用法详解
2018/05/25 Python
python面试题小结附答案实例代码
2019/04/11 Python
Django如何自定义model创建数据库索引的顺序
2019/06/20 Python
简单了解python PEP的一些知识
2019/07/13 Python
解决Pycharm中恢复被exclude的项目问题(pycharm source root)
2020/02/14 Python
Python+Appium实现自动化清理微信僵尸好友的方法
2021/02/04 Python
css3 border旋转时的动画应用
2016/01/22 HTML / CSS
浅析canvas元素的html尺寸和css尺寸对元素视觉的影响
2019/07/22 HTML / CSS
Bibloo匈牙利:女装、男装、童装及鞋子和配饰
2019/04/14 全球购物
如何填写个人简历自我评价
2013/12/10 职场文书
2014年平安建设工作总结
2014/11/19 职场文书
2015年远程教育工作总结
2015/05/20 职场文书
暂住证明怎么写
2015/06/19 职场文书
2019年圣诞节祝福语集锦
2019/12/25 职场文书
Python函数中的不定长参数相关知识总结
2021/06/24 Python
详解Python+OpenCV进行基础的图像操作
2022/02/15 Python
Redis官方可视化工具RedisInsight安装使用教程
2022/04/19 Redis