阅读 206

React Vue 解决火狐下禁用输入框无法复制

1.起因

根据不同条件禁用input框,是开发中常见的问题。但是在火狐浏览器的表现上,火狐禁用了input框所有的交互事件。无法触发用户勾选字段进行复制操作。

1.React+Antd

在配合Antd开发React中,我们一般讲Antd的Input组件多封装一层我们自己的组件,可以统一修改组件的样式和逻辑,在处理火狐禁用复制功能时也是在封装的这一层组件做事情。

render() {
  const { disabled } = this.props;
  const that = this;
  return (
    <Input
      className={disabled ? `ant-input-disabled ${className || ''}` : `${className || ''}`}
      {...disabled ? {
        readOnly: true
      } : {}}
      {...readonly || readOnly ? {
        onChange: (e) => e.preventDefault()
      } : {}}
      {
        ...function () {
          const {
              disabled,
              className,
              ...newData
          } = that.props;
          if (that.props.readOnly || that.props.readonly) {
              delete newData.onChange;
              return newData;
          } else {
              return newData;
          }
        }()
      }
  />);
}复制代码

具体思路就是捕获到disabled属性,删除该属性,设置readonly=true。然后再附上禁用的class类,造成假禁用的效果。

2.Vue+Element-ui

vue的解决思路也是一样,封装一层自己的组件。删除disabled属性,设置为readonly。

<template>
  <el-input
    v-bind="$attrs"
    v-on="$listeners"
    ref="input"
  >
  <span v-if="$slots.prefix" slot="prefix">
    <slot name="prefix"></slot>
  </span>
    <span v-if="$slots.suffix" slot="suffix">
    <slot name="suffix"></slot>
  </span>
    <span v-if="$slots.prepend" slot="prepend">
    <slot name="prepend"></slot>
  </span>
    <span v-if="$slots.append" slot="append">
    <slot name="append"></slot>
  </span>
  </el-input>
</template>
<script>
export default {
  name: 'crInputDemo',
  data() {
    return {
    };
  },
  mounted() {
  },
  computed: {
    attrs() {
      const newAttrs = JSON.parse(JSON.stringify(this.$attrs));
      if (newAttrs.disabled || newAttrs.disabled === '') {
        delete newAttrs.disabled;
        newAttrs.readonly = true;
      } else {
        newAttrs.readonly = false;
      }
      return newAttrs;
    },
  },
  watch: {

  },
};
</script>复制代码

当我们以为这个问题就此解决的时候,发现Element-ui的Form组件如果设置了disabled属性,在Form表单的每一个表单组件内部都拿不到disabled属性了,但是表单组件却依旧被禁用。

这个时候,明显修改disabled属性已经不能解决问题了,在使用vue-tools观察el-input组件内部变量中,发现在设置Form的disabled后,虽然el-input等各种组件拿不到传入的disabled attrs,但是在computed中可以通过inputDisabled属性拿到该组件是否禁用的标识。

所以我们修改了组件的逻辑,如果捕获到this.$refs.input.inputDisabled为true时,给组件增加readonly属性,在多次测试后,我们无法修改el-input内部的inputDisabled属性,增加的readonly属性并没有起作用。

最后我们只能通过暴力的获取input dom删除disabled标签属性,增加readonly标签属性来解决问题。

mounted() {
    this.$nextTick(() => {  
        const el = this.$refs.input.$el.children[0];  
        if (el.hasAttribute('disabled')) {    
            el.removeAttribute('disabled');    
            el.setAttribute('readonly', true)  
        }
    });
}复制代码

然后经过一番的折腾,结果这个需求被砍了,因为火狐上readonly框会有红色的边框围住,并且无法禁止focus,blur事件。



关注下面的标签,发现更多相似文章
评论