- Java锁的逻辑(结合对象头和ObjectMonitor)
- 还在用饼状图?来瞧瞧这些炫酷的百分比可视化新图形(附代码实现)⛵
- 自动注册实体类到EntityFrameworkCore上下文,并适配ABP及ABPVNext
- 基于Sklearn机器学习代码实战
实习工作中,遇到一个需求,需要完成点击复制的功能,当文字过长的时候,让用户手拖再ctrl+c这种方式体验就不是很好了,如果可以点击一下直接复制就是一种不错的优化用户体验的方式.
经过查阅文档,网络上完成这个功能大多使用两大类方法 。
第一种是以document.execCommand() 方法为主,无论是手写还是使用clipboard.js插件都是依赖的这个方法,但是在MDN 文档中已经显示过时了.
第二种是用了navigator.clipboard的方法,避免了过时问题,但是在复制图片的时候会有一定的浏览器兼容性问题 。
这个方法其实就是在模拟用户选择元素然后右键复制的动作。尽管MDN已经显示这个方法过时了,但是仅针对copy这个指令,大部分主流浏览器都可以支持,所以这个方法仍然可以作为一种实现问题的方案.
根据MDN文档学习本方法的传参和返回值 。
bool = document.execCommand(aCommandName, aShowDefaultUI, aValueArgument)
这个方法可以传3个参数,并且会返回一个布尔值 。
先从返回值开始,返回值相对比较简单,如果返回的值是false就表示浏览器不支持使用这个操作,反之浏览器支持该操作就返回true.
虽然这个返回值看似可以用来提前判断浏览器兼容性,但是 文档中不推荐在调用一个命令前,尝试使用返回值去校验浏览器的兼容性 。
参数一共可以传3个,但是使用复制命令的时候只需要传第一个参数就可以。这里简单介绍一下3个参数 。
以本文主要讲的复制命令为例子:document.execCommand('copy') 。
前文讲到,MDN 不推荐在调用一个命令前,尝试使用返回值去校验浏览器的兼容性, 那么就需要用另外的方法去检测浏览器是否支持某个指令,浏览器为我们提供了一个方法叫document.queryCommandSupported(),使用这个方法可以检测浏览器是否支持某个指令,这个方法比较简单,只有1个参数,参数就传指令字符串,方法的返回值是一个布尔值表示当前浏览器是否支持这个指令.
举例如下:
。
if
(document.queryCommandSupported && document.queryCommandSupported('copy'
)){
//
先检测是否支持document.queryCommandSupported和copy指令
//
如果都支持直接执行指令
document.execCommand('copy'
) }
。
MDN文档中提到,document.queryCommandSupported也被弃用了,但是为了兼容性依然保留可用,当我们使用 document.execCommand的时候仍然可以用document.queryCommandSupported来检测是否支持。同时,它的浏览器兼容性也是比较好的,大部分主流浏览器都支持.
。
复制文本这个操作对比复制图片是相对比较简单的,一共包含2大步 。
一是选中要复制的元素 。
二是执行复制指令.
执行复制指令在前面的基本语法里已经讲到了,直接调用document.execCommand('copy')就可以了。剩下要做的便是先选中元素了。下面便介绍一下和选中元素相关的selection api 。
MDN文档上写道:Selection 对象表示用户选择的文本范围或插入符号的当前位置。它代表页面中的文本选区,可能横跨多个元素。文本选区由用户拖拽鼠标经过文字而产生。如果要获取用于检查或修改的 Selection 对象,可以调用 window.getSelection() 方法.
这看起来就十分的官方和抽象,简单的来说 Selection 对象所对应的是用户所选择的 ranges (区域),俗称 拖蓝 。上图中的拖蓝就是selection对象中的一个区域.
通过getRangeAt方法可以获取到具体的选中区域 。
let selection = window.getSelection()
//
获取selection对象
let range = selection.getRangeAt(0)
//
获取第一个选中的区域
除了获取选区中的区域之外,我们还可以通过 document.createRange() 创建一个新的区域,然后将该区域添加到选区中 。
<
body
>
<
div
id
="hello"
>
你好
</
div
>
<
div
id
="yes"
>
是的
</
div
>
</
body
>
<
script
>
let selection
=
window.getSelection()
//
获取selection对象
const hello
=
document.querySelector(
'
#hello
'
)
if
(selection.rangeCount
>
0
){
//
如果有已经选中的区域,直接全部去除
selection.removeAllRanges() } let range
=
document.createRange()
//
创建range
range.selectNode(hello)
//
range选中hello
selection.addRange(range)
//
加入到选区中
</
script
>
。
效果如下,当代码执行后,你好这个元素被直接选中 。
加入区域的api包括range.selectNode和range.selectNodeContents。其中selectNode表示选中整个节点而selectNodeContents表示选中节点中的内容,针对文字的复制需要选中节点的内容,而图片的复制需要选中节点本身.
用法如下 。
<
body
>
<
div
id
="hello"
>
你好
</
div
>
<
div
id
="yes"
>
是的
</
div
>
<
button
class
="btn"
>
点击复制
</
button
>
</
body
>
<
script
>
const yes
=
document.querySelector(
'
#yes
'
) const selection
=
window.getSelection() const range
=
document.createRange() range.selectNode(yes) range.selectNode(yes)
</
script
>
。
。
通过以上的selection api可以完成 创建selection对象-->选中节点内容-->添加到区域-->执行一下copy指令就可以完成复制文字了 。
<
body
>
<
div
id
="hello"
>
你好
</
div
>
<
div
id
="yes"
>
是的
</
div
>
<
button
class
="btn"
>
点击复制
</
button
>
</
body
>
<
script
>
const btn
=
document.querySelector(
'
.btn
'
) const hello
=
document.querySelector(
'
#hello
'
) btn.addEventListener(
'
click
'
, ()
=>
{ let range
=
document.createRange()
//
创建range
range.selectNodeContents(hello)
//
range选中hello
let selection
=
window.getSelection()
//
获取selection对象
if
(selection.rangeCount
>
0
) {
//
如果有已经选中的区域,直接全部去除
selection.removeAllRanges() } selection.addRange(range)
//
加入到选区中
if
(document.queryCommandSupported
&&
document.queryCommandSupported(
'
copy
'
)) {
//
先检测是否支持document.queryCommandSupported和copy指令
//
如果都支持直接执行指令
document.execCommand(
'
copy
'
)
//
去除选中区域,取消拖蓝效果
selection.removeAllRanges() } })
</
script
>
。
复制图像的操作是和复制文字基本相同的,只是需要在加入区域时选中整个节点,也就是把selectNodeContents方法换成selectNode 。
<
body
>
<
div
id
="hello"
>
你好
</
div
>
<
div
id
="yes"
>
是的
</
div
>
<
img
src
="./test.png"
alt
=""
>
<
button
class
="btn"
>
点击复制
</
button
>
</
body
>
<
script
>
const btn
=
document.querySelector(
'
.btn
'
) const hello
=
document.querySelector(
'
#hello
'
) const img
=
document.querySelector(
'
img
'
) btn.addEventListener(
'
click
'
, ()
=>
{ let range
=
document.createRange()
//
创建range
range.selectNode(img)
//
range选中图像节点
let selection
=
window.getSelection()
//
获取selection对象
if
(selection.rangeCount
>
0
) {
//
如果有已经选中的区域,直接全部去除
selection.removeAllRanges() } selection.addRange(range)
//
加入到选区中
if
(document.queryCommandSupported
&&
document.queryCommandSupported(
'
copy
'
)) {
//
先检测是否支持document.queryCommandSupported和copy指令
//
如果都支持直接执行指令
document.execCommand(
'
copy
'
)
//
去除选中区域,取消拖蓝效果
selection.removeAllRanges() } })
</
script
>
。
clipboard.js是一个第三方库,也是使用了前文所讲到的document.execCommand('copy')来实现的点击复制,使用方便,但是只能用于文本的复制.
使用npm安装 。
npm install clipboard --save
安装后在html文件内引入 。
<
script
src
="dist/clipboard.min.js"
></
script
>
或者使用CDN引入(这里只写了一种CDN引入方式,可以选择多种不同CDN方,具体请看 https://github.com/zenorocha/clipboard.js/wiki/CDN-Providers ) 。
<
script
src
="https://cdn.jsdelivr.net/npm/clipboard@2.0.11/dist/clipboard.min.js"
></
script
>
使用import的方式引入 。
import Clipboard from "clipboard";
直接创建一个ClipboardJS对象,传的参数可以是选择器字符串或者是DOM元素或者是DOM元素列表 。
new
ClipboardJS('.btn')
//
import方式为 new Clipboard('.btn')
。
初始化完后,可以到要绑定的对应元素下添加data-clipboard-target属性,属性值是要复制的元素的选择器,这里要复制的元素是 ‘是的’ 那个div,所以属性值就写#yes。不进行其他配置时,我们点击按钮,触发点击事件后,就可以完成复制文字 ‘是的’ 了.
<
body
>
<
div
id
="hello"
>
你好
</
div
>
<
div
id
="yes"
>
是的
</
div
>
<
button
class
="btn"
data-clipboard-target
="#yes"
>
点击复制
</
button
>
</
body
>
<
script
src
="https://cdn.jsdelivr.net/npm/clipboard@2.0.11/dist/clipboard.min.js"
></
script
>
<
script
>
new
ClipboardJS(
'
.btn
'
)
//
import方式为 new Clipboard('.btn')
</
script
>
点击后,是的这个元素被选中(拖蓝),使用ctrl+v可以完成文字的复制,效果已经达到.
此时有2个问题需要优化 。
这时就要用到一个新的属性 data-clipboard-text ,属性值就是希望动态复制的内容。 对ClipboardJS绑定的元素设置这个属性就可以动态复制自己设定的内容,此时就不需要再设置data-clipboard-target属性了(如果同时写2个属性,data-clipboard-text优先)。以下代码是一个写死的简单展示,真实使用的时候属性值要用js设置成需要复制的值.
<
body
>
<
div
id
="hello"
>
你好
</
div
>
<
div
id
="yes"
>
是的
</
div
>
<
button
class
="btn"
data-clipboard-text
="动态设置的内容"
>
点击复制
</
button
>
</
body
>
<
script
src
="https://cdn.jsdelivr.net/npm/clipboard@2.0.11/dist/clipboard.min.js"
></
script
>
<
script
>
new
ClipboardJS(
'
.btn
'
)
//
import方式为 new Clipboard('.btn')
</
script
>
上图显示点击之后,复制内容成功,这样没有选中元素的效果,不会拖蓝,交互效果更好的同时又能动态设置内容 。
data-clipboard-action属性可以决定执行的操作,这个属性有2个可选值copy或者是cut,默认是copy也就是复制,前面的所有代码中都没有出现这个属性,是直接使用的默认值copy。cut剪切,只能在input和textarea标签中使用,显然之前的div标签是无法使用的。使用方法仍是对ClipboardJS绑定的元素设置这个属性.
<
button
class
="btn"
data-clipboard-text
="动态设置的内容"
data-clipboard-action
="copy"
>
点击复制
</
button
>
事件处理可以让用户设置复制或剪切成功或者失败的回调,事件名分别是success和error。可以通过on在 ClipboardJS实例对象身上绑定success和error事件处理的回调。以下示例写了最简单alert打印成功和失败 。
const clipboard =
new
ClipboardJS('.btn')
//
import方式为 new Clipboard('.btn')
clipboard.on('success',
function
(){ alert(
'复制成功'
) }) clipboard.on(
'error',
function
(){ alert(
'复制失败'
) })
如果不想改HTML,加入过多的属性,可以直接使用纯JS写法来初始化ClipboardJS对象构造函数中传入第二个参数,第二个参数为对象,如下的示例中仅用完成js就完成了动态设置复制内容。设置配置对象的text方法,返回值就是要复制的内容 。
new
ClipboardJS('.btn'
,{ text:
function
(){
return
'动态复制的内容'
} })
设置配置对象的target方法,返回值就是要复制的元素 。
new
ClipboardJS('.btn'
,{ target:
function
(){
return
document.querySelector('#hello'
) } })
经过测试,当html中设置属性的同时,又在构造函数里加入配置项,以js构造函数配置项为准(优先级高) 。
<
body
>
<
div
id
="hello"
>
你好
</
div
>
<
div
id
="yes"
>
是的
</
div
>
<
button
class
="btn"
data-clipboard-target
="#hello"
>
点击复制
</
button
>
</
body
>
<
script
src
="https://cdn.jsdelivr.net/npm/clipboard@2.0.11/dist/clipboard.min.js"
></
script
>
<
script
>
new
ClipboardJS(
'
.btn
'
,{ target(){
return
document.querySelector(
'
#yes
'
) } })
</
script
>
如果使用的是单页应用程序,可能希望更精确地管理DOM的生命周期。可以使用destroy方法销毁对象 。
var
clipboard =
new
ClipboardJS('.btn'
); clipboard.destroy();
看了之前的api,想了解一下这个所谓的简单的复制库是如何实现的,于是打开了源码开始分析一下 。
源码地址 https://github.com/zenorocha/clipboard.js 。
构造函数里面传2个参数,第一个trigger即触发点击的元素对象,第二个options配置项。从最简单的例子来看,只需要传一个trigger参数就可以实现功能,那就先不管options,直接看与trigger有关的listenClick方法.
listenClick方法调用了一个第三方库的listen方法绑定了click事件和对应的回调函数this.onClick,在onclick方法中,调用了ClipboardActionDefault方法,并且传了对应的几个配置项参数,action container,target,text,这些值都是this.xxx方法,这几个方法又是在哪定义的呢?
。
找了一下类内部,定义这些方法的地方是在前文构造函数里的 this.resolveOptions方法里 。
resolveOptions方法里的defaultAction,defaultText等等方法都是类似的,都是调用了一个getAttributeValue方法去获取html模板上的属性值 。
getAttributeValue方法如下,比较简单 。
上面跳了这么多方法虽然不难,但是也有点绕,主要还是在干一件事,那就是通过定义来准备好 ClipboardActionDefault这个方法的参数。这时候就要看一下ClipboardActionDefault这个方法在干什么.
简单来看,这个方法主要分4个if判断,前2个if就是一些条件的判断,判断action只能是复制或者剪切,还有就是判断要复制的目标节点的节点类型和readonly问题等等,此处不展开去研究,有兴趣者可以点击本部分开始处的源码链接下载.
后2个if判断中的内容如下,分别用于判断是否有text值和target值,这2个值也是通过本库的核心属性data-clipboard-text和data-clipboard-target在html中获取的(或者在js配置项里获取)。判断完后就调用了ClipboardActionCopy或者ClipboardActionCut方法去实现复制或者剪切功能.
这个方法就开始进行文本的复制了,首先判断要复制的目标是普通的字符串(通过data-clipboard-text设置)还是节点(通过data-clipboard-target设置),如果是文本或者不是普通的输入元素,直接调用 fakeCopyAction方法执行复制操作.
。
fakeCopyAction先创建了虚拟元素,然后把这个元素插入dom里,最后执行选中+复制操作 。
创建虚拟元素的方法也比较简单,先通过原生方法createElement创建了一个textarea元素,然后把它隐藏。创建这种输入类元素的好处就是可以直接去修改它的value,最后一步操作就是把文本text赋值给textarea 。
创建完虚拟元素就要处理选中问题了,这里调用了select方法,方法内部根据3种元素类型设置了不同的处理对策,select元素只要focus后赋值就好。输入元素可以调用原生的select方法来选中元素,而普通元素就需要使用之前讲到的selection api去获取range和添加range了 。
function
select(element) {
var
selectedText;
if
(element.nodeName === 'SELECT'
) {
//
针对select元素的处理
element.focus(); selectedText
=
element.value; }
else
if
(element.nodeName === 'INPUT' || element.nodeName === 'TEXTAREA'
) {
//
选中输入元素
var
isReadOnly = element.hasAttribute('readonly'
);
if
(!
isReadOnly) { element.setAttribute(
'readonly', ''
); } element.select(); element.setSelectionRange(
0
, element.value.length);
if
(!
isReadOnly) { element.removeAttribute(
'readonly'
); } selectedText
=
element.value; }
else
{
//
普通元素选中
if
(element.hasAttribute('contenteditable'
)) { element.focus(); }
var
selection =
window.getSelection();
var
range =
document.createRange(); range.selectNodeContents(element); selection.removeAllRanges(); selection.addRange(range); selectedText
=
selection.toString(); }
return
selectedText; }
最后的command('copy')也就是对执行复制指令这个方法的简单封装,做了一下兼容性的处理.
前面的document.execCommand和第三方库clipboard.js都非常的好用,但是他们可能面临被弃用的风险,那么该怎么解决复制粘贴这个问题呢? H5新推出的clipboard api是 处理复制粘贴相关的api,可以很好的解决这个问题。用promise的方式把数据写入剪贴板,避免了页面的卡顿.
使用Clipboard api时我们不需要手动创建Clipboard对象,而是通过navigator.clipboard来获取 。
打印出Clipboard对象后可以看出,这个对象有4个方法,分为两大类,write和read类。其中与复制相关的是write类表示把数据写入剪贴板,和粘贴相关的是read类表示从剪贴板里面读取数据 。
Clipboard对象中的writeText方法可以用于复制文字,也是非常简单易用的一个方法.
参数:传一个字符串参数,即要复制的内容 。
返回值: 一个promise对象,如果成功复制则是成功的promise,如果写入剪贴板失败(复制失败)则是失败的promise 。
示例如下:先创建了一个clipboard对象,然后直接调用writeText方法复制文字123 。
navigator.clipboard.writeText('123')
根据之前的html结构,使用Clipboard api完成文字的复制 。
默认情况下,会为当前的激活的页面自动授予剪贴板的写入权限。出于安全方面考虑,这里我们还是先主动向用户请求剪贴板的写入权限,如果被授权,就可以调用上面的方法直接完成复制了.
<
body
>
<
div
id
="hello"
>
你好
</
div
>
<
div
id
="yes"
>
是的
</
div
>
<
img
src
="./test.png"
alt
=""
>
<
button
class
="btn"
>
点击复制
</
button
>
</
body
>
<
script
>
const btn
=
document.querySelector(
'
.btn
'
) const hello
=
document.querySelector(
'
#hello
'
) const img
=
document.querySelector(
'
img
'
) btn.addEventListener(
'
click
'
, async ()
=>
{ const { state }
=
await navigator.permissions.query({
//
出于安全方面考虑,这里我们还是主动向用户请求剪贴板的写入权限
name:
"
clipboard-write
"
, });
if
(state
==
'
granted
'
) { navigator.clipboard.writeText(hello.innerHTML) } })
</
script
>
。
write方法除了支持文本数据之外,还支持将图像数据写入到剪贴板,调用该方法后会返回一个 Promise 对象.
以下是简单的使用案例,先通过 Blob API 创建 Blob 对象,然后使用该 Blob 对象来构造 ClipboardItem 对象,最后再通过 write 方法把数据写入到剪贴板,复制了文字(当前页面的地址) 。
<
button
onclick
="copyPageUrl()"
>
拷贝当前页面地址
</
button
>
<
script
>
async
function
copyPageUrl() { const text
=
new
Blob([location.href], {type:
'
text/plain
'
});
try
{ await navigator.clipboard.write(
new
ClipboardItem({
"
text/plain
"
: text, }), ); console.log(
"
页面地址已经被拷贝到剪贴板中
"
); }
catch
(err) { console.error(
"
页面地址拷贝失败:
"
, err); } }
</
script
>
了解了write的基本用法,那使用Clipboard对象复制图片也有办法了,只要先把图像变成Blob对象,然后构造 ClipboardItem 对象,最后再调用write方法就好.
可是,如何把一个img标签里的图片转换成Blob对象呢?
首先从Blob对象的构造函数开始, MDN文档 写了Blob构造函数所需要的参数 。
var aBlob = new Blob( array, options );
array 是一个由ArrayBuffer, ArrayBufferView, Blob, DOMString 等对象构成的 Array ,或者其他类似对象的混合体,它将会被放进 Blob。DOMStrings 会被编码为 UTF-8。 options 是一个可选的BlobPropertyBag字典,它可能会指定如下两个属性:
。
根据文档中显示,我们需要先准备一个对应的数组,然后才能构造Blob对象,也就是要把图片转成二进制数据.
分步骤实现把图片转换成Blob 。
。
下方代码完成了基本的功能实现:
。
微信输入框显示,可以完成复制 。
这个方法在浏览器兼容性上仍存在一些问题,比如火狐可能就不支持ClipboardItem对象,此时只能用前文写的document.execCommand方法了.
<
body
>
<
div
id
="hello"
>
你好
</
div
>
<
div
id
="yes"
>
是的
</
div
>
<
img
style
="width: 400px; height: 200px"
src
="./test.png"
alt
=""
>
<
button
class
="btn"
>
点击复制
</
button
>
</
body
>
<
script
>
const btn
=
document.querySelector(
'
.btn
'
) const hello
=
document.querySelector(
'
#hello
'
) const img
=
document.querySelector(
'
img
'
) btn.addEventListener(
'
click
'
, async ()
=>
{ const { state }
=
await navigator.permissions.query({
//
出于安全方面考虑,这里我们还是主动向用户请求剪贴板的写入权限
name:
"
clipboard-write
"
, });
if
(state
==
'
granted
'
) {
//
创建canvas对象
const canvas
=
document.createElement(
'
canvas
'
); const context
=
canvas.getContext(
'
2d
'
); const image
=
new
Image() image.src
=
img.src image.onload
=
async ()
=>
{ canvas.width
=
image.width; canvas.height
=
image.height; context.drawImage(image,
0
,
0
, image.width, image.height);
//
img图片转成canvas
const imageDataUrl
=
canvas.toDataURL()
//
通过canvas获取base64编码
const binary
=
atob(imageDataUrl.split(
'
,
'
)[
1
]);
//
base64编码转二进制数据
const array
=
[];
for
(let i
=
0
; i
<
binary.length; i
++
) { array.push(binary.charCodeAt(i)); }
//
二进制数据转Blob对象
const blob
=
new
Blob([
new
Uint8Array(array)], { type:
'
image/png
'
});
//
判断浏览器是否有ClipboardItem对象,有些浏览器不支持本方法
if
(
typeof
ClipboardItem
!==
'
undefined
'
) {
//
把blob数据写入剪贴板
await navigator.clipboard.write([
new
ClipboardItem({ [blob.type]: blob }) ]) } } } })
</
script
>
。
。
最后此篇关于前端实现复制文字和图片,原来这么简单!的文章就讲到这里了,如果你想了解更多关于前端实现复制文字和图片,原来这么简单!的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
1. HTML 结构 1.1 HTML 文件基本结构 第一个html程序 hello world! html 标签是整个 h
文件上传三种方案:1. form表单上传,2. iframe,3. FormData,base64上传文件,二进制流上传文件,二进制流下载文件。异步上传,大文件上传--切片:拆分上传请求断点续传显示上
1. HTML 结构 1.1 HTML 文件基本结构 第一个html程序 hello world! html 标签是整个 h
uniapp作为开发移动端的前端框架,目前国内是非常流行的,使用HbuilderX开发工具基于uniapp框架开发的系统可以方便的转换为小程序、APP等移动端程序,大大降低了移动开发的成本。网络
今天我们来复盘一下前端中css伪元素的知识以及如何用css伪元素来减轻javascript的压力,做出一些脑洞大开的图形。 预备知识 伪元素 伪元素是一个附加至选择器末的
今天给大家分享一些实用的JS代码片段,有需要的朋友欢迎收藏! 1、获取浏览器的版 functiongetBrowser(){ varUserAgent=navigator.us
1 . Wappalyzer 全球用户数:1,000,000+ Wappalyzer可以帮助我们了解目标网站的构建方式。工作当中存在大量此类情况,客户需要我们参照某些网站
在管理后台中我们会使用大量的表格表单组件, 导入导出各种报表, 有些场景还需要对报表数据进行可视化分析, 动态生成可视化图表, 笔者将基于以上场景, 总结一些实用的 Table 组件开发技巧,
3D动画效果现在越来越普及,已经被广泛的应用到了各个平台,比如阿里云,华为云,webpack官网等。它可以更接近于真实的展示我们的产品和介绍,带来极强的视觉冲击感。所以说,为了让自己更加优秀,c
QShop商城-快速开始-前端 工具准备 NodeJs 前端环境为NodeJs,下载地址:http://nodejs.cn/download/current/ 。 默认会用版
1. 初始JavaScript 1.1 什么是 JavaScript JavaScript (简称 JS) 是世界上最流行的编程语言之一 是一个脚本语言, 通过解释器运行 主要在客户端(浏览器)上运行
1. WebAPI 背景知识 1.1 什么是 WebAPI JS 分成三个大的部分: ECMAScript: 基础语法部分 DOM API: 操作页面结构 BOM API: 操作浏览器 WebAPI
1. WebAPI 背景知识 1.1 什么是 WebAPI JS 分成三个大的部分: ECMAScript: 基础语法部分 DOM API: 操作页面结构 BOM API: 操作浏览器 WebAPI
1. 初始JavaScript 1.1 什么是 JavaScript JavaScript (简称 JS) 是世界上最流行的编程语言之一 是一个脚本语言, 通过解释器运行 主要在客户端(浏览器)上运行
有没有办法从页面访问 tomcat 服务器日志?如果有一些方法或实现可以做到这一点...... 最佳答案 PSI Probe可以列出您的 Tomcat 日志文件并显示它们的内容。您可以采用相同的方法,
我想知道是否有一些很好的免费网站性能分析工具,特别是前端。这主要是关于Javascript的。 现有工具(例如 Google Pagespeed)的问题在于它不适用于我的应用程序。在进入我的应用程序之
我曾经遇到一个 MySQL 前端应用程序,它在父行中显示外部链接行,例如,如果 Client 表有一个指向 Suburb 表的外键: (来源:vb123.com) 您知道可以执行此操作的任何前端吗?
我正在建立一个带有管理区域的网上商店来管理产品。在管理区域中,所有产品都是可见的,但在网上商店中,只有数据库表中标记为 active = 1 的产品是可见的。 我正在使用 Silex 并将存储库注册为
有可能在 C# 中制作 GUI,但在 C 或 C++ 中制作实际程序。 比如说我想制作一个聊天应用程序。我希望界面在 C# 中。但我想用 C 编写所有实际代码。这可能吗? 我找到了 http://ww
对于我自己的教育,我很好奇编译器使用哪个 C++ 前端和后端。您能告诉我以下技术在哪里使用以及它们有哪些标志/优势(如果有的话)? Open64 - 它是后端、前端还是两者兼而有之?哪些编译器使用它?
我是一名优秀的程序员,十分优秀!