angular引用第三方js插件遇到的问题

一、找到Leaflet.Autocomplete搜索框在左边的例子的css和js代码

leaflet是一个开源并且对移动端友好的交互式地图 JavaScript 库,它的访问地址:Plugins - Leaflet - 一个交互式地图 JavaScript 库

leaflet里面有很多的插件,其中搜索功能比较好的就是Leaflet.Autocomplete。

我的项目是用angular框架,逻辑是在component.ts中完成的。需要做的效果就是在地图网页上加一个搜索地址的功能,这里我引用leaflet插件库里的Leaflet.Autocomplete,这个插件搜索功能比较好用,但是呢它没有封装到npm,所以只能把它的js和css代码都下载下来。

先访问leaflet的网址然后跟着下面两张图操作就可以去到Leaflet.Autocomplete的GitHub页面

 

 

leaflet.Autocomplete的默认样式是这样的,

 

如果需要像我那样的搜索框在左边的话,就继续往下滑,找到下面这个

然后就可以进到在线预览界面,点击右上角,就可以进到这例子的GitHub页面 

 找到你要的效果的例子的序号,我要的效果是第50个例子

点进去,就可以看到这个例子的代码了 

 

二、开始将第三方的插件用到自己的项目中

先进到插件的index.html页面中可以看到它引用了的css和js

我们公司的项目是用的angular框架,我在最外层的index.html页面也跟着引入了相关的css和js

其中,这两个css和js是引用的本地的,所以需要将这两个文件拷贝下来

 

我把这两个文件另取名字分别放到了项目中

 

接着需要到angular.json全局引用一下这两个文件

 然后需要用到这个插件的js文件的ts文件中引用一下,但是ts不能直接用import来引入js(我也不明白为啥不行,我百度有些说可以,但是我直接import会报错),所以需要给整个js取个函数名,然后function来包装一下。原本下载下来的js如下

/* eslint-disable no-undef */
/**
 * autocomplete on map
 * https://github.com/tomickigrzegorz/autocomplete
 *
 */

// config map
let config = {
  minZoom: 7,
  maxZoom: 18,
};
// magnification with which the map will start
const zoom = 18;
// co-ordinates
const lat = 52.22977;
const lng = 21.01178;

// calling map
const map = L.map("map", config).setView([lat, lng], zoom);

// Used to load and display tile layers on the map
// Most tile servers require attribution, which you can set under `Layer`
L.tileLayer("https://tile.openstreetmap.org/{z}/{x}/{y}.png", {
  attribution:
    '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors',
}).addTo(map);

// --------------------------------------------------------------
// create seearch button

// add "random" button
const buttonTemplate = `<div class="leaflet-search"><svg version="1.1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32"><path d="M31.008 27.231l-7.58-6.447c-0.784-0.705-1.622-1.029-2.299-0.998 1.789-2.096 2.87-4.815 2.87-7.787 0-6.627-5.373-12-12-12s-12 5.373-12 12 5.373 12 12 12c2.972 0 5.691-1.081 7.787-2.87-0.031 0.677 0.293 1.515 0.998 2.299l6.447 7.58c1.104 1.226 2.907 1.33 4.007 0.23s0.997-2.903-0.23-4.007zM12 20c-4.418 0-8-3.582-8-8s3.582-8 8-8 8 3.582 8 8-3.582 8-8 8z"></path></svg></div><div class="auto-search-wrapper max-height"><input type="text" id="marker" autocomplete="off"  aria-describedby="instruction" aria-label="Search ..." /><div id="instruction" class="hidden">When autocomplete results are available use up and down arrows to review and enter to select. Touch device users, explore by touch or with swipe gestures.</div></div>`;

// create custom button
const customControl = L.Control.extend({
  // button position
  options: {
    position: "topleft",
    className: "leaflet-autocomplete",
  },

  // method
  onAdd: function () {
    return this._initialLayout();
  },

  _initialLayout: function () {
    // create button
    const container = L.DomUtil.create(
      "div",
      "leaflet-bar " + this.options.className
    );

    L.DomEvent.disableClickPropagation(container);

    container.innerHTML = buttonTemplate;

    return container;
  },
});

// adding new button to map controll
map.addControl(new customControl());

// --------------------------------------------------------------

// input element
const root = document.getElementById("marker");

function addClassToParent() {
  const searchBtn = document.querySelector(".leaflet-search");
  searchBtn.addEventListener("click", (e) => {
    // toggle class
    e.target
      .closest(".leaflet-autocomplete")
      .classList.toggle("active-autocomplete");

    // add placeholder
    root.placeholder = "Search ...";

    // focus on input
    root.focus();

    // use destroy method
    autocomplete.destroy();
  });
}

addClassToParent();

// function clear input
map.on("click", () => {
  document
    .querySelector(".leaflet-autocomplete")
    .classList.remove("active-autocomplete");

  clickOnClearButton();
});

// autocomplete section
// more config find in https://github.com/tomickigrzegorz/autocomplete
// --------------------------------------------------------------

const autocomplete = new Autocomplete("marker", {
  delay: 1000,
  selectFirst: true,
  howManyCharacters: 2,

  onSearch: function ({ currentValue }) {
    const api = `https://nominatim.openstreetmap.org/search?format=geojson&limit=5&q=${encodeURI(
      currentValue
    )}`;

    /**
     * Promise
     */
    return new Promise((resolve) => {
      fetch(api)
        .then((response) => response.json())
        .then((data) => {
          resolve(data.features);
        })
        .catch((error) => {
          console.error(error);
        });
    });
  },

  onResults: ({ currentValue, matches, template }) => {
    const regex = new RegExp(currentValue, "i");
    // checking if we have results if we don't
    // take data from the noResults method
    return matches === 0
      ? template
      : matches
          .map((element) => {
            return `
              <li role="option">
                <p>${element.properties.display_name.replace(
                  regex,
                  (str) => `<b>${str}</b>`
                )}</p>
              </li> `;
          })
          .join("");
  },

  onSubmit: ({ object }) => {
    const { display_name } = object.properties;
    const cord = object.geometry.coordinates;
    // custom id for marker
    // const customId = Math.random();

    // remove last marker
    map.eachLayer(function (layer) {
      if (layer.options && layer.options.pane === "markerPane") {
        if (layer._icon.classList.contains("leaflet-marker-locate")) {
          map.removeLayer(layer);
        }
      }
    });

    // add marker
    const marker = L.marker([cord[1], cord[0]], {
      title: display_name,
    });

    // add marker to map
    marker.addTo(map).bindPopup(display_name);

    // set marker to coordinates
    map.setView([cord[1], cord[0]], 8);

    // add class to marker
    L.DomUtil.addClass(marker._icon, "leaflet-marker-locate");
  },

  // the method presents no results
  noResults: ({ currentValue, template }) =>
    template(`<li>No results found: "${currentValue}"</li>`),
});

我修改后的js如下:

function leafletSearch(map) {
/* eslint-disable no-undef */
/**
 * autocomplete on map
 * https://github.com/tomickigrzegorz/autocomplete
 *
 */

// config map
let config = {
  minZoom: 7,
  maxZoom: 18,
};
// magnification with which the map will start
const zoom = 18;
// co-ordinates
const lat = 52.22977;
const lng = 21.01178;

// calling map
const map = L.map("map", config).setView([lat, lng], zoom);

// Used to load and display tile layers on the map
// Most tile servers require attribution, which you can set under `Layer`
L.tileLayer("https://tile.openstreetmap.org/{z}/{x}/{y}.png", {
  attribution:
    '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors',
}).addTo(map);

// --------------------------------------------------------------
// create seearch button

// add "random" button
const buttonTemplate = `<div class="leaflet-search"><svg version="1.1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32"><path d="M31.008 27.231l-7.58-6.447c-0.784-0.705-1.622-1.029-2.299-0.998 1.789-2.096 2.87-4.815 2.87-7.787 0-6.627-5.373-12-12-12s-12 5.373-12 12 5.373 12 12 12c2.972 0 5.691-1.081 7.787-2.87-0.031 0.677 0.293 1.515 0.998 2.299l6.447 7.58c1.104 1.226 2.907 1.33 4.007 0.23s0.997-2.903-0.23-4.007zM12 20c-4.418 0-8-3.582-8-8s3.582-8 8-8 8 3.582 8 8-3.582 8-8 8z"></path></svg></div><div class="auto-search-wrapper max-height"><input type="text" id="marker" autocomplete="off"  aria-describedby="instruction" aria-label="Search ..." /><div id="instruction" class="hidden">When autocomplete results are available use up and down arrows to review and enter to select. Touch device users, explore by touch or with swipe gestures.</div></div>`;

// create custom button
const customControl = L.Control.extend({
  // button position
  options: {
    position: "topleft",
    className: "leaflet-autocomplete",
  },

  // method
  onAdd: function () {
    return this._initialLayout();
  },

  _initialLayout: function () {
    // create button
    const container = L.DomUtil.create(
      "div",
      "leaflet-bar " + this.options.className
    );

    L.DomEvent.disableClickPropagation(container);

    container.innerHTML = buttonTemplate;

    return container;
  },
});

// adding new button to map controll
map.addControl(new customControl());

// --------------------------------------------------------------

// input element
const root = document.getElementById("marker");

function addClassToParent() {
  const searchBtn = document.querySelector(".leaflet-search");
  searchBtn.addEventListener("click", (e) => {
    // toggle class
    e.target
      .closest(".leaflet-autocomplete")
      .classList.toggle("active-autocomplete");

    // add placeholder
    root.placeholder = "Search ...";

    // focus on input
    root.focus();

    // use destroy method
    autocomplete.destroy();
  });
}

addClassToParent();

// function clear input
map.on("click", () => {
  document
    .querySelector(".leaflet-autocomplete")
    .classList.remove("active-autocomplete");

  clickOnClearButton();
});

// autocomplete section
// more config find in https://github.com/tomickigrzegorz/autocomplete
// --------------------------------------------------------------

const autocomplete = new Autocomplete("marker", {
  delay: 1000,
  selectFirst: true,
  howManyCharacters: 2,

  onSearch: function ({ currentValue }) {
    const api = `https://nominatim.openstreetmap.org/search?format=geojson&limit=5&q=${encodeURI(
      currentValue
    )}`;

    /**
     * Promise
     */
    return new Promise((resolve) => {
      fetch(api)
        .then((response) => response.json())
        .then((data) => {
          resolve(data.features);
        })
        .catch((error) => {
          console.error(error);
        });
    });
  },

  onResults: ({ currentValue, matches, template }) => {
    const regex = new RegExp(currentValue, "i");
    // checking if we have results if we don't
    // take data from the noResults method
    return matches === 0
      ? template
      : matches
          .map((element) => {
            return `
              <li role="option">
                <p>${element.properties.display_name.replace(
                  regex,
                  (str) => `<b>${str}</b>`
                )}</p>
              </li> `;
          })
          .join("");
  },

  onSubmit: ({ object }) => {
    const { display_name } = object.properties;
    const cord = object.geometry.coordinates;
    // custom id for marker
    // const customId = Math.random();

    // remove last marker
    map.eachLayer(function (layer) {
      if (layer.options && layer.options.pane === "markerPane") {
        if (layer._icon.classList.contains("leaflet-marker-locate")) {
          map.removeLayer(layer);
        }
      }
    });

    // add marker
    const marker = L.marker([cord[1], cord[0]], {
      title: display_name,
    });

    // add marker to map
    marker.addTo(map).bindPopup(display_name);

    // set marker to coordinates
    map.setView([cord[1], cord[0]], 8);

    // add class to marker
    L.DomUtil.addClass(marker._icon, "leaflet-marker-locate");
  },

  // the method presents no results
  noResults: ({ currentValue, template }) =>
    template(`<li>No results found: "${currentValue}"</li>`),
});
}

 其实就是在最外面套了一个function leafletSearch(map) {}

然后就到ts中引用一下它,写法如下

declare function leafletSearch(map): any

然后,地图上就能使用搜索地址的功能了 。

以上就是这次的小总结~

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
### 回答1: 如果你想让其他人使用你编写的 JavaScript 文件,你可以将其打包成一个库或者件,然后发布到 npm 或者 GitHub 等代码托管平台上。 下面是一些步骤: 1. 创建一个项目并编写 JavaScript 文件 2. 使用工具如 Webpack 或 Rollup 打包 JavaScript 文件为库或件 3. 通过 npm 或 GitHub 等代码托管平台发布你的库或件 4. 在文档中提供使用说明和示例代码 当其他人想要使用你的库或件时,他们可以通过 npm 或者将代码下载到本地,然后在他们的项目中引入你的库或件,并按照你提供的文档进行使用。 ### 回答2: JavaScript编辑的文件可以通过以下几种方式提供给第三方使用: 1. 直接提供.js文件:将JavaScript文件打包为一个单独的.js文件,然后将该文件提供给第三方使用。第三方只需要将该文件引入到他们的HTML页面中,就可以使用其中定义的函数、对象或变量。 2. 提供一个库或框架:将JavaScript文件封装成一个库或框架,使得第三方可以更加方便地使用其中的功能。例如,常见的JavaScript库如jQuery、React等,或者框架如Angular、Vue等。第三方可以通过链接或下载这些库来使用其中定义的函数、组件、指令等。 3. 提供一个包管理工具:通过使用包管理工具如NPM或Yarn,将JavaScript文件发布到一个公共或私有的代码仓库中,然后第三方可以通过包管理工具将该文件作为一个依赖项添加到他们的项目中。这种方式可以方便地管理和更新依赖项,并且可以在多个项目之间共享代码。 4. 提供一个API:将JavaScript文件部署到服务器上,并提供一个API供第三方进行调用。第三方可以通过发送请求到该API,并传递相应的参数来调用其中定义的函数或执行某些操作。这种方式通常用于提供与服务器交互的功能或提供一些高级功能给第三方使用。 总的来说,JavaScript编辑的文件可以通过直接提供.js文件、提供库或框架、提供包管理工具、或提供API等方式给第三方使用。根据具体的需求和使用场景选择合适的方式。 ### 回答3: JavaScript编辑的文件可以给第三方使用的主要方法有以下几种: 1. 打包成库:将JavaScript文件编写成一个独立的库,通过打包工具如Webpack或Rollup打包,可以生成一个可以直接在浏览器或服务器端引用的压缩文件(通常是.min.js文件)。第三方用户可以通过script标签或其他方式引入该文件,并使用其中的函数、方法或对象。 2. 导出为模块:使用模块化工具如CommonJS、ES Modules或AMD将JavaScript文件导出为可复用的模块。第三方用户可以通过import或require语句引入该模块,并使用其中的函数、对象、类等。 3. 发布到CDN:将JavaScript文件上传到CDN(内容分发网络),CDN会将文件分发到全球的各个节点。第三方用户可以直接从CDN上引用该文件,无需下载和部署到自己的服务器上,提高了文件加载速度和用户体验。 4. 提供API接口:将JavaScript文件编写为一个服务端API接口,提供给第三方用户调用。用户可以通过HTTP请求访问该接口,并按照接口文档提供的规范传入参数,通过接口获取所需的数据或执行特定的操作。 需要注意的是,在提供给第三方使用时应该注意文件的兼容性和安全性,并提供详细的文档和示例代码以帮助用户正确使用。同时,还可以考虑使用JavaScript的打包工具、模块化工具或代码混淆工具,以提高代码可读性和保护代码安全性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Bonny雨曦

码字不易,多多鼓励

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值