Js-那些琐碎的事(学习中)

1、监视用户粘贴文本/读取剪贴板的值

// 创建一个输入框
let textInput = document.createElement('div');
textInput.innerHTML = '<label for="text"></label>\n' +
    '<textarea id="text" cols="40" rows="10"></textarea>';
document.body.appendChild(textInput);

// 给文本输入框绑定粘贴事件,通过用户的行为获取事件
textInput.onpaste = function (ev) {
    // 防止默认事件, 这里的默认事件是用户触发粘贴成功,并将值写入的过程
    ev.preventDefault();
    // 停止事件冒泡
    ev.stopPropagation();
    // 获取剪贴版的内容
    // 'text/html' 获得的是剪贴板的html文档
    // 'text/plain' 获得的是剪贴板的当前黏贴贴的纯文本文档
    let context = ev.clipboardData.getData("text/plain");
    console.log(context);
}

// 自动获取剪贴板的值
// 但是这个会弹出一个提示框,需要征得用户同意才可以获得
navigator.clipboard.readText().then(value => {
        console.log(value);
    }, reason => {
        console.log(reason);
    }
)

2、深拷贝(地址拷贝)和浅拷贝(拷贝指针)

let target = {name: 'alex', friends: ['tom', 'jhon']}
// 拷贝
let coped = Object.assign({}, target);

console.log(coped);
// 首先拷贝了一个对象
// {name: 'alex', friends: Array(2)}

// 第一层元素是深拷贝,拷贝了原来地址中的元素,然后在堆区新开辟的一个地址来储存这个元素
// 因此修改了第一层的元素相当于是在自己的地址上修改的,和被拷贝的元素的地址是不同的
// 所以修改了拷贝的元素的第一层属性的值,被拷贝元素的值是不变的
coped.name = 'jack';
console.log(coped);
// {name: 'jack', friends: Array(2)}
console.log(target);
// {name: 'alex', friends: Array(2)}

// 由于第二层拷贝的只是一个指针,但是指针指向的是相同的地址
// 所以通过这个指针修改元素,那么无论有多少个指针,只要指向的地址是相同的
// 那么访问的元素就是相同的,
// 只要是只是拷贝了指针的拷贝,就叫做浅拷贝
coped.friends[0] = 'modified';
console.log(coped);
console.log(target);
// friends: (2) ['modified', 'jhon']

// 只有一个等号的拷贝是浅拷贝,只是复制了指向地址的指针而已
let target_ = target;
target_.name = 'new-name'
console.log(target);
// {name: 'new-name', friends: Array(2)}

// 深拷贝,通过一下的方式实现
// JSON.stringify();将对象转化为字符串
// JSON.parse();将字符串转化为对象
let obj1 = JSON.stringify(target);
let obj2 = JSON.parse(obj1);
// 此时 obj1 与 obj2 在堆中指向的地址是不同的,所以是深拷贝

// 递归函数实现深拷贝
let check_type = data => {
    // 判断数据类型,经常通过toString方法来看数据类型
    return Object.prototype.toString.call(data).slice(8, -1)
}
let deepCopy = my_target => {
    let type = check_type(my_target);
    let result;
    if (type === 'Object') {
        result = {}
    } else if (type === 'Array') {
        result = []
    } else {
        // 基本数据类型不做处理,这里只考虑{} 和 []
        return my_target
    }
    for (let i in my_target) {
        let value = my_target[+i];
        let inner_type = check_type(value);
        if (inner_type === 'Object' || inner_type === 'Array') {
            result[+i] = deepCopy(value);
        } else {
            result[+i] = value;
        }
    }
    return result;
}

let arr1 = [1, 2, [1, 2, 3]];
let arr2 = deepCopy(arr1);
arr2[arr2.length - 1][0] = 'changed';
console.log(arr1);  // [1, 2, [1, 2, 3]]
console.log(arr2);  // [1, 2, ['changed', 2, 3]]

3、监视用户复制文本事件

let my_div = document.createElement('div');
my_div.innerHTML = 'this is a text';
document.body.appendChild(my_div);

my_div.oncopy = function (ev) {
    // 阻止事件默认的行为
    ev.preventDefault();
    // 阻止事件的冒泡
    ev.stopPropagation();

    // 获取选中的内容的内容对象
    const selection = document.getSelection();
    // 从内容对象中获取文字选中的部分
    const selected_data = selection.toString();

    // 将文字选中部分的值转移到剪贴版上
    ev.clipboardData.setData('text/plain', selected_data);
}

4、监听用户剪切文本事件

let my_div = document.createElement('div');
my_div.innerHTML = 'for cut event';
document.body.appendChild(my_div);

my_div.oncut = function (ev) {
    // 阻止默认事件
    ev.preventDefault();
    // 阻止事件冒泡
    ev.stopPropagation();
    // 获取用户选中对象
    const selection = document.getSelection();
    // 从用户选中对象中获取用户选中文本
    const text = selection.toString();
    // 将文本复制到用户剪贴板
    ev.clipboardData.setData('text/plain', text);
    // 删除用户在文本中所选中的文本,更新文本
    my_div.innerHTML = my_div.innerHTML.replace(text, '');
}

上一篇:python 穷举银行密码方法


下一篇:Linux编译系统之主Makefile(二)