javascript - 'DOMException : Failed to execute 'querySelectorAll' on 'Element' when using an 'option:selected' selector

标签 javascript jquery css jquery-selectors

我正在运行一个页面,该页面在以下行抛出错误:

var label = $select.find('option:selected').html() || $select.find('option:first').html() || "";

为了完整起见,这里是完整的 jQuery 函数(country-select.js):

(function($) {
  $.fn.countrySelect = function (callback) {
    $(this).each(function(){
      var $select = $(this);

      var lastID = $select.data('select-id'); // Tear down structure if Select needs to be rebuilt

      if (lastID) {
        $select.parent().find('span.caret').remove();
        $select.parent().find('input').remove();

        $select.unwrap();
        $('ul#select-options-'+lastID).remove();
      }

      // If destroying the select, remove the selelct-id and reset it to it's uninitialized state.
      if(callback === 'destroy') {
        $select.data('select-id', null).removeClass('initialized');
        return;
      }

      var uniqueID = Materialize.guid();
      $select.data('select-id', uniqueID);
      var wrapper = $('<div class="select-wrapper"></div>');
      wrapper.addClass($select.attr('class'));
      var options = $('<ul id="select-options-' + uniqueID +'" class="dropdown-content select-dropdown country-select"></ul>'),
          selectChildren = $select.children('option, optgroup'),
          valuesSelected = [],
          optionsHover = false;

      var label = $select.find('option:selected').html() || $select.find('option:first').html() || "";

      // Function that renders and appends the option taking into
      // account type and possible image icon.
      var appendOptionWithIcon = function(select, option, type) {
        // Add disabled attr if disabled
        var disabledClass = (option.is(':disabled')) ? 'disabled ' : '';
        var optgroupClass = (type === 'optgroup-option') ? 'optgroup-option ' : '';

        var classes = option.attr('class');
        var data = option.data('phone-code');

        var opt = '<li class="' + disabledClass + optgroupClass + '"><span>';

        if (option.val() !== '') {
          opt += '<b class="flag flag-' + option.val().toLowerCase() + '"></b>';
        }
        opt += '<span class="option-label">' + option.html() + '</span>';
        if (data && data !== '') {
          opt += '<small>' + data + '</small>';
        }
        opt += '</span></li>';


        options.append($(opt));
      };

      /* Create dropdown structure. */
      if (selectChildren.length) {
        selectChildren.each(function() {
          if ($(this).is('option')) {
            appendOptionWithIcon($select, $(this));
          } else if ($(this).is('optgroup')) {
            // Optgroup.
            var selectOptions = $(this).children('option');
            options.append($('<li class="optgroup"><span>' + $(this).attr('label') + '</span></li>'));

            selectOptions.each(function() {
              appendOptionWithIcon($select, $(this), 'optgroup-option');
            });
          }
        });
      }

      options.find('li:not(.optgroup)').each(function (i) {
        $(this).click(function (e) {
          // Check if option element is disabled
          if (!$(this).hasClass('disabled') && !$(this).hasClass('optgroup')) {
            var selected = true;

            options.find('li').removeClass('active');
            $(this).toggleClass('active');
            $newSelect.val($(this).find('.option-label').text());

            activateOption(options, $(this));
            $select.find('option').eq(i).prop('selected', selected);
            // Trigger onchange() event
            $select.trigger('change');
            if (typeof callback !== 'undefined') callback();
          }

          e.stopPropagation();
        });
      });

      // Wrap Elements
      $select.wrap(wrapper);
      // Add Select Display Element
      var dropdownIcon = $('<span class="caret">&#9660;</span>');
      if ($select.is(':disabled'))
        dropdownIcon.addClass('disabled');

      // escape double quotes
      var sanitizedLabelHtml = label.replace(/"/g, '&quot;');

      var $newSelect = $('<input type="text" class="select-dropdown" readonly="true" ' + (($select.is(':disabled')) ? 'disabled' : '') + ' data-activates="select-options-' + uniqueID +'" value="'+ sanitizedLabelHtml +'"/>');
      $select.before($newSelect);
      $newSelect.before(dropdownIcon);

      $newSelect.after(options);
      // Check if section element is disabled
      if (!$select.is(':disabled')) {
        $newSelect.data('constrainwidth', false)
        $newSelect.dropdown({'hover': false, 'closeOnClick': false});
      }

      // Copy tabindex
      if ($select.attr('tabindex')) {
        $($newSelect[0]).attr('tabindex', $select.attr('tabindex'));
      }

      $select.addClass('initialized');

      $newSelect.on({
        'focus': function (){
          if ($('ul.select-dropdown').not(options[0]).is(':visible')) {
            $('input.select-dropdown').trigger('close');
          }
          if (!options.is(':visible')) {
            $(this).trigger('open', ['focus']);
            var label = $(this).val();
            var selectedOption = options.find('li').filter(function() {
              return $(this).find('.option-label').text().toLowerCase() === label.toLowerCase();
            })[0];
            activateOption(options, selectedOption);
          }
        },
        'click': function (e){
          e.stopPropagation();
        }
      });

      $newSelect.on('blur', function() {
        $(this).trigger('close');
        options.find('li.selected').removeClass('selected');
      });

      options.hover(function() {
        optionsHover = true;
      }, function () {
        optionsHover = false;
      });

      // Make option as selected and scroll to selected position
      var activateOption = function(collection, newOption) {
        if (newOption) {
          collection.find('li.selected').removeClass('selected');
          var option = $(newOption);
          option.addClass('selected');
          options.scrollTo(option);
        }
      };

      // Allow user to search by typing
      // this array is cleared after 1 second
      var filterQuery = [],
          onKeyDown = function(e){
            // TAB - switch to another input
            if(e.which == 9){
              $newSelect.trigger('close');
              return;
            }

            // ARROW DOWN WHEN SELECT IS CLOSED - open select options
            if(e.which == 40 && !options.is(':visible')){
              $newSelect.trigger('open');
              return;
            }

            // ENTER WHEN SELECT IS CLOSED - submit form
            if(e.which == 13 && !options.is(':visible')){
              return;
            }

            e.preventDefault();

            // CASE WHEN USER TYPE LETTERS
            var letter = String.fromCharCode(e.which).toLowerCase(),
                nonLetters = [9,13,27,38,40];
            if (letter && (nonLetters.indexOf(e.which) === -1)) {
              filterQuery.push(letter);

              var string = filterQuery.join(''),
                  newOption = options.find('li').filter(function() {
                    return $(this).text().toLowerCase().indexOf(string) === 0;
                  })[0];

              if (newOption) {
                activateOption(options, newOption);
              }
            }

            // ENTER - select option and close when select options are opened
            if (e.which == 13) {
              var activeOption = options.find('li.selected:not(.disabled)')[0];
              if(activeOption){
                $(activeOption).trigger('click');
                $newSelect.trigger('close');
              }
            }

            // ARROW DOWN - move to next not disabled option
            if (e.which == 40) {
              if (options.find('li.selected').length) {
                newOption = options.find('li.selected').next('li:not(.disabled)')[0];
              } else {
                newOption = options.find('li:not(.disabled)')[0];
              }
              activateOption(options, newOption);
            }

            // ESC - close options
            if (e.which == 27) {
              $newSelect.trigger('close');
            }

            // ARROW UP - move to previous not disabled option
            if (e.which == 38) {
              newOption = options.find('li.selected').prev('li:not(.disabled)')[0];
              if(newOption)
                activateOption(options, newOption);
            }

            // Automaticaly clean filter query so user can search again by starting letters
            setTimeout(function(){ filterQuery = []; }, 1000);
          };

      $newSelect.on('keydown', onKeyDown);
    });

    function toggleEntryFromArray(entriesArray, entryIndex, select) {
      var index = entriesArray.indexOf(entryIndex),
          notAdded = index === -1;

      if (notAdded) {
        entriesArray.push(entryIndex);
      } else {
        entriesArray.splice(index, 1);
      }

      select.siblings('ul.dropdown-content').find('li').eq(entryIndex).toggleClass('active');

      // use notAdded instead of true (to detect if the option is selected or not)
      select.find('option').eq(entryIndex).prop('selected', notAdded);
      setValueToInput(entriesArray, select);

      return notAdded;
    }

    function setValueToInput(entriesArray, select) {
      var value = '';

      for (var i = 0, count = entriesArray.length; i < count; i++) {
        var text = select.find('option').eq(entriesArray[i]).text();

        i === 0 ? value += text : value += ', ' + text;
      }

      if (value === '') {
        value = select.find('option:disabled').eq(0).text();
      }

      select.siblings('input.select-dropdown').val(value);
    }
  };

  $(function() {
    $('.js-country-select').countrySelect();
  });

  $(document).on('change', '[data-country-select]', function() {
    var target = 'select' + $(this).data('country-select');
    var val = $(this).val();
    var label = 'State';
    var options = [
      '<option value="" selected="" disabled="">Select State</option>'
    ];

    if (val !== '') {
      var country = window.__COUNTRIES[val];
      var subdivisions = country.subdivisions;
      var keys = Object.keys(subdivisions);

      label = country.subdivisionName;
      options = [
        '<option value="" selected="" disabled="">Select ' + label + '</option>'
      ];

      keys = keys.sort(function(a, b) {
        var valA = subdivisions[a].toLowerCase();
        var valB = subdivisions[b].toLowerCase();

        if (valA < valB) return -1;
        if (valA > valB) return 1;

        return 0;
      });

      keys.forEach(function(key) {
        options.push('<option value="' + key + '">' + subdivisions[key] + '</option>');
      });

      $(target).removeAttr('disabled');
    } else {
      $(target).attr('disabled', 'disabled');
    }

    $(target).parents('.input-field').find('label').html(label);
    $(target).val('').html(options);
    $(target).select2();
  });
})(jQuery);

这是我在 Debug模式下看到的异常:

enter image description here

据我了解 Failed to execute 'querySelectorAll' on 'Element' in ExtJS 5 , :selected不是 CSS 规范的一部分。

我应该如何解决这个问题?我应该使用:

var label = $select.find('option').filter(':selected').html() || $select.find('option').filter(':first').html() || "";

?

最佳答案

正在转换 Phil对答案的评论,我的调试器设置为暂停所有异常(包括捕获的异常)。我不得不取消激活下面显示的“停止标志”按钮,以使调试器再次正常工作。

enter image description here

关于javascript - 'DOMException : Failed to execute 'querySelectorAll' on 'Element' when using an 'option:selected' selector,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50519829/

相关文章:

javascript - Fancybox 尺寸错误

css - 给予行内 block div 边距

html - 如何创建标签可见的图像单选按钮

css - 使用 gtk_css_provider_load_from_data() 后如何将小部件的背景颜色重置为默认状态

javascript - 无法将文本颜色设置为较早的值

javascript - 如何使 3 列两列并排一个中间我的 div 把所有东西都放在左边

Javascript - 确定对 Element.children 功能的支持

javascript - jQuery .load() 没有触发图像(可能是缓存?)

javascript - 在 Jinja 中模板化 JavaScript 函数

php - 使用ajax从javascript/jquery调用php函数