javascript – Jquery在div内的x个单词之后插入html而不使用split

已经4天了,我尝试了很多不同的方法,现在我几乎放弃了,似乎无法做到……

我正在尝试创建一个脚本,它会生成一个html文本,并在计算x个单词后将其放在博客文章中,让我们说它在计算10个单词之后.我能够通过使用正则表达式(拆分)来实现这一点,但正则表达式正在剥离我的帖子的HTML.从理论上讲,它非常简单,但我不知道为什么它在实践中如此复杂.我不能使用段落或任何元素作为引用,它必须仅在文本之后插入html,而不是在代码标记内,例如,我有< script>一些代码< / script>我的博客文本—需要插入的文本 – 它不能计算脚本标签内的内容,它应该只计算纯文本并在其后插入新的html并进行渲染.让我们说它与使用WYSIWG编辑器输入文本和插入图像的逻辑相同.
这很难解释.

基本上我需要的东西只是得到一个横幅并插入文本中的x个单词之后,就是这样.

这是我上次尝试过的,没有任何成功(代码不能正常工作):

更新 – 这是我开始在stackoverflow中打开关于这个主题的主题,我将提供链接供参考:

> jquery code not working in site
> jquery calling null element that actually exists
> Jquery use “count” instead of “slice”
> Jquery script operator == not working in website,but works in local
> Is it possible to skip html tags using jquery and split method?
> jquery – Use split to split only text?
> How can I use split but skip html/javascript/php and other inner tags?
> Jquery – Break/Prevent each loop

最佳答案
对此的一种解决方法如下,尽管可悲的是,有点幼稚,我不禁怀疑,过于复杂.然而:

// a simple utility function to get only the actual words
// from the supplied textNode (though this should work for
// elements also):
function getActualWords(node) {

    // gets the textContent of the node,// splits that string on one-or-more ('+')
    // white-space characters ('\s');
    // filters the array returned by split():
    return node.textContent.split(/\s+/).filter(function (word) {
        // word is the current array-element
        // (a 'word') in the array over
        // which we're iterating using
        // Array.prototype.filter();
        // here if the word,with leading
        // and trailing white-space removed
        // (using String.prototype.trim())
        // has a length greater than 0
        // (a falsey value) the word is kept
        // in the array returned by filter:
        return word.trim().length;

        // note that negative numbers are
        // also truthy,but no string can
        // have a negative length; so the
        // comparison is effectively,if
        // not explicitly 'greater than zero'
        // rather than simply 'not-zero'
    });
}

// named function to insert the specified
// element after the nth word:
function insertElemAfterNthWord(opts) {

    // defining the defaults for the function
    // (which can be overridden via the opts
    // Object):
    var defaults = {

        // the word after-which to insert the
        // the new element:
        'nth': 5,// the text of the new element:
            'elemText': 'new element',// the type of element (note no '<' or '>'):
            'elemTag': 'div'
    };

    // iterating over the supplied opts Object to update
    // the defaults with the user-supplied options using
    // for...in loop:
    for (var prop in opts) {

        // if the opts Object has a property and
        // that property is not inherited from the
        // prototype chain:
        if (opts.hasOwnProperty(prop)) {

            // we set the defaults property
            // to the property-value held
            // in the opts Object:
            defaults[prop] = opts[prop];
        }
    }

    // aliasing the defaults object (simply to save
    // typing; this is not essential):
    var d = defaults,// ensuring that the supplied string,// specifying the element-type has no
        // '<' or '>' characters (to ensure validty
        // this should be extended further to
        // ensure only alphabetical characters are kept):
        tag = d.elemTag.replace(/<|>/g,''),// creating the new element:
        elem = document.createElement(tag);

    // setting the textContent of the new element:
    elem.textContent = d.elemText;

    // ensuring that the d.nth variable is
    // a number,not a string,in base-10:
    d.nth = parseInt(d.nth,10);

    // if a node was specified:
    if (d.node) {

        // setting the 'n' variable to hold
        // to the firstChild of the d.node:
        var n = d.node.firstChild,// using the utility function (above)
            // to get an Array of only the actual 
            // words held in the node:
            words = getActualWords(n),// getting the number of words held
            // in the Array of words:
            wordCount = words.length;

        // while (n.nodeType is not a textNode OR
        // d.nth is a greater number than the number
        // of words in the node) AND the node has
        // a following sibling node:
        while ((n.nodeType !== 3 || d.nth > wordCount) && n.nextSibling) {

            // we update n to the next-sibling:
            n = n.nextSibling;

            // we get an array of words from
            // newly-assigned node:
            words = getActualWords(n);

            // we update the wordCount,in
            // order to progress through:
            wordCount = words.length;
        }

        // if the number of words is less than
        // the nth word after which we want to
        // insert the element,we return from
        // the function (doing nothing):
        if (getActualWords(n).length < d.nth) {
            return;

        // otherwise:
        } else {

            // again we get an Array of actual words,// we slice that Array and then get the
            // last array-element from that array,// using Array.prototype.pop():
            var w = getActualWords(n).slice(0,d.nth).pop(),// here we get the index of that word
                // (note that this is naive,and relies
                // upon the word being unique as a
                // proof-of-concept; I plan to update later):
                i = n.textContent.indexOf(w);

                // we split the n textNode into
                // two separate textNodes,at
                // supplied index ('i + w.length');
                // n remains the shortened 'first'
                // textNode:
                n.splitText(i + w.length);

            // navigating to the parentNode,and
            // using insertBefore() to insert the
            // new element ('elem') before the
            // next-siblin of the n textNode:
            n.parentNode.insertBefore(elem,n.nextSibling);

            // doing exactly the same,but adding a
            // newly-created textNode (of a space character)
            // between the 'n' textNode (which by definition
            // ends without a space) and newly-inserted
            // element:
            n.parentNode.insertBefore(document.createTextNode(' '),n.nextSibling);

            // joining adjacent,but unconnected,// textNodes (n and the newly-inserted
            // space character) together,to become
            // a single node:
            n.parentNode.normalize();

            // returning the newly-created element
            // so that it can be modified if required
            // or simply cached:
            return elem;
        }

    }
}


// calling the function,specifying the
// user-defined properties:
insertElemAfterNthWord({
    // after the tenth word:
    'nth': 10,// the element-type (a span):
        'elemTag': 'span',// setting the text of that new element:
        'elemText': 'this is the newly-added text inside the newly-added element!',// specifying the node into which the element
    // should inserted:
        'node': document.querySelector('div > div')

// chaining the function,to use the Element.classList
// API to add the 'newlyAdded' class to the
// newly-created element:
}).classList.add('newlyAdded');
function getActualWords(node) {
  return node.textContent.split(/\s+/).filter(function(word) {
    return word.trim().length;
  });
}

function insertElemAfterNthWord(opts) {
  var defaults = {
    'nth': 5,'elemText': 'new element','elemTag': 'div'
  };

  for (var prop in opts) {
    if (opts.hasOwnProperty(prop)) {
      defaults[prop] = opts[prop];
    }
  }

  var d = defaults,tag = d.elemTag.replace(/<|>/g,elem = document.createElement(tag);

  elem.textContent = d.elemText;

  d.nth = parseInt(d.nth,10);

  if (d.node) {
    var n = d.node.firstChild,words = getActualWords(n),wordCount = words.length;

    while ((n.nodeType !== 3 || d.nth > wordCount) && n.nextSibling) {

      n = n.nextSibling;
      words = getActualWords(n);
      wordCount = words.length;
    }
    if (getActualWords(n).length < d.nth) {
      return;
    } else {
      var w = getActualWords(n).slice(0,i = n.textContent.indexOf(w);
      n.splitText(i + w.length);
      n.parentNode.insertBefore(elem,n.nextSibling);
      n.parentNode.insertBefore(document.createTextNode(' '),n.nextSibling);
      n.parentNode.normalize();

      return elem;
    }

  }
}


insertElemAfterNthWord({
  'nth': 10,'elemTag': 'span','elemText': 'this is the newly-added text inside the newly-added element!','node': document.querySelector('div > div')
}).classList.add('newlyAdded');
span {
  color: #f90;
}
div {
  margin-left: auto;
  margin-right: auto;
}
.newlyAdded {
  background-color: #ffa;
}

JS Fiddle demo.

以上方法的注意事项:

>它要求所有单词都保存在单个文本节点中;它甚至不会尝试计算可能在一个元素中开始并在兄弟元素内部结束的单词.
>它不允许 – 在其当前实现中 – 任何将非文本插入到created元素中的方法(尽管可以通过使用elem.innerHTML代替elem.textContent来允许),但它确实返回create-element到调用上下文,因此它可以被缓存或链接,这允许以某种方式操纵created元素.
>有些检查,如果不是大多数,都非常幼稚;并将从扩展到受益于您自己的特定边缘案例.

参考文献:

> Array.prototype.filter().
> Array.prototype.pop().
> Array.prototype.slice().
> Document.createElement().
> Document.createTextNode().
> Document.querySelector().
> Element.classList
> for...in loop
> Guide to JavaScript Regular Expressions
> Node.firstChild
> Node.insertBefore()
> Node.nextSibling
> Node.nodeType
> Node.normalize()
> Object.hasOwnProperty()
> parseInt()
> String.prototype.indexOf()
> String.prototype.replace()
> String.prototype.split()
> String.prototype.trim().
> Text.splitText()
> while () {...} loop

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


1.第一步 设置响应头 header(&#39;Access-Control-Allow-Origin:*&#39;); //支持全域名访问,不安全,部署后需要固定限制为客户端网址 header(&#39;Access-Control-Allow-Methods:POST,GET,OPTIONS,D
$.inArray()方法介绍 $.inArray()函数用于在数组中搜索指定的值,并返回其索引值。如果数组中不存在该值,则返回-1; $.inArray(value,array) --value是要查找的值,array是被查找的数组。 有如下实例: &lt;!DOCTYPE html&gt; &l
jquery.serializejson.min.js的妙用 关于这个jquery.serializejson.min.js插件来看,他是转json的一个非常简单好用的插件。 前端在处理含有大量数据提交的表单时,除了使用Form直接提交刷新页面之外,经常碰到的需求是收集表单信息成数据对象,Ajax提
JS 将form表单数据快速转化为object对象(json对象) jaymou 于 2020-03-03 11:11:05 发布 3534 收藏 3 分类专栏: 前端 文章标签: javascript jquery 版权 前端 专栏收录该内容 5 篇文章0 订阅 订阅专栏 直接上代码 /** *
jQuery的区别:$().click()和$(document).on(&#39;click&#39;,&#39;要选择的元素&#39;,function(){})的不同 文章地址:https://www.cnblogs.com/sqh17/p/7746418.html 解决:动态创建的元素的事件
jQuery插件之jquery.spinner数字智能增减插件 参考地址:http://www.helloweba.com/view-blog-282.html 左右加减数字 像京东提交订单时目前使用的是左右加减数字的效果,这个效果直接明了,操作简单。我们使用jquery.spinner.js插件实
layui标签或一般标签均可&lt;div class=&quot;layui-form-item&quot;&gt; &lt;label class=&quot;layui-form-label&quot;&gt;异地仓名称&lt;/label&gt; &lt;div class=&quot;la
网上对于select option 动态添加修改如下, $(&quot;#selectId&quot;).append(&quot;&lt;option value=&#39;&quot;+value+&quot;&#39;&gt;&quot;+text+&quot;&lt;/option&gt;&
jQuery中的 $.extend() 和 $.fn.extend() ANGWH 于 2020-05-24 06:39:59 发布 注意:$.extend是为jQuery类添加添加类方法,用$.调用(类似$.ajax),$.fn.extend则是为jQuery对象添加方法(实例方法),用DOM元素
jquery 循环数组输出显示在html页面 jquery 没有双向数据绑定,但是很多需求确实需要我们从后台接收到数组或者对象循环显示在前台页面上,这时我们可以用字符串拼接,元素添加的方法去实现 js部分如下: 复制代码 $(function(){ var a=[&quot;1aa&quot;,&q
javascript事件委托理解,jQuery .on()方法一步到位实现事件委托 Javascript-概念原理 专栏收录该内容 10 篇文章0 订阅 订阅专栏 本篇文章借鉴自:博客园文章,只为自己巩固下事件委托方面的知识 概述: 什么叫事件委托?他还有一个名字叫做事件代理,(时间代理 事件委托,
JQuery-$.when().done().fail()的使用 原文引用于&#160;Echoo华地于&#160;2022-01-06 14:07:10 发布 jQuery的开发速度很快,几乎每半年一个大版本,每两个月一个小版本。 每个版本都会引入一些新功能。今天我想介绍的,就是从jQuery 1
jQuery tableExport导出 excel 上篇写的是jQuery&#160;导出word,就试试导出excel。看见网上写的很乱,我这就把我写的整理下来,有部分来自网上capy 1. js文件的引用 &lt;script type=&quot;text/javascript&quot;
jQuery的遍历-prev()和next()方法 &lt;div class=&quot;box&quot; id=&quot;box&quot;&gt; &lt;a href=&#39;#&#39; class=&quot;a&quot;&gt; &lt;input type=&quot;tex
attr()和addClass()的区别 方法 addClass() attr()用途&#x9;追加样式&#x9;设置样式对同一个网页元素操作&#x9;&lt;p&gt;test&lt;/p&gt;第1次使用方法&#x9;$(&quot;p&quot;).addClass(&quot;high&quot;);&#x9;$(&quot;p&
前端——函数(匿名函数、自执行函数) FreshLemon_ 于 2019-06-11 17:11:49 发布 函数声明:function box(){} 函数表达式:var box = function(){}; 匿名函数:function(){} (属于函数表达式) 1声明了一个函数: var
js: 获取标签元素data-*属性值的方法 彭世瑜 于 2022-05-23 09:59:50 发布 2165 收藏 1 文章标签: javascript 前端 jquery 版权 标签上有两个属性data-id 和 data-user-name, 需要通过js去获取 &lt;style&gt;
JavaScript函数详解:匿名函数、具名函数、函数传参、不定参、返回值、JS预解析机制 1.具名函数 定义: 调用: 方式1:方法名(); 可以多次调用 方式2:在事件中调用,直接写函数名,不需用括号 2.匿名函数 没有名字的函数 匿名函数在使用时只有两种情况: 1.匿名函数自执行:声明后不需要
如何等待ajax完成再执行相应操作 ajax广泛应用于异步请求,对于大多数业务来说,这是十分方便的,但对于一些特殊的业务,ajax的异步性会起到相反的作用。 例如在ajax请求成功后,后续的操作需要依赖ajax执行成功后的相应操作。 // 声明一个表示状态的全局变量 status var statu
一步一步教你写一个jQuery的插件教程(Plugin) 更新时间:2009年09月03日 02:10:54 作者: 我将会在下面的例子中一个一个的说明上面这几个条件,做完这些事情后我们就会创建一个高亮显示text的简单插件。 jQuery 的plugin开发需要注意的事情, 1. 明确jQuery