将 jQuery 插件转换为 TypeScript

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/34811716/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-21 03:13:13  来源:igfitidea点击:

Converting a jQuery plugin to TypeScript

javascriptjqueryhtmltypescript

提问by Canvas

Ok so first off here is my very basic jQuery plugin

好的,首先这里是我非常基本的 jQuery 插件

(function ($){
    $.fn.greenify = function (options) {
        var settings = $.extend({
            // These are the defaults
            color: '#556b2f',
            backgroundColor: 'white'
        }, options);
}(jQuery));

$('a').greenify({
    color: 'orange'
}).showLinkLocation();

Basically all this does is change the text color and background-color with the provided element. Now what I am trying to do is convert this simple plugin into TypeScript

基本上所有这些都是使用提供的元素更改文本颜色和背景颜色。现在我要做的是将这个简单的插件转换成 TypeScript

I have tried a few things and the closest I got is this.

我已经尝试了一些东西,我得到的最接近的是这个。

TypeScript

打字稿

/// <reference path="../../typings/jquery/jquery.d.ts" />

module Coloring
{
    interface IGreenifyOptions
    {
        color: string;
        backgroundColor: string;
    }

    export class GreenifyOptions implements IGreenifyOptions
    {
        // Fields
        color: string;
        backgroundColor: string;

        constructor(color: string, backgroundColor: string)
        {
            this.color = color;
            this.backgroundColor = backgroundColor;
        }
    }

    export class Greenify
    {
        // Fields
        element: JQuery;
        options: GreenifyOptions;

        constructor(element: JQuery, options: GreenifyOptions)
        {
            this.element = element;
            this.options = options;

            this.OnCreate();
        }

        OnCreate()
        {
            this.element.css('color', this.options.color).css('background-color', this.options.backgroundColor);
        }
    }
}

JQuery which calls it

调用它的 JQuery

$(function ()
{
    var options: Coloring.GreenifyOptions = new Coloring.GreenifyOptions('#0F0', '#000');

    var $elems = $('a');
    $elems.each(function()
    {
        var result = new Coloring.Greenify($(this), options)
    });
});

However I don't want to provide the element like the above new Coloring.Greenify($(this), options), I basically want to do something like this

但是我不想提供像上面那样的元素new Coloring.Greenify($(this), options),我基本上想做这样的事情

$('a').Coloring.Greenify(options);

or

或者

$('a').Coloring.Greenify(Coloring.GreenifyOptions()
{
    color: '#F0F',
    backgroundColor: '#FFF'
});

But I can't seem to figure how to tell TypeScript that the element it is attached to already is the Jqueryelement. Could anyone shine some light on this to help me out.

但我似乎无法弄清楚如何告诉 TypeScript 它所附加的Jquery元素已经是该元素。任何人都可以对此有所了解以帮助我。

P.S. the above I have works fine, I just want to change the calling code.

PS 以上我工作正常,我只想更改调用代码。



Update

更新

This is what I have at the moment and it works

这就是我目前拥有的并且有效

TypeScript

打字稿

interface JQuery
{
    Greenify();
    Greenify(options: Coloring.GreenifyOptions);
}

(function ($)
{
    $.fn.Greenify = function (options)
    {
        return new Coloring.Greenify(this, options);
    }
})(jQuery);

jQuery

jQuery

var $elems = $('a').Greenify(options);

However it means I have to provide options and if I do the constructor without options I get options is undefined. The answer I have ticked as correct is correct for the question I have asked. However just keep in mind that the answer provided required you provide options into your typescript constructor, I am going to see on how to have default options and then override them in the constructor but this is a different question :)

然而,这意味着我必须提供选项,如果我在没有选项的情况下执行构造函数,我得到的选项是未定义的。我勾选正确的答案对于我提出的问题是正确的。但是请记住,提供的答案要求您在打字稿构造函数中提供选项,我将了解如何使用默认选项,然后在构造函数中覆盖它们,但这是一个不同的问题:)



Update 2

更新 2

Just to let everyone know I have found a way to provide options to your plugin or not.

只是为了让大家知道我找到了一种方法来为您的插件提供选项。

What you can do is this

你能做的是这个

TypeScript class

打字稿类

export class Greenify
    {
        // Default Options
        static defaultOptions: IGreenifyOptions =
        {
            color: '#F00',
            backgroundColor: '#00F'
        };

        // Fields
        element: JQuery;
        options: GreenifyOptions;

        constructor(element: JQuery, options: GreenifyOptions)
        {
            // Merge options
            var mergedOptions: GreenifyOptions = $.extend(Greenify.defaultOptions, options);
            this.options = mergedOptions;
            this.element = element;

            this.OnCreate();
        }

        OnCreate()
        {
            this.element.css('color', this.options.color).css('background-color', this.options.backgroundColor);
        }

    }

TypeScript Interface

打字稿接口

interface JQuery
{
    Greenofy();
    Greenify(obj?: any);
    Greenify(options?: Coloring.GreenifyOptions);
}

(function ($)
{
    $.fn.Greenify = function (options)
    {
        return new Coloring.Greenify(this, options);
    }
})(jQuery);

jQuery code to call the plugin with one optional option

使用一个可选选项调用插件的 jQuery 代码

$(function ()
{
    var $elems = $('a').Greenify(<Coloring.GreenifyOptions>{
        color: '#00F'
    });
});

So not the output will make the anchors background color '#00F' which is the default and the option I have provided will make the anchor text color '#00F'.

因此,输出不会使锚点背景颜色为“#00F”,这是默认值,而我提供的选项将使锚点文本颜色为“#00F”。

I hope this helps anyone else that is having the same problem as me :)

我希望这可以帮助其他和我有同样问题的人:)

采纳答案by jsonmurphy

You can create and referenceyour own definitions file greenify.d.tsand add the function like this:

您可以创建和引用自己的定义文件greenify.d.ts并添加如下函数:

interface Jquery {
     greenify: (options: Coloring.IGreenifyOptions) => void
}

Then you can simple call it like:

然后你可以简单地称之为:

$('a').greenify(new GreenifyOptions(...));

or

或者

$('a').greenify({color:'', backgroundColor:''});

Explanation:

解释:

At compile time typescript will actually merge all interface definitions.

在编译时打字稿实际上会合并所有接口定义。

Side Note:

边注:

if you're adamant about having it exactly as $('a').Coloring.Greenify(..)then you'll have to change a lot more:

如果您坚持要完全一样,$('a').Coloring.Greenify(..)那么您将不得不进行更多更改:

  • Coloring couldnt be your module's name anymore as you'd have to use it in the interface definition above
  • You would probably have to create a class that has .Greenify as static method
  • Possibly more...
  • 着色不能再是您的模块的名称,因为您必须在上面的接口定义中使用它
  • 您可能必须创建一个将 .Greenify 作为静态方法的类
  • 可能更多...

All in all it's probably easier to stick with my initial solution as it its a bit less verbose but that's up to you.

总而言之,坚持我的初始解决方案可能更容易,因为它不那么冗长,但这取决于您。

Hope that helps

希望有帮助

Update:

更新:

To account for the default options you can modify the interface definition to have overrides:

要考虑默认选项,您可以修改接口定义以进行覆盖:

interface Jquery {
     greenify: () => void;
     greenify: (options: Coloring.IGreenifyOptions) => void;
}

interface IGreenifyOptions
{
    color?: string;
    backgroundColor?: string;
}

回答by vorillaz

Creating jQuery plugins along with TypeScript can get a bit messy. I personally prefer keeping the jQuery plugin chaining syntax, mostly for consistency and maintainability .

与 TypeScript 一起创建 jQuery 插件可能会有点混乱。我个人更喜欢保留 jQuery 插件链接语法,主要是为了一致性和可维护性。

So, after the module declaration you can basically wrap around your implementation extending the jQuery prototype as:

因此,在模块声明之后,您基本上可以将扩展 jQuery 原型的实现包装为:

module Coloring {
  interface IGreenifyOptions {
    color: string;
    backgroundColor: string;
  }

  export class GreenifyOptions implements IGreenifyOptions {
    // Fields
    color: string;
    backgroundColor: string;

    constructor(color: string, backgroundColor: string) {
      this.color = color;
      this.backgroundColor = backgroundColor;
    }
  }

  export class Greenify {
    // Fields
    element: JQuery;
    options: GreenifyOptions;

    constructor(element: JQuery, options: GreenifyOptions) {
      this.element = element;
      this.options = options;

      this.OnCreate();
    }

    OnCreate() {
      this.element.css('color', this.options.color).css('background-color', this.options.backgroundColor);
    }
  }
}


//jquery plugin wrapper.
;
(function(w, $) {
    //no jQuery around
  if (!$) return false;

  $.fn.extend({
    Coloring: function(opts) {
      //defaults
      var defaults: Coloring.GreenifyOptions = new Coloring.GreenifyOptions('#0F0', '#000');

      //extend the defaults!
      var opts = $.extend({}, defaults, opts)

      return this.each(function() {
        var o = opts;
        var obj = $(this);
        new Coloring.Greenify(obj, o);

      });
    }
  });
})(window, jQuery);

Fetching the plugin as:

获取插件为:

$(function() {

  var $a = $('a').Coloring();
  var $div = $('div').Coloring({
    color: '#F0F',
    backgroundColor: '#FFF'
  });
  var $div = $('strong').Coloring({
    color: '#gold',
    backgroundColor: 'pink'
  });
});

Demo

演示