检测用户是否使用Google Chrome的自动填充选项填写表单

时间:2022-07-05 15:24:16

If anyone can guide me on how to detect if the user fills the form with the autofill option of google chrome.

如果有人可以指导我如何检测用户是否使用谷歌浏览器的自动填充选项填写表单。

I have a directive where each time the user fills in the field and change the blur sends an event to google analytics.

我有一个指令,每次用户填写该字段并更改模糊时,都会向Google Analytics发送一个事件。

But also I need to detect whether the user has filled the form with the autofill option of chrome and push the data for each of the fields to google analytics.

但我还需要检测用户是否已使用chrome的自动填充选项填充表单,并将每个字段的数据推送到Google Analytics。

Part of my directive:

我的指令的一部分:

element.bind('blur', function (e) {
  if ((e.target.value !== 0) && typeof value !== 'undefined')  {
    if (_.has(ga_data, 'sendEvent')) {
      analyticsService.sendEvent(ga_data.sendEvent);
    }

    if (_.has(ga_data, 'action') && ga_data.action === 'blur') {
      analyticsService.sendEvent(ga_data);
    }
  }
});

3 个解决方案

#1


1  

Based on input-directive src, angular sets up a listener for cases of change, input, paste etc.

基于input-directive src,angular为更改,输入,粘贴等情况设置了一个监听器。

And whenever the browser autofills the input element, this listener is called and viewValue is commited through array of $parsers as of here ngModel directive src.

每当浏览器自动填充输入元素时,就会调用此侦听器,并通过$解析器数组提交viewValue,此处为ngModel指令src。

So eventually you can avoid additional scope.$watch and just rely on $parsers to send ga track event just on linking phase of each input element with directive. And btw don't forget to destroy you parser func right after first usage (i.e. browser autofill), so it will not spam further on viewValue change.

所以最终你可以避免额外的范围。$ watch并且只需依靠$ parsers就可以在每个输入元素与指令的链接阶段发送ga track事件。并且顺便说一下,在第一次使用(即浏览器自动填充)后,不要忘记销毁解析器功能,因此它不会在viewValue更改时进一步发送垃圾邮件。

Here's an example:

这是一个例子:

angular
  .module('app', [])
  .directive('detectPrefill', function() {
    return {
      require: 'ngModel',
      link: { 
        pre: function(scope, element, attrs, ctrl) {
          function detectPrefill (viewValue) {
            //send GA data
            //...

            // just checking that detectPrefill func is destroyed after first usage                
            viewValue && console.log(viewValue);
            ctrl.$parsers.splice(
              ctrl.$parsers.indexOf(detectPrefill), 
              1
            );
            return viewValue;
          }

          ctrl.$parsers.push(detectPrefill);
        }
      }
    };
  });

Hope this helps.

希望这可以帮助。

#2


2  

You can use two way data binding here and watch the ng model on the form field for changes

您可以在此处使用双向数据绑定,并在表单字段上查看ng模型以进行更改

<form method="post">
  First name:<input type="text" name="fname" ng-model="user.fname"/><br />
  Last name: <input type="text" name="lname" ng-model="user.lname"/><br />
  E-mail: <input type="text" name="email" ng-model="user.email"/><br />
  Phone: <input type="text" name="phone" ng-model="user.phone"/><br />
  Address: <input type="text" name="address" ng-model="user.address"/><br />
</form>

Then inside your angular controller you can do something of this sort.

然后在角度控制器内部,您可以执行此类操作。

angular.module('app', []).controller('AppController', function($scope){
  $scope.user = { };
  $scope.$watch('user', function(nv, ov){
    console.log(nv);
  }, true);
});

There might be some cases that you need to handle though, to prevent sending multiple requests because $watch function will be triggered every time the value in the text field changes.

可能会有一些情况需要处理,以防止发送多个请求,因为每次文本字段中的值更改时都会触发$ watch函数。

Here is a fiddle which triggers $watch when any value in a form field changes, be it via autofill or manual entry by user.

这是一个小提琴,当表单字段中的任何值发生变化时触发$ watch,无论是通过自动填充还是用户手动输入。

#3


2  

In this case, the way to detect when Chrome auto-fills a form instead of the user doing it is by detecting the absence of an event having occurred, such as the keyup event. Consider the block of HTML and Javascript below. I have the text input field marked with a data attribute that is initially set to false. If the user fills out anything in the form by typing, then the attribute is set to true. The moment when you record whether or not the user filled out the form is on form submit. Then you can check the fields of the form and see if the user entered the input his or herself.

在这种情况下,检测Chrome何时自动填充表单而不是用户执行此操作的方法是检测是否发生了事件,例如keyup事件。考虑下面的HTML和Javascript块。我的文本输入字段标有最初设置为false的数据属性。如果用户通过键入填写表单中的任何内容,则该属性设置为true。记录用户填写表单是否在表单提交的那一刻。然后,您可以检查表单的字段,看看用户是否输入了他或她自己的输入。

<form onsubmit="dosomething()">
    <label for="somefield"></label>
    <input type="text" id="somefield" onkeyup="this.setAttribute('data-entered', (this.value != '').toString());" data-entered="false" />
    <input type="submit" value="submit"/>
</form>

The reason why you need to use a keyboard event and send the information when the form is submitted is because you can only tell if auto-fill took place when any of the fields have values even when the user typed nothing in. This part is less about code, and is more about what needs to be done so to take a proper measurement.

您需要使用键盘事件并在提交表单时发送信息的原因是因为您只能告诉自动填充是否在任何字段具有值时发生,即使用户未输入任何内容也是如此。此部分较少关于代码,更多的是关于需要做什么以便进行适当的测量。

#1


1  

Based on input-directive src, angular sets up a listener for cases of change, input, paste etc.

基于input-directive src,angular为更改,输入,粘贴等情况设置了一个监听器。

And whenever the browser autofills the input element, this listener is called and viewValue is commited through array of $parsers as of here ngModel directive src.

每当浏览器自动填充输入元素时,就会调用此侦听器,并通过$解析器数组提交viewValue,此处为ngModel指令src。

So eventually you can avoid additional scope.$watch and just rely on $parsers to send ga track event just on linking phase of each input element with directive. And btw don't forget to destroy you parser func right after first usage (i.e. browser autofill), so it will not spam further on viewValue change.

所以最终你可以避免额外的范围。$ watch并且只需依靠$ parsers就可以在每个输入元素与指令的链接阶段发送ga track事件。并且顺便说一下,在第一次使用(即浏览器自动填充)后,不要忘记销毁解析器功能,因此它不会在viewValue更改时进一步发送垃圾邮件。

Here's an example:

这是一个例子:

angular
  .module('app', [])
  .directive('detectPrefill', function() {
    return {
      require: 'ngModel',
      link: { 
        pre: function(scope, element, attrs, ctrl) {
          function detectPrefill (viewValue) {
            //send GA data
            //...

            // just checking that detectPrefill func is destroyed after first usage                
            viewValue && console.log(viewValue);
            ctrl.$parsers.splice(
              ctrl.$parsers.indexOf(detectPrefill), 
              1
            );
            return viewValue;
          }

          ctrl.$parsers.push(detectPrefill);
        }
      }
    };
  });

Hope this helps.

希望这可以帮助。

#2


2  

You can use two way data binding here and watch the ng model on the form field for changes

您可以在此处使用双向数据绑定,并在表单字段上查看ng模型以进行更改

<form method="post">
  First name:<input type="text" name="fname" ng-model="user.fname"/><br />
  Last name: <input type="text" name="lname" ng-model="user.lname"/><br />
  E-mail: <input type="text" name="email" ng-model="user.email"/><br />
  Phone: <input type="text" name="phone" ng-model="user.phone"/><br />
  Address: <input type="text" name="address" ng-model="user.address"/><br />
</form>

Then inside your angular controller you can do something of this sort.

然后在角度控制器内部,您可以执行此类操作。

angular.module('app', []).controller('AppController', function($scope){
  $scope.user = { };
  $scope.$watch('user', function(nv, ov){
    console.log(nv);
  }, true);
});

There might be some cases that you need to handle though, to prevent sending multiple requests because $watch function will be triggered every time the value in the text field changes.

可能会有一些情况需要处理,以防止发送多个请求,因为每次文本字段中的值更改时都会触发$ watch函数。

Here is a fiddle which triggers $watch when any value in a form field changes, be it via autofill or manual entry by user.

这是一个小提琴,当表单字段中的任何值发生变化时触发$ watch,无论是通过自动填充还是用户手动输入。

#3


2  

In this case, the way to detect when Chrome auto-fills a form instead of the user doing it is by detecting the absence of an event having occurred, such as the keyup event. Consider the block of HTML and Javascript below. I have the text input field marked with a data attribute that is initially set to false. If the user fills out anything in the form by typing, then the attribute is set to true. The moment when you record whether or not the user filled out the form is on form submit. Then you can check the fields of the form and see if the user entered the input his or herself.

在这种情况下,检测Chrome何时自动填充表单而不是用户执行此操作的方法是检测是否发生了事件,例如keyup事件。考虑下面的HTML和Javascript块。我的文本输入字段标有最初设置为false的数据属性。如果用户通过键入填写表单中的任何内容,则该属性设置为true。记录用户填写表单是否在表单提交的那一刻。然后,您可以检查表单的字段,看看用户是否输入了他或她自己的输入。

<form onsubmit="dosomething()">
    <label for="somefield"></label>
    <input type="text" id="somefield" onkeyup="this.setAttribute('data-entered', (this.value != '').toString());" data-entered="false" />
    <input type="submit" value="submit"/>
</form>

The reason why you need to use a keyboard event and send the information when the form is submitted is because you can only tell if auto-fill took place when any of the fields have values even when the user typed nothing in. This part is less about code, and is more about what needs to be done so to take a proper measurement.

您需要使用键盘事件并在提交表单时发送信息的原因是因为您只能告诉自动填充是否在任何字段具有值时发生,即使用户未输入任何内容也是如此。此部分较少关于代码,更多的是关于需要做什么以便进行适当的测量。