【问题标题】:jQuery - replaceWith to update HTML does not make image or linkjQuery - replaceWith 更新 HTML 不会生成图像或链接
【发布时间】:2016-10-10 14:37:46
【问题描述】:

我正在用 JavaScript(使用 jQuery 和 Knockout)和 HTML 编写一个小代码,它接受用户输入(GitHub 用户名),检查输入是否对 GitHub api 有效,并显示用户的 GitHub 头像和用户名(链接到GitHub 上的匹配配置文件)。显示替换用户输入用户名的表单。

用户输入前的原始 HTML 为:

<div id="inputSection">
    <form>
        <p>
            GitHub Username:
                <input type="text" name="username" value="" placeholder="username" id="un"/>
                <button type="button" id="submitButton">Login</button>
        </p>
    </form>
</div>

替换它的代码是这样的:

$("#submitButton").click(function() {
    var username = document.getElementById('un').value;
    var inputForm = $(document.getElementById('inputSection'));

    $.ajax( {
        ...
        success: function () {
            alert("Welcome, " + username);
            var userURL = 'https://github.com/' + username;
            var inputContent = $('<a data-bind="attr: {href: userURL}"><img data-bind="attr: {src: avatar_url}" height=\"30\" width=\"30\"/>' + username + '</a>');
            $(inputForm.replaceWith(inputContent));
            }
    });
});

这似乎在大多数情况下都有效。警报通过用户名欢迎用户后,表单将从网页中消失。它被用户名取代,用户名的格式类似于链接。但是,它不能作为一个。单击它不会执行任何操作。另外,用户的头像虽然在网页上显示了一个设置大小的框,但并没有出现。

解决方案可能非常简单明了,但由于我这周才开始学习这些语言和库,我不确定出了什么问题。 Knockout 应该在调用 JavaScript 页面的 HTML 页面上运行,并且 ajax 正在处理其他函数,所以我认为这很好。值“avatar_url”是使用 ajax 在https://api.github.com/users 请求的 api 的一部分。

我尝试了各种不同的方法,但都没有效果。如果您想了解更多信息或有建议使这个问题变得更好,请发表评论。我是编码和 Stack Overflow 的新手,但我想让我的程序和我的问题尽可能好。感谢您的宝贵时间。

编辑: 1. 原来我没有给图片设置大小,导致图片为0x0。这已得到纠正,尽管图像本身仍然不显示。 2. 当我第一次输入我的代码时,我试图通过排除某些变量已为其他不相关部分重命名的位置并仅使所有名称在两个相关的 sn-ps 之间匹配来使其更易于阅读。我没有全部抓到。他们现在应该都匹配了。

【问题讨论】:

    标签: javascript jquery html ajax knockout.js


    【解决方案1】:

    简答:

    您正在插入一个带有 data-binds 的 html 元素,而没有显式地初始化它的绑定。在新注入的 DOM 部分使用ko.applyBindings(vm, node)

    长答案:

    如果您不熟悉编码以及 jQuery 和淘汰赛,我建议不要同时使用这两个库。原因如下:

    如果你想使用淘汰赛,你必须坚持某种软件架构:

    使用模型-视图-视图模型 (MVVM) (http://knockoutjs.com/) 简化动态 JavaScript UI

    另一方面,jQuery 更像是一个工具箱。它并不规定架构模式。

    它使 HTML 文档遍历和操作、事件处理、动画和 Ajax 等事情变得更加简单,它具有易于使用的 API,可在多种浏览器中运行。 (https://jquery.com/)

    这可能听起来有点蹩脚,并不是真正的答案,但我将向您展示解决问题的“敲除方式”和“jQuery 方式”之间的区别。我将从后者开始,因为它最接近您当前的方法:

    jQuery 方法(注意我跳过了 Ajax 部分)

    找到使 UI 具有交互性所需的元素。将事件监听器附加到按钮,当有新数据可用时修改 DOM。

    $(document).ready(function() {
      // Notice that you don't need document.getElementById
      var submitButton = $("#loginButton");
      var userNameInput = $("#un");
      var inputSection = $("#inputSection");
    
      var getContentString = function(userName) {
        var userUrl = "https://github.com/" + userName;
        var avatarUrl = "...";
    
        // Inject the user specific attributes
        return "<a href=`" + userUrl + "`><img src=`" + avatarUrl + "` height='30' width='30'/>" + userName + "</a>";
      };
    
    
      var onSubmitClick = function(event) {
        var userName = userNameInput.val();
        var onSuccess = function() {
          // Create new <a> element and replace the form with the new HTML
          var inputContent = $(getContentString(userName));
          inputSection.replaceWith(inputContent);
        };
    
        /* 
        $.ajax({
          
          success: onSuccess
        });
        */
    
        //Just call onSuccess to circumvent unimplemented ajax:
        onSuccess();
      };
    
      submitButton.click(onSubmitClick);
    
    });
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <form id="inputSection">
      <p>
        GitHub Username:
        <input type="text" name="username" value="" placeholder="username" id="un" />
        <button type="button" id="loginButton">Login</button>
      </p>
    </form>

    淘汰赛法

    为您的用户创建一个视图模型。绑定输入并自动计算其他属性。通过数据绑定附加事件侦听器。使用 ifvisibletemplate 绑定来交换部分 UI。

    var UserViewModel = function() {
    
      this.userName = ko.observable("");
      this.confirmed = ko.observable(false);
    
      this.userUrl = ko.computed(function() {
        return "https://github.com/" + this.userName();
      }, this);
    
      this.avatarUrl = ko.computed(function() {
        return "???" + this.userName();
      }, this);
    };
    
    UserViewModel.prototype.confirm = function() {
      /* ajax (disabled for example)
      $.ajax({
        success: this.confirmed.bind(null, true)
      });
      */
    
      this.confirmed(true);
    };
    
    var viewModel = {
      user: new UserViewModel()
    };
    
    ko.applyBindings(viewModel);
    <script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
    
    <div data-bind="with: user">
      <!-- ko ifnot: confirmed -->
      <form>
        <p>
          GitHub Username:
          <input data-bind="value: userName" type="text" placeholder="username" />
          <button data-bind="click: confirm">Login</button>
        </p>
      </form>
      <!-- /ko -->
    
      <!-- ko if: confirmed -->
      <a data-bind="attr: { href: userUrl }">
        <img data-bind="attr: {src: avatarUrl }" />
        <span data-bind="text: userName"></span>
    
      </a>
      <!-- /ko -->
    
    </div>

    【讨论】:

    • 长答案 jQuery 方法中 getContentString 中的反引号似乎是不必要的并且会导致问题。我可能在尝试它们时做错了什么。你能解释一下它们的作用吗?
    • 反引号应该是单引号(以规避必须转义它们)。抱歉……
    【解决方案2】:

    在上面 user3297291 的 jQuery 答案的帮助下,我最终得出了这个结论。答案是好的,对于这个进展是必要的;某些部分在这种情况下不起作用(主要是与此示例中未包含的其他代码的简单兼容性问题)。虽然这是一个非常具体的问题,但我认为应该包括解决方案。请注意,我决定暂时远离 Knockout。

    将 id 附加到表单而不是 div 的 HTML 建议是一个不错的举措。

    $("#submitButton").click(function inputForm() {
        var username = $("#un").val();
    
        function makeUserContent(user, profile, avatar) { //arguments are data from ajax
            //writes a string without the messy quotes within quotes within quotes problem
            //much clearer than trying to handle the jQuery and string all at once
            return "<a href=" + profile + "><img src=" + avatar + " height='30' width='30' />" + user + "</a>";
        }
    
        function submitUsername() {
            $.ajax({
                ...
                success: function correntInformation(data) {
                    //data is what the ajax gets, which is passed for use
                    alert("Welcome, " + username + ".");
                    //calls to make the string with the data gotten by ajax
                    var inputContent = $(makeUserContent(data.login, data.html_url, data.avatar_url));
                    $("#inputSection").replaceWith(inputContent);
                }
            })
        }
        submitUsername();
    })
    

    我从这个问题中得到的最大收获是:简化字符串、保存和使用数据、一次使用一个库(直到对两者都有经验)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-10-08
      • 1970-01-01
      • 1970-01-01
      • 2017-02-24
      • 2021-03-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多