整合营销服务商

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

免费咨询热线:

我再也不敢说我会写前端 Button组件「实践」

我再也不敢说我会写前端 Button组件「实践」


者:彭道宽

https://juejin.im/post/5e8d4300f265da47f85de3db

钮(Button)在 Bootstrap 按钮 中介绍过。通过按钮(Button)插件,您可以添加进一些交互,比如控制按钮状态,或者为其他组件(如工具栏)创建按钮组。

如果您想要单独引用该插件的功能,那么您需要引用 button.js。或者,正如 Bootstrap 插件概览 一章中所提到,您可以引用 bootstrap.js 或压缩版的 bootstrap.min.js。

加载状态

如需向按钮添加加载状态,只需要简单地向 button 元素添加 data-loading-text="Loading..." 作为其属性即可,如下面实例所示:

实例

<buttonid="fat-btn"class="btn btn-primary"data-loading-text="Loading..."type="button"> 加载状态</button><script> $(function() { $(".btn").click(function(){ $(this).button('loading').delay(1000).queue(function() { // $(this).button('reset'); // $(this).dequeue(); }); }); }); </script>

结果如下所示:

单个切换

如需激活单个按钮的切换(即改变按钮的正常状态为按压状态,反之亦然),只需向 button 元素添加 data-toggle="button" 作为其属性即可,如下面实例所示:

实例

<buttontype="button"class="btn btn-primary"data-toggle="button"> 单个切换</button>

尝试一下 ?

结果如下所示:

复选框(Checkbox)

您可以创建复选框组,并通过向 btn-group 添加 data 属性 data-toggle="buttons" 来添加复选框组的切换。

实例

<divclass="btn-group"data-toggle="buttons"><labelclass="btn btn-primary"><inputtype="checkbox"> 选项 1 </label><labelclass="btn btn-primary"><inputtype="checkbox"> 选项 2 </label><labelclass="btn btn-primary"><inputtype="checkbox"> 选项 3 </label></div>

结果如下所示:

单选按钮(Radio)

类似地,您可以创建单选按钮组,并通过向 btn-group 添加 data 属性 data-toggle="buttons" 来添加单选按钮组的切换。

实例

<divclass="btn-group"data-toggle="buttons"><labelclass="btn btn-primary"><inputtype="radio"name="options"id="option1"> 选项 1 </label><labelclass="btn btn-primary"><inputtype="radio"name="options"id="option2"> 选项 2 </label><labelclass="btn btn-primary"><inputtype="radio"name="options"id="option3"> 选项 3 </label></div>

尝试一下 ?

结果如下所示:

用法

您可以 通过 JavaScript 启用按钮(Button)插件,如下所示:

$('.btn').button()

选项

没有选项。

方法

下面是一些按钮(Button)插件中有用的方法:

方法描述实例
button('toggle')切换按压状态。赋予按钮被激活的外观。您可以使用 data-toggle 属性启用按钮的自动切换。
$().button('toggle')
.button('loading')当加载时,按钮是禁用的,且文本变为 button 元素的 data-loading-text 属性的值。
$().button('loading')
.button('reset')重置按钮状态,文本内容恢复为最初的内容。当您想要把按钮返回为原始的状态时,该方法非常有用。
$().button('reset')
.button(string)该方法中的字符串是指由用户声明的任何字符串。使用该方法,重置按钮状态,并添加新的内容。
$().button(string)

实例

下面的实例演示了上面方法的用法:

实例

<h2>点击每个按钮查看方法效果</h2><h4>演示 .button('toggle') 方法</h4><divid="myButtons1"class="bs-example"><buttontype="button"class="btn btn-primary">原始</button></div><h4>演示 .button('loading') 方法</h4><divid="myButtons2"class="bs-example"><buttontype="button"class="btn btn-primary"data-loading-text="Loading...">原始 </button></div><h4>演示 .button('reset') 方法</h4><divid="myButtons3"class="bs-example"><buttontype="button"class="btn btn-primary"data-loading-text="Loading...">原始 </button></div><h4>演示 .button(string) 方法</h4><buttontype="button"class="btn btn-primary"id="myButton4"data-complete-text="Loading finished">请点击我</button><script>

$(function(){ $("#myButtons1 .btn").click(function(){ $(this).button('toggle'); }); }); $(function(){ $("#myButtons2 .btn").click(function(){ $(this).button('loading').delay(1000).queue(function(){}); }); }); $(function(){ $("#myButtons3 .btn").click(function(){ $(this).button('loading').delay(1000).queue(function(){ $(this).button('reset'); }); }); }); $(function(){ $("#myButton4").click(function(){ $(this).button('loading').delay(1000).queue(function(){ $(this).button('complete'); }); }); });

</script>

尝试一下 ?

结果如下所示:

如您还有不明白的可以在下面与我留言或是与我探讨QQ群308855039,我们一起飞!

一篇文章Stimulus:连接HTML和JavaScript的桥梁,实现简单的controller,并学习了Stimulus是如何连接HTML与JavaScript的。现在我们使用Stimulus来实现复制文本到粘贴板的按钮。

比如说,我们现在有一个需求,就是帮助用户生成密码,在密码旁边放置一个按钮,点击按钮后密码就被拷贝到粘贴板上了,这样就方便用户使用这个密码了。

打开public/index.html,修改body内容,填充一个简单的按钮,如下:

<div>
    PIN: <input type="text" value="1234" readonly>
    <button>Copy to Clipboard</button>
</div>



下一步,创建src/controllers/clipboard_controller.js,然后添加一个copy()方法:

import { Controller } from "@hotwired/stimulus"

export default class extends Controller {
    copy() {
    }
}

然后,给div添加data-controller=“clipboard”。只要是给元素添加了data-controller属性,Stimulus就会连接一个controller实例。

<div data-controller="clipboard">

我们还需要一个对输入框的引用,这样我们就可以在调用粘贴板API之前获取输入框的内容。给文本框添加data-clipboard-target=“source“:

PIN: <input data-clipboard-target="source" type="text" value="1234" readonly>

在controller中定义一个target,然后就可以通过this.sourceTarget访问文本框了。

import { Controller } from "@hotwired/stimulus"

export default class extends Controller {
    static targets=[ "source" ]
    
    copy() {
    }
}


解释一下这个targets:

当Stimulus加载你的controller类时,它会查看静态数组targets的字符串元素,对于每一个字符串,Stimulus会在controller中添加3个属性。在这里,对于“source”,会添加如下属性:

this.sourceTarget 在controller的域内的第一个source

this.sourceTargets 在controller的域内所有的source组成的一个数组

this.hasSourceTarget 在controller的域内是否有source


我们希望点击按钮时调用controller中的copy()方法,所以我们需要添加data-action=“clipboard#copy“

<button data-action="clipboard#copy">Copy to Clipboard</button>

你可以已经注意到在上面的动作描述符中省略了click->。那是因为Stimulus给button设置了click作为它默认的事件。


某些其他元素也有默认事件。下面是个全部列表:

元素

默认事件

a

click

button

click

details

toggle

form

submit

input

input

input type=“submit”

click

select

change

textarea

input

最终,在copy()方法中,我们获取输入框的内容,调用粘贴板API

copy() {
    navigator.clipboard.writeText(this.sourceTarget.value)
}


刷新页面,点击按钮,然后快捷键粘贴到Greet按钮前到输入框,可以看到1234。



到目前为止,在页面上同一时间只有一个controller实例。在页面上同时有一个controller的多个实例也是很正常的。


我们的controller是可以复用的,只要你需要在页面上添加复制内容的按钮,无论是哪个页面,只要把对应的属性值写好,我们的controller都是生效的。


还是上面的例子,再添加另外一个复制按钮:

<div data-controller="clipboard">
    PIN: <input data-clipboard-target="source" type="text" value="3737" readonly>
    <button data-action="clipboard#copy" class="clipboard-button">Copy to Clipboard</button>
</div>


刷新页面,验证一下两个复制按钮是否都生效。

我们再添加一个可以复制的元素,不用button,我们用a标签,

<div data-controller="clipboard">
    PIN: <input data-clipboard-target="source" type="text" value="6666" readonly>
    <a href="#" data-action="clipboard#copy" class="clipboard-button">Copy to Clipboard</a>
</div>



Stimulus允许我们使用任何元素,只要它设置了合适的data-action属性,就可以触发复制。

这个例子里,要注意一点,点击链接会使浏览器追踪a标签内的href属性跳转,可以取消这种默认行为,只需要在action中调用 event.preventDefault()就可以了。

copy(event) {
    event.preventDefault()    
    navigator.clipboard.writeText(this.sourceTarget.value)
}


还有另外一个方法,拷贝粘贴板上

copy(event) {
    event.preventDefault()    
    this.sourceTarget.select()
    document.execCommand("copy")
}


在本文中,我们看了一个在现实中把浏览器API包装在Stimulus的controller中的例子。还有一个controller的多个实例如何同时出现在页面上,我们还探索了actions和targets如何保持HTML和JavaScript的松散耦合。


下一篇文章,我们将优化一下这个复制粘贴板的功能,让它运行起来更加健壮。

Stimulus:浏览器不支持复制或者弱网条件下,怎么办?