在AJAX驱动的站点上选择并激活正确的控件 [英] Choosing and activating the right controls on an AJAX-driven site

查看:122
本文介绍了在AJAX驱动的站点上选择并激活正确的控件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

因此,我每次访问任何nike.com运动鞋页面(没有HTML链接)时都会尝试将其设置在哪里,它会自动选择我的鞋子尺寸,将其添加到购物车中,然后检查我。



我目前正在尝试使用此脚本(如下所示),但每次进入运动鞋页面时,都没有正确添加我想要的鞋码,只是在我的购物车中没有任何东西直接结帐。



我被告知我需要将代码与实际页面HTML匹配,但我不知道该怎么做。请帮忙。

  // == UserScript == 
// @name _Nike auto-buy(!!! )脚本
// @include http:// * / *
// @require http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js
// @require https://gist.github.com/raw/2625891/waitForKeyElements.js
// @grant GM_addStyle
// == / UserScript ==
/ * - 需要@grant指令来解决GM 1.0中引入的设计更改
。它恢复了沙箱。
* /

var okayToClickAddtoCart = false;

// - 假设该尺寸是标准<选项>标签或类似...
waitForKeyElements(。selectBox-label [value ='10'],selectShoeSize);

函数selectShoeSize(jNode){
jNode.prop('selected',true);

okayToClickAddtoCart = true;
}


waitForKeyElements(。addd-to-cart.nike-button,clickAddToCart);

函数clickAddToCart(jNode){
if(!okayToClickAddtoCart){
return true; // - 不要点击了。
}

var clickEvent = document.createEvent('MouseEvents');
clickEvent.initEvent('click',true,true);
jNode [0] .dispatchEvent(clickEvent);
}


waitForKeyElements(。checkck-button,clickCheckoutButton);

函数clickCheckoutButton(jNode){
var clickEvent = document.createEvent('MouseEvents');
clickEvent.initEvent('click',true,true);
jNode [0] .dispatchEvent(clickEvent);
}









  • 使用Firebug(或类似工具),我们获得关键节点的HTML结构。例如, SIZE 下拉列表包含如下HTML:

     < div class =size-量> 
    < span class =sizeDropdown selectBox-open>
    ...
    < label class =dropdown-label selectBox-label-showing> SIZE< / label>
    ...
    < a class =selectBox size-dropdown mediumSelect footwear selectBox-dropdown...>
    ...
    < / a>
    < / span>
    < / div>

    链接实际触发 mousedown 事件,而不是点击。



    Firebug给我们一个CSS路径:

      html.js body div#body div#body-wrapper.fullheight div#body-liner.clear div#content div#pdp.footwear div#product-container.clear div.pdp-buying-tools-container div。 pdp-box div.buying-tools-container div#PDPBuyingTools.buying-tools-gadget form.add-to-cart-form div.product-selections div.size-quantity span.sizeDropdown a.selectBox 

    我们可以减价:

      div.footwear form.add-to-cart-form span.sizeDropdown a.size-dropdown 

    对于一个合理的选择器,它可能会在琐碎的页面更改中存活,并且不太可能触发不需要的页面/产品。



    ~~~~~~~~~~~ ~~

    请注意,Firebug还可以帮助我们查看哪些事件附加到哪些事件,这在确定我们需要什么时至关重要igger。例如,对于该节点,我看到:





    该链接没有 href ,也没有收听单击事件。在这种情况下,我们必须触发 mousedown (或 keydown )。



    ~~~~~~~~~~~~~

    对其他4个关键节点使用类似的过程,我们获得了CSS / jQuery选择器:

     节点1:div.footwear form.add-to-cart-form span.sizeDropdown a.size-dropdown 

    节点2:ul.selectBox-dropdown-menu li a:contains('10')
    (但这需要额外检查)

    节点3:div .footwear form.add-to-cart-form span.sizeDropdown a.selectBox span.selectBox-label:contains('(10)')

    节点4:div.footwear form.add-to -cart-form div.product-selections div.add-to-cart

    节点5:div.mini-cart div.cart-item-data a.checkout-button:visible



  • 最后,我们使用 waitForKeyElements 将所需事件发送到关键节点并按照正确的操作顺序排序ons。


  • 生成的完整的工作脚本是:

      // == UserScript == 
    // @name _Nike auto-buy shoes(!!!)script
    / / @include http://store.nike.com/*
    // @include https://store.nike.com/*
    // @require http://ajax.googleapis.com /ajax/libs/jquery/1.7.2/jquery.min.js
    // @require https://gist.github.com/raw/2625891/waitForKeyElements.js
    // @grant GM_addStyle
    // == / UserScript ==
    / * - 需要@grant指令来解决GM 1.0中引入的设计更改
    。它恢复了沙箱。
    * /

    var targetShoeSize =10;

    // - 步骤1:激活尺寸下拉菜单。
    waitForKeyElements(
    div.footwear form.add-to-cart-form span.sizeDropdown a.size-dropdown,
    activateSizeDropdown
    );
    function activateSizeDropdown(jNode){
    triggerMouseEvent(jNode [0],mousedown);

    // - 设置步骤2.
    waitForKeyElements(
    ul.selectBox-dropdown-menu li a:contains('+ targetShoeSize +'):visible ,
    selectDesiredShoeSize
    );
    }

    // - 第2步:选择所需的鞋码。
    函数selectDesiredShoeSize(jNode){
    / * - 因为此节点的选择器易受误报,
    我们需要在此处进行额外检查。
    * /
    if($ .trim(jNode.text())=== targetShoeSize){
    // - 此节点需要triplex事件
    triggerMouseEvent(jNode [ 0],mouseover);
    triggerMouseEvent(jNode [0],mousedown);
    triggerMouseEvent(jNode [0],mouseup);

    // - 设置步骤3和4.
    waitForKeyElements(
    div.footwear form.add-to-cart-form span.sizeDropdown a.selectBox
    +span.selectBox-label:contains('(+ targetShoeSize +)'),
    waitForShoeSizeDisplayAndAddToCart
    );
    }
    }

    // - 步骤3和4:等待鞋码显示并添加到购物车。
    函数waitForShoeSizeDisplayAndAddToCart(jNode){
    var addToCartButton = $(
    div.footwear form.add-to-cart-form div.product-selections div.add-to-cart
    );
    triggerMouseEvent(addToCartButton [0],click);

    // - 设置步骤5.
    waitForKeyElements(
    div.mini-cart div.cart-item-data a.checkout-button:visible,
    clickTheCheckoutButton
    );
    }

    // - 步骤5:点击结帐按钮。
    函数clickTheCheckoutButton(jNode){
    triggerMouseEvent(jNode [0],click);

    // - 全部完成。结帐页面应该加载。
    }

    函数triggerMouseEvent(node,eventType){
    var clickEvent = document.createEvent('MouseEvents');
    clickEvent.initEvent(eventType,true,true);
    node.dispatchEvent(clickEvent);
    }


    So, I am trying to make it where every time I visit any nike.com sneaker page (without the HTML link), it automatically picks my shoe size, adds it to the cart, and checks out for me.

    I am currently trying to use this script (below), but every time I go to the sneaker page, it does not properly add the shoe size I want, but just goes straight to checkout with nothing in my cart.

    I'm told that I need to match the code to the actual page HTML, but I don't know how to do that. Please help.

    // ==UserScript==
    // @name     _Nike auto-buy(!!!) script
    // @include  http://*/*
    // @require  http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js
    // @require  https://gist.github.com/raw/2625891/waitForKeyElements.js
    // @grant    GM_addStyle
    // ==/UserScript==
    /*- The @grant directive is needed to work around a design change
        introduced in GM 1.0.   It restores the sandbox.
    */
    
    var okayToClickAddtoCart = false;
    
    //-- Assumes that size is a standard <option> tag or similar...
    waitForKeyElements (".selectBox-label[value='10']", selectShoeSize);
    
    function selectShoeSize (jNode) {
        jNode.prop ('selected', true);
    
        okayToClickAddtoCart = true;
    }
    
    
    waitForKeyElements (".add-to-cart.nike-button", clickAddToCart);
    
    function clickAddToCart (jNode) {
        if ( ! okayToClickAddtoCart) {
            return true;    //-- Don't click yet.
        }
    
        var clickEvent  = document.createEvent ('MouseEvents');
        clickEvent.initEvent ('click', true, true);
        jNode[0].dispatchEvent (clickEvent);
    }
    
    
    waitForKeyElements (".checkout-button", clickCheckoutButton);
    
    function clickCheckoutButton (jNode) {
        var clickEvent  = document.createEvent ('MouseEvents');
        clickEvent.initEvent ('click', true, true);
        jNode[0].dispatchEvent (clickEvent);
    }
    


    Link to the "target page"
    Snapshot of the target HTML (in case the target page is removed or changed by Nike)

    解决方案

    Rather than just alter the script from the question, I hope to make a quick outline of how to script these kinds of pages and actions with Greasemonkey/Tampermonkey.

    The steps are:

    1. Take careful note of what you do manually. Take special note of elements added/altered by the page's javascript, and the needed sequence of steps, if any.

    2. Using Firebug, and/or Firefox's inspector, and/or Chrome's Developer tools, determine CSS/jQuery selector's for all of the elements you will read or manipulate. This is especially easy to do using Firebug.

    3. Use jQuery to manipulate static HTML. Use waitForKeyElements to handle nodes added or changed by javascript (AJAX). Use the Greasemonkey API -- which is also supported by Tampermonkey and partially supported by Chrome userscripts -- to do any cross-domain page calls, or to store any values between page loads for cross-domain sets of pages.



    Specific example:

    1. For the OP's target pages, the OP wants to: (a) automatically select the shoe size, (b) add the shoes to the shopping cart, and (c) click the checkout button.

      This requires waiting for, and/or clicking on, five (5) page elements like so:


    2. Using Firebug (or similar tool) we obtain the HTML structure for the key nodes. For example, the SIZE dropdown has HTML like this:

      <div class="size-quantity">
          <span class="sizeDropdown selectBox-open">
              ...
              <label class="dropdown-label selectBox-label-showing">SIZE</label>
              ...
              <a class="selectBox size-dropdown mediumSelect footwear selectBox-dropdown" ...>
                  ...
              </a>
          </span>
      </div>
      

      Where the link actually fires off a mousedown event, not a click.

      Firebug gives us a CSS path of:

      html.js body div#body div#body-wrapper.fullheight div#body-liner.clear div#content div#pdp.footwear div#product-container.clear div.pdp-buying-tools-container div.pdp-box div.buying-tools-container div#PDPBuyingTools.buying-tools-gadget form.add-to-cart-form div.product-selections div.size-quantity span.sizeDropdown a.selectBox
      

      Which we can pare down to:

      div.footwear form.add-to-cart-form span.sizeDropdown a.size-dropdown
      

      for a reasonable selector that's likely to survive trivial page changes and unlikely to trigger on unwanted pages/products.

      ~~~~~~~~~~~~~
      Note that Firebug also helps us see what events are attached to what, which is crucial when determining what we need to trigger. For example, for that node, I see:

      That link has no href, nor does it listen for click events. In this case, we must trigger a mousedown (or keydown).

      ~~~~~~~~~~~~~
      Using a similar process for the other 4 key nodes, we obtain CSS/jQuery selectors of:

      Node 1:     div.footwear form.add-to-cart-form span.sizeDropdown a.size-dropdown
      
      Node 2:     ul.selectBox-dropdown-menu li a:contains('10')
                  (But this will need an additional check)
      
      Node 3:     div.footwear form.add-to-cart-form span.sizeDropdown a.selectBox span.selectBox-label:contains('(10)')
      
      Node 4:     div.footwear form.add-to-cart-form div.product-selections div.add-to-cart
      
      Node 5:     div.mini-cart div.cart-item-data a.checkout-button:visible
      


    3. Finally, we use waitForKeyElements to send the required events to the key nodes and to sequence through the proper order of operations.

    The resulting, complete, working script is:

    // ==UserScript==
    // @name     _Nike auto-buy shoes(!!!) script
    // @include  http://store.nike.com/*
    // @include  https://store.nike.com/*
    // @require  http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js
    // @require  https://gist.github.com/raw/2625891/waitForKeyElements.js
    // @grant    GM_addStyle
    // ==/UserScript==
    /*- The @grant directive is needed to work around a design change
        introduced in GM 1.0.   It restores the sandbox.
    */
    
    var targetShoeSize  = "10";
    
    //-- STEP 1:    Activate size drop-down.
    waitForKeyElements (
        "div.footwear form.add-to-cart-form span.sizeDropdown a.size-dropdown",
        activateSizeDropdown
    );
    function activateSizeDropdown (jNode) {
        triggerMouseEvent (jNode[0], "mousedown");
    
        //-- Setup step 2.
        waitForKeyElements (
            "ul.selectBox-dropdown-menu li a:contains('" + targetShoeSize + "'):visible",
            selectDesiredShoeSize
        );
    }
    
    //-- STEP 2:    Select desired shoe size.
    function selectDesiredShoeSize (jNode) {
        /*-- Because the selector for this node is vulnerable to false positives,
            we need an additional check here.
        */
        if ($.trim (jNode.text () ) === targetShoeSize) {
            //-- This node needs a triplex event
            triggerMouseEvent (jNode[0], "mouseover");
            triggerMouseEvent (jNode[0], "mousedown");
            triggerMouseEvent (jNode[0], "mouseup");
    
            //-- Setup steps 3 and 4.
            waitForKeyElements (
                "div.footwear form.add-to-cart-form span.sizeDropdown a.selectBox "
                + "span.selectBox-label:contains('(" + targetShoeSize + ")')",
                waitForShoeSizeDisplayAndAddToCart
            );
        }
    }
    
    //-- STEPS 3 and 4: Wait for shoe size display and add to cart.
    function waitForShoeSizeDisplayAndAddToCart (jNode) {
        var addToCartButton = $(
            "div.footwear form.add-to-cart-form div.product-selections div.add-to-cart"
        );
        triggerMouseEvent (addToCartButton[0], "click");
    
        //-- Setup step 5.
        waitForKeyElements (
            "div.mini-cart div.cart-item-data a.checkout-button:visible",
            clickTheCheckoutButton
        );
    }
    
    //-- STEP 5:    Click the checkout button.
    function clickTheCheckoutButton (jNode) {
        triggerMouseEvent (jNode[0], "click");
    
        //-- All done.  The checkout page should load.
    }
    
    function triggerMouseEvent (node, eventType) {
        var clickEvent = document.createEvent('MouseEvents');
        clickEvent.initEvent (eventType, true, true);
        node.dispatchEvent (clickEvent);
    }
    

    这篇关于在AJAX驱动的站点上选择并激活正确的控件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆